Создание приложений глубокого обучения с помощью Raspberry Pi 4b (IX) Yolo

малиновый пирог
Создание приложений глубокого обучения с помощью Raspberry Pi 4b (IX) Yolo

предисловие

В предыдущей статье мы установили среду OpenVINO на Raspberry Pi и запустили несколько официальных демонстраций.В качестве ключевого момента работы по преобразованию модели мы взяли за пример реализацию каждой версии yolo и реализовали ее в этой статье. .

Обнаружение цели является относительно зрелой областью приложений искусственного интеллекта.Он должен не только идентифицировать цель изображения, но и определять ее положение.Это будет основной сценой в автоматическом вождении. Обычно делится на две категории, одна из которых двухэтапная, основанная на R-CNN, Fast R-CNN, Faster R-CNN и т. д., сначала генерируется предложение региона, а затем классифицируются и получаются категории, а затем возвращаются для получения местоположения; другой тип — Yolo, одноэтапный алгоритм SSD, который напрямую использует сеть CNN для получения цели и местоположения.

Условно говоря, система R-CNN имеет более высокую точность, но более низкую скорость, в то время как система Yolo имеет более высокую скорость и более низкую точность. Во многих областях CV, если гарантируется точность классификации, скорость обнаружения важнее, чем точность позиционирования, а одноэтапное развертывание модели имеет естественное преимущество, которое значительно снижает вычислительную нагрузку граничных устройств с ограниченной вычислительной мощностью. .

Yolo является представителем скорости оптимизации класса обнаружения целей, и после преобразования в Openvino скорость может быть дополнительно улучшена. В этой статье в основном представлен метод преобразования моделей двух основных фреймворков Tensorflow и Pytorch в Openvino.

Прежде всего, процесс преобразования модели Tensorflow заключается в том, чтобы сначала преобразовать файл веса .weight в файл статического изображения .pb, затем преобразовать его в .bin и .xml модели IR и, наконец, развернуть его на нейронной сети. бар для запуска. Давайте сначала запустим приложение yolov4-tiny, чтобы испытать его.

Приложение Йолов4

1. Загрузите исходный код

git clone https://github.com/TNTWEN/OpenVINO-YOLOV4.git
cd OpenVINO-YOLOV4

2. Ставим вес --> pb

Загрузите yolov4.weight и yolov4-tiny.weight в этот каталог

python convert_weights_pb.py --class_names cfg/coco.names --weights_file yolov4-tiny.weights --data_format NHWC --tiny

Если в каталоге есть вывод Frozen_darknet_yolov4_model.pb, преобразование выполнено успешно.

Tip:

Формат данных должен быть указан как NHWC, чтобы соответствовать соответствующему формату в Intel NCS2.

Tip:

Если вы столкнулись с сообщением об ошибке «облачного» импорта, это связано с тем, что флаг --nogcp был включен при компиляции TF, в результате чего tensorflow/contrib/cloud не добавляется в установочный пакет pip. Вот просто поставьinitЭту ошибку можно исправить, закомментировав две строки кода в Формат данных должен быть указан как NHWC, поэтому reverse_input_channels требуется для переключения соответствующего входного канала.

/home/pi/my_envs/tensorflow/lib/python3.7/site-packages/tensorflow/contrib/__init__.py

3. Инициализировать среду openvino

Чтобы выполнить преобразование на хосте Windows или Linux, необходимо установить комплект разработки OpenVINO.

ubuntu01

"C:\Program Files (x86)\IntelSWTools\openvino\bin\setupvars.bat"

4. Поместите pb --> ir

Перейдите в каталог OpenVINO-YOLOV4 и преобразуйте файлы pb в файлы xml и bin.

python "C:\Program Files (x86)\IntelSWTools\openvino_2020.4.287\deployment_tools\model_optimizer\mo.py" --input_model frozen_darknet_yolov4_model.pb --transformations_config yolo_v4_tiny.json --batch 1 --reverse_input_channels

Tip:

Перед преобразованием модели IR необходимо обратить внимание на совместимость оператора op и точность данных соответствующей платформы. Вы можете найти конкретную информацию на следующей странице Многие модели не могут быть преобразованы, потому что они не поддерживаются.

https://docs.openvinotoolkit.org/latest/openvino_docs_IE_DG_supported_plugins_Supported_Devices.html

5. Запустите модель

Запустив модель на Raspberry Pi, FPS стабилен на уровне 6-7 кадров.

source ~/my_envs/tensorflow/bin/activate
/opt/intel/openvino/bin/setupvars.sh
python object_detection_demo_yolov4_async.py -i cam -m frozen_darknet_yolov4_model.xml -d MYRIAD

Приложение Йолов5

Yolov5 в основном представляет улучшение мозаики и адаптивную опорную рамку.Эти новые функции структурно не отличаются от Yolov4.Однако версия v5 с открытым исходным кодом — это pytorch, которую легче конвертировать на различные платформы, чем в даркнет.

Рабочий процесс:

Если другой основной фреймворк, Pytorch, хочет использовать openvino для оптимизации, процесс преобразования заключается в том, чтобы сначала преобразовать файл модели pytorch .pt в формат onnx, а затем преобразовать его в модель IR, которую можно развернуть на нервном стержне.

Далее мы используем последнюю версию Yolov5 для запуска этого процесса.

1. Установите инструменты разработки OpenVINO в Ubuntu.

Скачать установочный пакет для версии linux от апреля 2020 г.

cd ~/Downloads/
wget http://registrationcenter-download.intel.com/akdlm/irc_nas/16803/l_openvino_toolkit_p_2020.4.287.tgz
tar -xvzf l_openvino_toolkit_p_2020.4.287.tgz

2. Установите зависимости

pip3 install defusedxml
pip3 install networkx
pip3 install test-generator==0.1.1
# 这里我们只需要转换 onnx
cd l_openvino_toolkit_p_2020.4.287
sudo ./install_prerequisites_onnx.sh

3. Создайте виртуальную среду

Python>=3.8, PyTorch==1.5.1, ONNX>=1.7.

conda activate openvino  # 进入ubuntu 的虚拟环境
git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip3 install -r requirements.txt onnx
# 降版本
pip install torch==1.5.1 torchvision==0.6.1

4. Экспортируйте модель yolov5, обученную на pytorch.

Сначала загрузите yolov5s.pt (или обучите модель yolov5 вашего собственного набора данных) и поместите ее в каталог

wget https://github.com/ultralytics/yolov5/releases/download/v2.0/yolov5s.pt
mv yolov5s.pt yolov5s_2.0.pt

Tip:

Скачать v2.0 с nn.LeakyReLU(0.1), так как nn.Hardswish для 3.0 пока не поддерживается.

5. Измените функцию активации

Поскольку onnx и openvino пока не поддерживают Hardswitch, измените функцию активации Hardswish на Relu или Leaky Relu.

# yolov5/models/common.py
# Line 26 in 5e0b90d
# self.act = nn.Hardswish() if act else nn.Identity()
self.act = nn.Relu() if act else nn.Identity()

6. Измените yolo.py

# yolov5/models/yolo.py
# Lines 49 to 53 in 5e0b90d
#    y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i]  # xy 
#    y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh 
#    z.append(y.view(bs, -1, self.no)) 
#  
# return x if self.training else (torch.cat(z, 1), x) 

Измените стек выходного слоя, исключая входной слой

    c=(y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i]  # xy
    d=(y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh
    e=y[..., 4:]
    f=torch.cat((c,d,e),4)
    z.append(f.view(bs, -1, self.no))

  return x if self.training else torch.cat(z, 1)

7. Измените файл export.py

# yolov5/models/export.py
# Line 31 in 5e0b90d
# model.model[-1].export = True  # set Detect() layer export=True 
model.model[-1].export = False

Поскольку версия opset 10 может поддерживать оператор изменения размера, вам необходимо изменить номер версии opset.

# yolov5/models/export.py
# Lines 51 to 52 in 5e0b90d
# torch.onnx.export(model, img, f, verbose=False, opset_version=12, input_names=['images'], 
torch.onnx.export(model, img, f, verbose=False, opset_version=10, input_names=['images'], 
                   output_names=['classes', 'boxes'] if y is None else ['output'])

Tip:

Убедитесь, что torch==1.15.1, torchvision==0.6.1, onnx==1.7, opset=10. Функция активации — Relu, а уровень сетевого вывода изменен.

8. Ставим пт --> onnx

export PYTHONPATH="$PWD"  
python models/export.py --weights yolov5s_2.0.pt --img 640 --batch 1  

Показать экспорт в виде файлов onnx и torchscript.

ONNX export success, saved as ./yolov5s.onnx
Export complete. Visualize with https://github.com/lutzroeder/netron.

9. Ставим onnx --> ir

python3 /opt/intel/openvino_2020.4.287/deployment_tools/model_optimizer/mo.py 
    --input_model yolov5s_2.0.onnx 
    --output_dir ./out 
    --input_shape [1,3,640,640]

Если все пойдет хорошо, IR-модель yolov5s может быть сгенерирована в каталоге out, а затем файл будет передан на Raspberry Pi.

Tip:

Здесь входная форма, соответствующая yolov5s, — [ 1, 3, 640, 640 ].

10. Измените параметры в соответствии с моделью обучения.

git clone https://github.com/linhaoqi027/yolov5_openvino_sdk.git

Изменить устройство вывода и форму ввода

# device = 'CPU'
# input_h, input_w, input_c, input_n = (480, 480, 3, 1)
device = 'MYRIAD'
input_h, input_w, input_c, input_n = (640, 640, 3, 1)

Изменить информацию о категории

# label_id_map = {
#     0: "fire",
# }
names=['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
       'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
       'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
       'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
       'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
       'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
       'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
       'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
       'hair drier', 'toothbrush']

label_id_map = {index: item for index, item in enumerate(names)}

Изменить вывод нескольких категорий

for idx, proposal in enumerate(data):
    if proposal[4] > 0:
        print(proposal)
        confidence = proposal[4]
        xmin = np.int(iw * (proposal[0] / 640))
        ymin = np.int(ih * (proposal[1] / 640))
        xmax = np.int(iw * (proposal[2] / 640))
        ymax = np.int(ih * (proposal[3] / 640))
        idx = int(proposal[5])
        #if label not in label_id_map:
        #    log.warning(f'{label} does not in {label_id_map}')
        #    continue
        detect_objs.append({
            'name': label_id_map[idx],
            'xmin': int(xmin),
            'ymin': int(ymin),
            'xmax': int(xmax),
            'ymax': int(ymax),
            'confidence': float(confidence)
        })

11. Вывод вывода

if __name__ == '__main__':
    # Test API
    img = cv2.imread('../inference/images/bus.jpg')
    predictor = init()
    import time
    t = time.time()
    n = 10
    for i in range(n):
        result = process_image(predictor, img)

    print("平均推理时间",(time.time()-t)/n)
    print("FPS", 1/((time.time()-t)/n))
    # log.info(result)
    for obj in json.loads(result)['objects']:
        print(obj)
python inference.py 

FPS у yolov5s всего около 2 кадров.По сравнению с yolov4-tiny скорость не быстрая.Форма ввода 640 намного больше чем 416 у yolov4.Ощутимо.

Кроме того, разница достоверности преобразованной IR-модели на ЦП и вывод MYRIAD также очень высока, кажется, что у yolov5 еще есть много возможностей для оптимизации.

Чтобы добиться максимальной скорости обнаружения, можно попробовать несколько направлений:

  • Множественное распределённое рассуждение Neural Rod;
  • использовать многопоточный вывод;
  • Обновлять экран асинхронно;
  • используйте модель меньшего размера;
  • Код вывода изменен с Python на C++

Особенно недавно Youtu выложил в открытый доступ версию yolo-fastest.Основой является EfficientNet-lite, так что вес обученной модели составляет всего 1,2 млн, а у yolo-fastest-xl всего 3,3 млн, что очень мало. .

Этот твердотельный накопитель MobileNet на самом деле работал со скоростью выше 40 кадров в секунду на Raspberry Pi 4 + 5 NCS2, потрясающе! ! !

В этой статье в основном представлен способ преобразования двух основных фреймворков Tensorflow и Pytorch в модель OpenVINO.

  • .weight --> .pb --> .xml .bin
  • .pt --> onnx --> .xml .bin

На самом деле существует больше AI-фреймворков, которые вообще конвертируются друг в друга через pb, onnx, ir, такие промежуточные модели, как TensorRT, Tensorflow Lite и т.д.

Как правило, если вы понимаете структуру входных и выходных слоев, веса и файлы сетевой структуры, соответствующие каждой модели, и обращаете внимание на поддержку оператора op, вы можете использовать конвейер, предоставляемый платформой, для выполнения преобразование.

Последнее средство — переписать топологию сети, использовать метод, аналогичный load_weight, для импорта весов, а затем сохранить их в целевой платформе.

загрузка кода

Для получения соответствующих документов и материалов в этом выпуске вы можете ответить на фоне официального аккаунта: «rpi09», чтобы получить ссылку для скачивания.


Следующее уведомление

Мы представим агентское программное обеспечение на Raspberry Pi, Развернуть мягкую маршрутизацию Openwrt, Создайте единую онлайн-среду, Быть в курсе...