Intel Movidius

Intel Movidius Neural Compute Stick 2 привлек мое внимание как дешевая и, казалось бы, простая возможность запускать нейронные сети на периферии и делать серьезные выводы ИИ на периферийных устройствах (например, Raspberry Pi). Это действительно доступно по цене около 70 евро. В моем университете у все большего числа научных сотрудников валяется один - не знающий, что с ним делать. Поскольку мой отдел на самом деле не занимается ни визуализацией, ни НЛП, мы не хотели переносить стандартную модель из модельного зоопарка, но иметь собственные сети, работающие на Movidius. Итак, я решил выяснить, как это сделать, но оказалось, что все не так просто. Чтобы всем было проще, я решил написать этот пост в блоге. Я надеюсь, что это помогает! Пример кода для преобразования простого NN из Scikit-Learn, Pytorch и Keras доступен на моем github.

Создание и обучение вашей модели

Мы хотели быть как можно более общими в нашем подходе к обучению моделей. После некоторого отчаяния при попытке переноса моделей напрямую из Tensorflow 2.0 с использованием NCSDK, аналогичного таковому в Oviyum, я нашел довольно простой способ переноса с использованием формата ONNX. Используя это, мы можем построить и обучить нашу сеть PyTorch, Tensorflow, Keras или даже SciKit Learn - ну и всему, что можно экспортировать в ONNX. На своей домашней странице они предлагают обзор возможных фреймворков и функций. Но не все функции пока поддерживаются Intel, их список можно найти здесь. Я планирую выпустить полный конвертер в какой-то момент в будущем, но пока вы должны сами проверить, все ли ваши слои / функции поддерживаются.

Установка

Сначала нам понадобится Openvino Toolkit для преобразования наших моделей ONNX в формат Movidius, называемый промежуточным представлением (IR). Я запускал его на своей Windows 10 и тестировал примеры, используя свою оболочку Anaconda Shell - не забывайте запускать сценарий bash, который устанавливает переменные среды вначале каждый раз, когда вы открываете новую оболочку! Кроме того, вам понадобится python (версия 3 - я рекомендую Anaconda при работе в Windows), IDE по вашему выбору (я предпочитаю PyCharm) и некоторые дополнительные пакеты (лучше всего установить в виртуальной среде). Вам нужен фреймворк, в котором вы хотите создать свою модель (Pytorch, Keras или SciKit Learn или что-то еще), пакет ONNX и, возможно, конвертер, который идет с вашим фреймворком. Например, для преобразования Keras вам нужно запустить:

conda install scikit-learn, keras, pandas
pip install keras2onnx

Экспорт вашей модели

После обучения модели вам необходимо экспортировать модель и веса в формат ONNX. Это действительно просто. Для вашей модели keras вы просто выполните:

import keras2onnx
import onnx
onnx_model = keras2onnx.convert_keras(model, model.name)
onnx.save_model(onnx_model, 'keras_iris_model.onnx')

Вы можете найти примеры кода для сохранения вашей модели как onnx из keras, pytorch и sklearn на моем github. По возможности попробуйте сохранить модель без параметров обучения.

Теперь давайте посмотрим на нашу модель и проверим, какие параметры мы сохранили.

Для открытия файлов onnx рекомендую Netron. Это позволяет вам видеть все ваши слои, соединения и даже веса. Красивый! Но, как видите, наша сеть - это не только явно определенные уровни. В зависимости от вашей структуры модель все еще имеет некоторые параметры обучения или некоторые параметры удобного декодирования, такие как эта модель sklearn. Zip-Map здесь, например, сопоставляет выходной индекс с конкретным именем класса - это приятно, но невозможно для преобразования модели Openvino.

Обрезка вашей модели

Чтобы успешно преобразовать вашу модель с помощью Openvino, вам (иногда) необходимо ее обрезать. Это означает, что вам нужно удалить все, что модели не нужно или что недоступно для преобразования Openvino. Слои или узлы, как они называются в ONNX, можно легко удалить с помощью пакета python onnx.

import onnx
onnx_model = onnx.load(model_path)
graph = onnx_model.graph
graph.node.remove(graph.node[9])
onnx.save(onnx_model, save_path)

Я знаю, что это не самый чистый способ сделать это, но он все равно работает. Долгосрочная цель здесь - это очиститель графа, который удаляет все узлы, недоступные для Openvino, и выдает ошибку, если модель неконвертируема. Если у вас есть что-то подобное, не стесняйтесь и поделитесь этим. А пока нам нужно делать это вручную.

Преобразование вашей модели в формат Openvino IR

Теперь, когда у нас есть идеальная модель ONNX, мы можем следовать чрезвычайно информативному руководству Intel о том, как ее преобразовать. - Это не очень полезно ... Вместо этого следуйте этим инструкциям:

1) Откройте оболочку (Anaconda) от имени администратора
2) Активируйте setupvars.bat
3) Убедитесь, что вы установили правильные предварительные требования
4) Перейдите в каталог оптимизатора моделей Intel (C: \ Program Files (x86) \ IntelSWTools \ openvino \ deployment_tools \ model_optimizer \)
5) Запустите скрипт mo.py, указав форму ввода и каталог модели.

python mo.py — input_model Path\to\your\model.onnx — input_shape [10,4] — log_level WARNING

6) Просмотрите сообщение УСПЕХ и устройте вечеринку.
7) Скопируйте файлы .xml и .bin, предоставленные оптимизатором модели, в выбранный вами каталог.

Мне потребовалось некоторое время, чтобы понять это, поэтому вот самые распространенные и загадочные ошибки, с которыми я сталкивался:

- Не все формы вывода были выведены или полностью определены для узла «Добавить». - ›Означает, что вам нужно установить форму ввода.
- Невозможно вывести формы или значения для узла« ZipMap ».
[ОШИБКА] Для узла« ZipMap »не существует зарегистрированной функции« вывести »с op =« ZipMap ». Пожалуйста, реализуйте эту функцию в расширениях. - ›Что ж, это означает, что вам нужно обрезать вашу модель, поскольку функция ZipMap недоступна для Openvino
- PermissionError: [Errno 13] Permission denied:‘ Path ’-› вам необходимо запустить оболочку от имени администратора

Запуск вашей модели на Movidius

Здесь мы снова можем полагаться на великолепную документацию и руководства пользователя от Intel - НЕЛЬЗЯ!

Единственное, что мне помогло, - это посмотреть на примеры, поставляемые с инструментарием в C: \ Program Files (x86) \ IntelSWTools \ openvino \ _2019.3.379 \ deployment \ _tools \ inference \ _engine \ samples \ python \ _samples - даже хотя они не содержат много комментариев.
Если вы хотите запустить код в своей среде IDE, убедитесь, что вы активировали setupvars.bat перед запуском среды IDE из той же оболочки (или любым другим способом выполнить настройку). Чтобы запустить нашу сеть, нам нужно импортировать два класса IECore и IENetwork. Мы загружаем нашу модель, определяем входные и выходные большие двоичные объекты, загружаем сеть на флешку и теперь, наконец, готовы что-то сделать! Опять же, на моем гитхабе есть более подробный код.

from openvino.inference_engine import IECore, IENetwork
ie = IECore()
net = IENetwork(model=model_xml, weights=model_bin)
input_blob = next(iter(net.inputs))
out_blob = next(iter(net.outputs))
exec_net = ie.load_network(network=net, device_name=’MYRIAD’)
res = exec_net.infer(inputs={input_blob: X_test[:10,:]})
res = res[out_blob]

Надеюсь, это помогло вам начать работу с Movidius Compute Stick для нестандартных моделей и избавило вас от раздражения и отчаяния, связанных с документами Intel, с которыми я столкнулся. Если у вас есть советы или улучшения, не стесняйтесь делиться!