Карстен Меннинг, доктор философии

Это заключительная часть серии из двух частей, посвященных запуску приложений ИИ на периферии в целом и анализу компьютерного зрения на Raspberry Pi 3 с ускорением Intel Neural Compute Stick 2, в частности.

Взгляните на часть 1, чтобы получить:

  1. обзор аппаратных ускорителей ИИ Edge и вариантов плат для разработки,
  2. руководство о том, как настроить Raspberry Pi со встроенной камерой в качестве периферийного устройства с поддержкой ИИ,
  3. руководство по установке набора инструментов Intel OpenVINO на Raspberry Pi и, например, на ваш ноутбук, чтобы подготовиться к выполнению логического вывода компьютерного зрения на Raspberry Pi.

Эта вторая часть построена на шагах 2 и 3. В то время как часть 1 завершилась демонстрационным приложением для обнаружения лиц OpenVINO, работающим на Raspberry Pi, в этом посте рассматривается разработка вашего собственного пользовательского решения Computer Vision на таком периферийном устройстве. В частности, я расскажу вам о пользовательской реализации модели обнаружения объектов YOLOv3-tiny на Raspberry Pi, предварительно настроенной, как описано в части 1. (Подробности о модели обнаружения объектов YOLOv3 можно найти здесь.) Но, Во-первых, давайте поближе познакомимся с набором инструментов Intel OpenVINO с открытым исходным кодом в целом и набором инструментов OpenVINO для ОС Raspbian в частности. 🗹

Набор инструментов Intel OpenVINO

Процитируем официальную документацию по набору инструментов OpenVINO: «Набор инструментов OpenVINO ™ - это всеобъемлющий набор инструментов для быстрой разработки приложений и решений, имитирующих человеческое видение. Этот инструментарий, основанный на сверточных нейронных сетях (CNN), расширяет рабочие нагрузки CV на оборудование Intel®, обеспечивая максимальную производительность ».

Процитируем далее, инструментарий:

  • «Позволяет делать выводы глубокого обучения на основе CNN на грани
  • поддерживает разнородное выполнение на ЦП Intel®, интегрированной графике Intel®, Intel® FPGA, Intel® Neural Compute Stick 2 и Intel® Vision Accelerator Design с помощью Intel® Movidius ™ VPU
  • ускоряет вывод продукта на рынок за счет простой в использовании библиотеки функций компьютерного зрения и предварительно оптимизированных ядер
  • включает оптимизированные требования к стандартам компьютерного зрения, включая OpenCV и OpenCL ™ ».

Среди прочего, это означает, что набор инструментов особенно хорошо подходит для разработки приложений логического вывода компьютерного зрения на периферийных устройствах, таких как Raspberry Pi, усиленных USB-ускорителем Intel Neural Compute Stick 2 с Intel Movidius VPU.

⚡ В случае, если вам может быть интересно: «OpenVINO» означает «Открытый визуальный вывод и оптимизация нейронной сети», что указывает на его направленность на глубокое обучение и компьютерное зрение. ⚡

Основные элементы инструментария OpenVINO состоят из:

  • Оптимизатор модели,
  • механизм вывода и
  • Открытый модельный зоопарк.

Оптимизатор моделей берет модели компьютерного зрения с глубоким обучением, предварительно обученные в фреймворках Caffe, TensorFlow, MXNet, Kaldi или ONNX, и преобразует их в промежуточное представление OpenVINO (IR), оптимизированное представление модели, оптимизированное для выполнения модели с использованием механизма вывода, работающего на краевое устройство. Механизм вывода загружает и выводит эти IR-файлы, используя общий API для ЦП и ГП, а также оборудования VPU.

Open Model Zoo предоставляет предварительно обученные модели для бесплатной загрузки, которые можно использовать для ускорения процесса разработки, поскольку не нужно сначала обучать собственную модель, которую затем нужно будет преобразовать в промежуточное представление с помощью оптимизатора моделей. перед тем, как быть готовым к использованию с механизмом вывода на рассматриваемом граничном устройстве.

Если не использовать предварительно обученную модель из Open Model Zoo, ниже показан типичный рабочий процесс для развертывания модели глубокого обучения на периферии с помощью набора инструментов OpenVINO.

Итак, модели Open Model Zoo имеют то преимущество, что они уже были преобразованы в промежуточное представление OpenVINO, но что такое промежуточное представление?

IR описывает результат входной модели, которая была оптимизирована для вывода ребер с помощью одного или нескольких из следующих методов:

  • квантование, то есть снижение числовой точности весов модели и смещения,
  • объединение слоев модели, то есть объединение нескольких слоев модели в один,
  • замораживание, то есть удаление метаданных и операций, которые были полезны только для обучения модели (только в случае моделей TensorFlow).

Конечно, вы также можете совершенно бесплатно использовать модели из других источников. Однако они должны пройти второй шаг рабочего процесса OpenVINO. То есть вам нужно будет применить оптимизатор модели к входной модели, чтобы получить ее IR, оптимизированную для вывода.

После создания IR его файлы .xml (оптимизированная топология модели) и .bin (оптимизированные веса и смещения модели) могут быть загружены в OpenVINO Inference Engine, работающий на граничном устройстве, для оптимизированного для производительности вывода на грани.

Фактически, мы уже прошли этот простой путь через этот рабочий процесс на примере обнаружения лиц в части 1 этой серии из двух статей: Мы загрузили предварительно обученную модель обнаружения лиц из Open Model Zoo. В частности, поскольку загрузчик моделей OpenVINO недоступен в наборе инструментов OpenVINO для ОС Raspbian, мы вручную загрузили файлы IR на Raspberry Pi и загрузили их в механизм вывода для создания ограничивающей рамки на входном изображении.

Теперь мы выберем немного более сложный путь преобразования предварительно обученной общедоступной модели, крошечной версии YOLOv3 [2], в IR через оптимизатор моделей. Это подводит нас к важному моменту: поскольку OpenVINO Inference Engine представляет собой единственный основной элемент OpenVINO, включенный в набор инструментов OpenVINO для Raspbian OS, преобразование модели должно выполняться вне среды Raspberry Pi, например, на вашем основном компьютере, Это означает, что вам также нужно будет установить OpenVINO на свой основной компьютер. С помощью руководств по установке OpenVINO Linux, macOS и Windows это не должно быть слишком сложной задачей.

⚡ В случае набора инструментов OpenVINO для Windows вы можете обойтись без шагов установки Microsoft Visual Studio и CMake, поскольку в дальнейшем мы будем использовать только Оптимизатор модели. Однако, если вы хотите иметь полноценную установку OpenVINO на вашем компьютере с Windows, конечно, настоятельно рекомендуется выполнить все шаги установки. ⚡

Теперь вы готовы к пользовательской реализации модели YOLOv3-tiny [2] на Raspberry Pi.

Преобразование предварительно обученной модели YOLOv3-tiny в промежуточное представление OpenVINO

После установки OpenVINO на вашем основном компьютере давайте сгенерируем IR модели YOLOv3-tiny. Сетевая архитектура YOLOv3-tiny оптимизирована для низкопроизводительных устройств за счет снижения точности прогнозирования: она использует только 19 сверточных слоев вместо 53 сверточных слоев стандартной модели YOLOv3. Как следствие, она намного более эффективна для выполнения, чем стандартная модель YOLOv3, но также намного менее точна со средней средней точностью (mAP) 33,1% по сравнению со значением mAP 51–57% в стандартной модели YOLOv3. .

Чтобы преобразовать модель YOLOv3-tiny в формат IR, мы в основном будем следовать руководству по преобразованию моделей YOLO OpenVINO.

Шаг 1: клонируйте следующий репозиторий GitHub, чтобы получить реализацию YOLOv3-tiny на основе TensorFlow.

⚡ В принципе, вы также можете использовать любую другую реализацию модели YOLOv3-tiny на основе TensorFlow, но вы можете столкнуться с трудностями при попытке преобразовать ее в промежуточное представление, используя следующие шаги. ⚡

git clone https://github.com/mystic123/tensorflow-yolo-v3.git

Шаг 2. Загрузите набор меток классов в виде, например, coco.names, который включает 80 общих классов объектов, от людей до автомобилей и животных, или предоставьте свой собственный набор метки классов, которые вы хотите сделать логическим выводом при использовании YOLOv3-tiny, при условии, что YOLOv3-tiny был предварительно обучен на выбранных вами классах.

Шаг 3: загрузите предварительно обученные YOLOv3-tiny weights или тренируйте YOLOv3-tiny сами и используйте получившиеся модельные веса.

Шаг 4. Преобразуйте модель YOLOv3 в формат файла буфера протокола (.pb), чтобы получить упрощенное, то есть «замороженное» определение модели для вывода.

python convert_weights_pb.py --class_names coco.names --data_format NHWC --weights_file yolov3-tiny.weights --tiny

Параметр --tiny в конце statemenet инструктирует конвертер сгенерировать YOLOv3-tiny версию замороженного графа TensorFlow.

Шаг 5. Преобразуйте определение замороженной модели в ее формат IR. Не забудьте перед этим шагом выполнить сценарий настройки среды OpenVINO setupvars, расположенный в $OPENVINO_INSTALL_DIR/bin/.

python mo_tf.py --input_model frozen_darknet_yolov3_model.pb --tensorflow_use_custom_operations_config <path/>yolo_v3_tiny.json --batch 1 --generate_deprecated_IR_V7

где файл конфигурации OpenVINO <path/> в yolo_v3_tiny.json модели должен выглядеть примерно так:

$OPENVINO_INSTALL_DIR/deployment_tools/model_optimizer/extensions/front/tf/

⚡ Параметр --generate_deprecated_IR_V7 заставляет оптимизатор модели генерировать старую версию IR 7. Это связано с ошибкой совместимости, связанной с версией IR 10, уже упомянутой в части 1. Если не использовать этот параметр, ваша преобразованная модель завершится ошибкой во время логического вывода с несколько трудноизлечимыми сообщениями об ошибках. ⚡

⚡ Если вы хотите запускать демонстрации OpenVINO с использованием преобразованной модели, обратите внимание, что вам может потребоваться добавить параметр --reverse_input_channel, поскольку демонстрации OpenVINO обычно предполагают, что цветовые каналы будут в BGR, а не в обычном порядке RGB. Обратитесь к официальной демонстрационной документации OpenVINO, чтобы проверить конкретные входные требования демонстрации. ⚡

В результате мы получаем оптимизированные для ребер YOLOv3-tiny топологию сети (.xml) и термины веса и смещения (.bin) IR-файлы.

Чтобы проверить достоверность сгенерированных файлов IR, вы можете запустить OpenVINO демонстрацию YOLOv3 для обнаружения объектов на вашем основном компьютере. Пожалуйста, примите во внимание --reverse_input_channel замечание выше в этом контексте.

Результат для образца входного видео может быть показан ниже. Как и следовало ожидать при использовании YOLOv3-tiny для вывода, частота кадров легко достигает вывода почти в реальном времени на всех устройствах без Edge за счет частично довольно плохого обнаружения автомобилей и точности ограничивающей рамки.

Чтобы завершить этот подготовительный этап, просто перенесите файлы IR на свой Raspberry Pi. 🗹

Это оставляет нам возможность включить преобразованную модель YOLOv3-tiny в специально разработанное приложение, работающее на Raspberry Pi.

Приложение для обнаружения объектов с использованием YOLOv3-tiny на краю

Наше приложение состоит из трех основных элементов, которые, вообще говоря, характерны для большинства граничных приложений на основе OpenVINO:

  • Загрузка модели механизма вывода
  • Обработка ввода и запрос вывода на основе приложений
  • Результат вывода и обработка вывода на основе приложения

Это отражено в следующей структуре кода нашего приложения Raspberry PI:

  1. Вспомогательный класс для загрузки IR в механизм вывода и выполнения вывода
  2. Основная процедура, состоящая из предварительной обработки видео и ввода с камеры, извлечения и вывода кадров, а также обработки вывода видео
  3. YOLOv3-tiny класс параметризации модели

Мы будем использовать Python-оболочку API-интерфейса механизма вывода. Кодовую базу можно найти здесь на GitHub. Элементы, касающиеся обработки логического вывода YOLO, в значительной степени совпадают, например, с соответствующими частями в object_detection_demo_yolov3_async.py из Витрины OpenVINO YOLO. Итак, чтобы все было проще и по существу, ниже я обсуждаю только элементы, специфичные для OpenVINO.

Давайте сначала кратко рассмотрим параметризацию YOLOv3-tiny в форме Python class YoloParams. Его значения соответствуют исходной параметризации даркнета, так что здесь в принципе никаких сюрпризов. Однако выбор правильного набора якорей (строки 9–10) - это не только искусство, но и наука, и конкретный набор значений привязки, используемый здесь, вероятно, не будет лучшим выбором для конкретных сценариев обнаружения объектов. рассматривается ниже. Так что, если вас тоже интересует выбор параметра привязки YOLO, загляните сюда.

Специфичные для OpenVINO методы, предоставляемые помощником class Network, более уместны в контексте этой серии из двух статей: Метод load_model создает экземпляр объекта класса ядра Inference Engine, IECore (строка 24 ниже). Этот класс обеспечивает уровень абстракции для поддерживаемых устройств, скрывая любые особенности устройства. Как следствие, методы этого класса обычно ожидают, что устройство, с которым фактически работает, в качестве параметра, поэтому параметр устройства включен в список параметров load_model. Поскольку мы имеем дело с Intel Neural Compute Stick 2 в качестве устройства логического вывода, значение этого параметра по умолчанию установлено на «MYRIAD».

Затем модель обнаружения объектов YOLOv3-tiny в форме ранее созданных файлов IR считывается в объект IENetwork (строка 29). Класс IENetwork поддерживает чтение и изменение параметров модели, таких как размер пакета, числовая точность, форма модели и различные свойства слоя. Эта функция используется для установки размера пакета на 1 (строка 31), поскольку мы будем выполнять логический вывод для одного кадра за раз. Это требование единственного входа также утверждается в строке 33 при рассмотрении топологии входных данных модели. В случае успеха исполняемая версия модели создается в строке 36 и загружается в устройство MYRIAD для вывода. Наконец, строки 39–40 создают повторяющиеся объекты для входных и выходных слоев модели с помощью объекта IENetwork.

⚡ Поскольку мы имеем дело с устройством MYRIAD, для простоты я отказался от обычной проверки безопасности для неподдерживаемых сетевых уровней, которая требуется при использовании устройства ЦП для визуального вывода: поскольку предварительная обработка оптимизатора модели входит в файл IR генерация не зависит от устройства, возможно, что оптимизированная нейронная сеть может содержать слои, не поддерживаемые конкретным используемым ЦП устройства. Поэтому перед выполнением вывода на базе ЦП необходимо проверить наличие неподдерживаемых слоев, и необходимо завершить дальнейшую обработку, чтобы предотвратить произвольные результаты или сбой системы при обнаружении неподдерживаемых слоев. Поскольку приведенные выше строки кода также поддерживают вывод на основе ЦП, и если вы хотите поэкспериментировать с выводом с использованием ЦП Raspberry Pi вместо Intel Neural Compute Stick 2, посмотрите, например, object_detection_demo_yolov3_async.py для поддержки дополнительного уровня - требуются соответствующие строки кода. ⚡

Что касается других методов в class Network, метод get_input_shape использует объект IENetwork для возврата формы входного слоя модели.

Метод async_inference принимает идентификатор входного запроса и выполняет асинхронный вывод для этого запроса. Поскольку мы не выполняем по-настоящему асинхронную обработку, а скорее отправляем по одному кадру в механизм вывода, для идентификатора запроса устанавливается значение 0. Действительно для асинхронной обработки потребуются разные идентификаторы для разных запросов вывода, отправляющих дополнительные кадры в механизм вывода, в то время как возможно, он все еще обрабатывает предыдущие запросы. Эти идентификаторы запроса различия затем позволяют различать различные результаты логического вывода и выполнять индивидуально необходимую дополнительную обработку.

Поскольку мы выполняем асинхронную обработку, метод wait поддерживает ожидание завершения этого процесса перед попыткой получить какой-либо результат логического вывода. Обратите внимание, что эта проверка статуса должна выполняться со ссылкой на правильный идентификатор запроса, поэтому в данном случае 0.

Затем метод extract_output возвращает вывод логического вывода, сгенерированный запросом логического вывода для исполняемой сети. Индекс запроса снова должен быть установлен на 0, чтобы ссылаться на правильный запрос вывода. Значение функции ожидания -1 гарантирует, что статус будет возвращен после завершения процесса. Он эффективно блокирует обработку до тех пор, пока не истечет определенный тайм-аут или пока не станет доступен результат, в зависимости от того, что наступит раньше.

С различными вспомогательными методами, связанными с OpenVINO, это оставляет обсуждение основной процедуры вывода видео, infer_video, в файле tinyYOLOv3.py в репозитории GitHub, который использует вспомогательные методы для ввода видео или данных с камеры. для генерации результатов вывода на экран и видео файла.

Связанное с OpenVINO содержимое инициализации infer_video состоит из инициализации механизма вывода с помощью Network class (строка 7 ниже), за которым следует извлечение входной формы модели (строка 18).

Объект net впоследствии используется для запуска запроса асинхронного вывода для отдельного предварительно обработанного видеокадра (строка 3 ниже) и, дождавшись завершения асинхронного вывода (строка 8), получает результат вывода с помощью вспомогательного метода extract_output. (строка 9). Затем этот вывод анализируется, как применимо в случае модели YOLOv3.

⚡ Чтобы позже записать результат логического вывода в видео в рамках метода infer_video, я использую класс OpenCV VideoWriter с расширением выходного файла .avi и кодеком MP42: codec = cv2.VideoWriter_fourcc("M","P","4","2"). Поиск правильной комбинации кодека и расширения файла для конкретного настройка устройства может быть несколько утомительной. См., Например, эту статью Адриана Роузброка из Pyimagesearch по этому поводу. Он дает вам ряд указателей на то, какие комбинации могут быть потенциально допустимыми для вашей конкретной установки. Также он рекомендует установить привязки Python для FFMPEG на Raspberry Pi. В моем случае это сработало довольно хорошо. Тем не менее, тот факт, что расширение файла .avi в сочетании с кодеком MP42 работало для моей установки после установки библиотеки FFMPEG, не означает, что оно будет работать для вас, и вам может потребоваться пройти ряд комбинаций, пока вы не получить действительный видеовыход. ⚡

⚡ Обратите внимание, что метод infer_video также использует видеопакет в пакете imutils Pyimagesearch для вычисления количества кадров в секунду (FPS), поддерживаемых конвейером обработки. ⚡

Теперь мы готовы протестировать наше приложение на Raspberry Pi, используя как входное видео MP4, так и сценарий встроенной камеры Raspberry Pi.

В случае входного файла MP4 следующая команда запускает приложение, считывает входной файл, создает экранное окно, показывающее результаты логического вывода в виде ограничивающих рамок вокруг обнаруженных объектов, включая соответствующие метки, и записывает эти результаты. в выходной файл .avi:

python tinyYOLOv3.py --m "frozen_darknet_yolov3_model.xml" --i "test_video.mp4" --l "coco.names"

где вам, возможно, придется добавить ваши конкретные пути к модели, входному видео и параметрам файла метки класса. Результирующий выходной видеосигнал для использованного тестового файла [1] показан ниже. Raspberry Pi обеспечивает респектабельную частоту кадров около 3 кадров в секунду благодаря поддержке Intel Neural Compute Stick 2. Без этого аппаратного ускорителя обработка данных замедляется до ползания, а процессор Raspberry Pi в основном занят декодированием входных данных MP4. Неудивительно, что преимущество модели YOLOv3-tiny в производительности достигается за счет низкой точности обнаружения объектов: хотя люди и велосипеды обнаруживаются достаточно хорошо, другие объекты, такие как собаки и мячи, не обнаруживаются вообще.

Когда дело доходит до вывода в прямом эфире с камеры, команда запуска выглядит довольно похожей, за исключением, конечно, отсутствия входного видеофайла, так что приложение по умолчанию использует обработку ввода с камеры, то есть:

python tinyYOLOv3.py --m "frozen_darknet_yolov3_model.xml" --l "coco.names"

Опять же, вам может потребоваться добавить ваши конкретные пути к параметрам файла меток модели и класса. Частота кадров увеличивается до 4–5 кадров в секунду. Это связано с тем, что обработка входного файла MP4 заменена менее требовательной к вычислениям обработкой изображения с камеры. Как и в сценарии входного видео, некоторые объекты, такие как пульт дистанционного управления и кофейная кружка, обнаруживаются довольно надежно, в то время как, например, стул за столом не обнаруживается вообще.

В зависимости от сценария применения эти относительно низкие уровни точности могут быть достаточно хорошими. В противном случае можно было бы использовать более точные, но часто менее эффективные модели, такие как одноразовые детекторы MobileNet. 🗹

Готово.

Начав с обзора аппаратных ускорителей Edge AI и плат для разработки, а также руководств по настройке Raspberry Pi и Intel OpenVINO, включая демонстрационное приложение для обнаружения объектов, в части 1, нам удалось пройти весь путь до настраиваемого - реализация приложения для обнаружения объектов на основе YOLOv3-tiny, обрабатывающего видеофайл или вход камеры на периферийном устройстве Raspberry Pi с Intel Neural Compute Stick 2. Кодовую базу можно найти на GitHub.

Хотя пакет Intel OpenVINO отличается необычной сложностью, в целом он представляет собой отличный и простой способ реализации приложений ИИ на периферийных устройствах, особенно при использовании предварительно обученных и предварительно преобразованных моделей из Open Model Zoo.

Благодаря этим относительно недавним разработкам, область сценариев приложений Edge AI стала слишком многочисленной, чтобы ее можно было упомянуть, и варьируется от, например, умного дома или умных дронов до распознавания жестов и сценариев автоматизации на основе визуальных датчиков. Все, что необходимо, - это относительно недорогие устройства, такие как Raspberry Pi и аппаратный ускоритель, бесплатная библиотека OpenVINO, немного воображения и немного настойчивости.

Источники
[1] Y. Xu, X. Liu, L. Qin и S.-C. Чжу, «Перекрестное отслеживание людей с помощью пространственно-временного анализа, ориентированного на сцены», Конференция AAAI по искусственному интеллекту (AAAI), 2017 г.

[2] Дж. Редмон и А. Фархади, «YOLOv3: постепенное улучшение», технический отчет, arXiv: 1804.02767, апрель 2018 г.