В части 5 мы использовали три разные предварительно обученные модели для обнаружения объектов и сравнили их с помощью пары изображений.

Мы узнали, что модели имеют очень разные требования к памяти, причем самой экономной моделью является Inception v3 с «всего» 43 МБ. Очевидно, возникает вопрос: «Можем ли мы запустить это на чем-то действительно маленьком, скажем, на Raspberry Pi?». Что ж, давай узнаем!

Построение MXNet на Pi

Есть официальное руководство, но я обнаружил, что в нем отсутствуют некоторые шаги, поэтому вот моя версия. Он отлично работает на Raspberry Pi 3 с последней версией Raspbian.

$ uname -a
Linux raspberrypi 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux

Сначала добавим все необходимые зависимости.

$ sudo apt-get update
$ sudo apt-get -y install git cmake build-essential g++-4.8 c++-4.8 liblapack* libblas* libopencv* python-opencv libssl-dev screen

Затем давайте клонируем репозиторий MXNet и извлечем последнюю стабильную версию. Не пропустите этот последний шаг, так как я обнаружил, что HEAD в большинстве случаев не работает (Обновление 30.04.17: команда разработчиков MXNet связалась со мной и сообщила мне, что теперь существует непрерывная интеграция. Я могу подтвердите, что HEAD теперь работает нормально. Молодцы, ребята).

$ git clone https://github.com/dmlc/mxnet.git --recursive
$ cd mxnet
# List tags: v0.9.3a is the latest at the time of writing
$ git tag -l
$ git checkout tags/v0.9.3a

MXNet может загружать и сохранять данные в S3, поэтому давайте включим эту функцию, она может пригодиться позже. MXNet также поддерживает HDFS, но вам нужно установить Hadoop локально, так что… нет :)

Мы могли бы просто запустить make, но, учитывая ограниченную вычислительную мощность Pi, сборка займет некоторое время: вы не хотите, чтобы она прерывалась по истечении времени ожидания сеанса SSH! Экран решит эту проблему.

Чтобы немного ускорить процесс, мы можем запустить параллельную сборку на 2 ядрах (из 4). Я бы не рекомендовал использовать больше, так как мой Pi перестал отвечать, когда я попробовал.

$ export USE_S3=1
$ screen make -j2

Это должно длиться около часа. Последний шаг - установить библиотеку и ее привязки Python.

$ cd python
$ sudo python setup.py install
$ python
Python 2.7.9 (default, Sep 17 2016, 20:26:04)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mxnet as mx
>>> mx.__version__
'0.9.3a'

Загрузка моделей

После того, как мы скопировали файлы модели на Pi, нам нужно убедиться, что мы действительно можем загрузить их. Давайте повторно используем тот же самый код, который мы написали в части 5. Для справки, Pi находится в режиме CLI с примерно 580 МБ свободной памяти. Все данные хранятся на SD-карте емкостью 32 ГБ.

Попробуем загрузить VGG16.

>>> vgg16,categories = init("vgg16")
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Ой! VGG16 слишком велик для размещения в памяти. Попробуем ResNet-152.

>>> resnet152,categories = init("resnet-152")
Loaded in 11056.10 milliseconds
>> print predict("kreator.jpg",resnet152,categories,5)
Predicted in 7.98 milliseconds
[(0.87835813, 'n04296562 stage'), (0.045634001, 'n03759954 microphone, mike'), (0.035906471, 'n03272010 electric guitar'), (0.021166906, 'n04286575 spotlight, spot'), (0.0054096784, 'n02676566 acoustic guitar')]

ResNet-152 успешно загружается примерно за 10 секунд и прогнозирует менее чем за 10 миллисекунд. Перейдем к Inception v3.

>>> inceptionv3,categories = init("Inception-BN")
Loaded in 2137.62 milliseconds
>> print predict("kreator.jpg",resnet152,categories,5)
Predicted in 2.35 milliseconds
[(0.4685601, 'n04296562 stage'), (0.40474886, 'n03272010 electric guitar'), (0.073685646, 'n04456115 torch'), (0.011639798, 'n03250847 drumstick'), (0.011014056, 'n02676566 acoustic guitar')]

На устройстве с ограниченными возможностями, таком как Pi, различия моделей намного более очевидны! Inception v3 загружается намного быстрее и прогнозирует за несколько миллисекунд. Даже когда модель загружена, на PI остается много оперативной памяти для запуска реального приложения, так что это определенно интересный кандидат для встроенных приложений. Давайте продолжим :)

Захват изображений с помощью камеры Pi

Один из лучших гаджетов, который вы можете добавить к Raspberry Pi, - это модуль камеры. Нет ничего проще в использовании!

>>> inceptionv3,categories = init("Inception-BN")
>>> import picamera
>>> camera = picamera.PiCamera()
>>> filename = '/home/pi/cap.jpg'
>>> print predict(filename, inceptionv3, categories, 5)

Вот пример.

Predicted in 12.90 milliseconds
[(0.95071173, 'n04074963 remote control, remote'), (0.013508897, 'n04372370 switch, electric switch, electrical switch'), (0.013224524, 'n03602883 joystick'), (0.00399205, 'n04009552 projector'), (0.0036674738, 'n03777754 modem')]

Очень круто!

Добавляем пару сервисов Amazon AI, почему бы и нет?

Конечно, я не могу удержаться от запуска той же картинки через Amazon Rekognition, используя скрипты Python, которые я написал некоторое время назад (статья, код).

$ ./rekognitionDetect.py jsimon-public cap.jpg copy
Label Remote Control, confidence: 94.7508468628

Хорошая работа, Rekognition. А теперь… разве не было бы хорошо, если бы Пи на самом деле сказал нам, о чем фотография? Добавить в микс (статью) Amazon Polly не так уж и сложно.

Amazon Rekognition и Amazon Polly - это управляемые сервисы, основанные на технологии глубокого обучения. Нам не нужно беспокоиться о моделях или инфраструктуре: все, что нам нужно сделать, это вызвать API.

Итак, вот видео, на котором мой Raspberry Pi выполняет обнаружение объектов в реальном времени с помощью модели Inception v3, работающей в MXNet, и описывает то, что он видит с помощью Amazon Polly.

Что ж, мы прошли долгий путь! В этих 6 статьях мы узнали, как:

  • управлять данными с помощью NDArrays,
  • определять модели с помощью символов,
  • выполнять прогнозы с помощью модулей,
  • загружать и сравнивать предварительно обученные модели для обнаружения объектов,
  • использовать предварительно обученную модель на Raspberry Pi в режиме реального времени.

Мы сосредоточились на сверточных нейронных сетях для обнаружения объектов, но MXNet - это гораздо больше, так что ожидайте больше статей!

На этом мы завершаем эту серию. Надеюсь, вам понравилось, и вы узнали полезные вещи по пути.