Использование Intel Movidius для нейронных сетей

Введение


Мы занимаемся разработкой глубоких нейронных сетей для анализа фото, видео и текстов. В прошлом месяце мы купили для одного из проектов очень интересную штуковину:
Intel Movidius Neural Compute Stick.
Intel MNCS

Это специализированное устройство для нейросетевых вычислений. По сути, внешняя видеокарточка, заточенная под нейронные сети, очень компактная и недорогая (~$83). Первыми впечатлениями от работы с Movidius«ом мы и хотим поделиться. Всех заинтересовавшихся прошу под кат.

Вычислительные мощности устройства


В плане вычислений нейронки чрезвычайно прожорливы: для их обучения нужны GPU, а для использования в реальных задачах — тоже GPU или мощные CPU. Movidius NCS позволяет использовать глубокие нейросети на устройствах, которые были первоначально на это не рассчитаны, например: Raspberry Pi, DJI Phantom 4, DJI Spark. Речь идёт только про этап предсказания (inference заранее обученной сети): обучение нейросетей на Movidius пока что не поддерживается.

Производительность чипа — около 100 гигафлопс, 10^9 FLOPS, (это примерно соответствует уровню топовых суперкомпьютеров начала 90ых, сейчас это порядка сотен петафлопс, 10^15).

Для справки: FLOPS — это количество вычислительных операций или инструкций, выполняемых над операндами с плавающей точкой (FP) в секунду. Для углубления в тему советую интеловскую статью.

Железка построена на базе чипа Myriad 2. В конфигурацию Myriad 2 входит 12 специализированных программируемых векторных процессоров. Компоненты SoC подключены к высокоскоростному внутреннему соединению, работающему с минимальными задержками. Myriad 2 позиционируется как сопроцессор совместно с процессором приложений в мобильных устройствах, или как автономный процессор в устройствах носимой или встраиваемой электроники.

Myriad 2
Сам процессор Myriad 2

Ну, а в форм-факторе флешки (Neural Compute Stick) его можно использовать для встраивания нейросетей в беспилотники, например, вместе с Raspberry Pi.

Приступим к установке и запуску первой программы на NCS


Что нам понадобится


  • Intel Movidius. Узнать, где он продаётся, можно по ссылке. Мы брали на Амазоне.
  • Ubuntu 16.04 LTS или Raspbian OS. Официально поддерживаются только они, но в принципе можно попробовать использовать и на других линуксах.
  • SDK с официального репозитория компании. Его мы скачаем дальше из консоли.
  • Экспортированный из Tensorflow или Caffe бинарник с графом весов нейросети. Последняя версия Movidius поддерживает только форматы моделей Tensorflow или Caffe. Поскольку мы будем запускать стандартный пример, строить самим граф нам не придётся.


Подготовка


Подключаем Movidius в разъем USB 3.0. Далее пишем в консоли:

$ git clone https://github.com/movidius/ncsdk.git
$ cd ncsdk
$ sudo make install


Эти команды установят:

  • NCS Libraries → /usr/local/lib
  • NCS Toolkit binaries → /usr/local/bin
  • NCS Include files → /usr/local/include
  • NCS Python API → /opt/movidius


А также добавят путь к python-либе Мовидиуса в PYTHONPATH.

Запустим пример


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

$ make examples


Чтобы подготовить стандартный пример — обученную на ImageNet реализацию inception_v1 — выполним следующие команды:

$ cd examples/tensorflow/inception_v1
$ make all


Последняя команда использует описание сетки и уже обученные веса и компилирует бинарный граф, который мы можем потом уже запустить на Myriad 2 VPU.

Теперь мы запустим тестовый скрипт run.py. Коротко расскажу, что происходит в скрипте в целом (некоторые части скрипта опущены):

#Подключаем библиотеки NCS, numpy, sys и opencv
from mvnc import mvncapi as mvnc
import sys
import numpy
import cv2

#/Кусок кода опущен/

#Указываем путь к бинарному графу
graph_filename = 'graph'

#Указываем путь к папке с картинкой
image_filename = path_to_images + 'mouse.jpg'

#Проверяется доступность NCS-устройства, а затем производится его открытие,
#в ином случае выкидывается ошибка
devices = mvnc.EnumerateDevices()
if len(devices) == 0:
    print('No devices found')
    quit()
device = mvnc.Device(devices[0])
device.OpenDevice()

#Загружается предкомпилированный бинарный граф, экспортированный из TensorFlow
#(ещё поддерживается Caffe)
with open(path_to_networks + graph_filename, mode='rb') as f:
    graphfile = f.read()

#/Кусок кода опущен/

#Подключенный выше граф грузится на устройство
graph = device.AllocateGraph(graphfile)

#Изображение переводится в подходящий формат и загружается на чип
img = cv2.imread(image_filename).astype(numpy.float32)
dx,dy,dz= img.shape
delta=float(abs(dy-dx))
if dx > dy: #crop the x dimension
    img=img[int(0.5*delta):dx-int(0.5*delta),0:dy]
else:
    img=img[0:dx,int(0.5*delta):dy-int(0.5*delta)]
    
img = cv2.resize(img, (reqsize, reqsize))

img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#Нормализация изображения
for i in range(3):
    img[:,:,i] = (img[:,:,i] - mean) * std

print('Start download to NCS...')
graph.LoadTensor(img.astype(numpy.float16), 'user object')

#Получаем результат
output, userobj = graph.GetResult()

#Далее печатаем релевантный топ по категориям и закрываем NCS-устройство
top_inds = output.argsort()[::-1][:5]

print(''.join(['*' for i in range(79)]))
print('inception-v1 on NCS')
print(''.join(['*' for i in range(79)]))
for i in range(5):
    print(top_inds[i], categories[top_inds[i]], output[top_inds[i]])

print(''.join(['*' for i in range(79)]))
graph.DeallocateGraph()
device.CloseDevice()
print('Finished')


Когда мы собирали пример, мы вводили в консоль команду make all, после которой в консоль выводилась полезная информация, например, можно увидеть, как быстро данные проходят через каждый слой сети с помощью Detailed Per Layer Profile. Полезная для отладки и оптимизации штука.

Запускаем скрипт:

$ python3 run.py


Тестовая картинка загрузится на NCS, пройдёт через Inception, и в консоли отобразится результат распознавания (вероятностное распределение по 1000+1 категории датасета ImageNet).

Вывод консоли
Number of categories: 1001
Start download to NCS...
*******************************************************************************
inception-v1 on NCS
*******************************************************************************
674 mouse, computer mouse 0.99512
663 modem 0.0037899
614 joystick 0.00031853
528 desktop computer 0.00021553
623 lens cap, lens cover 0.0001626
*******************************************************************************
Finished


Тестовая картинка
imageЗагрузили эту фотку на Movidius и прогнали через Inception


Видно, что сеть с ~99% уверенностью полагает, что на картинке компьютерная мышь (благодаря нашей подсказке:)), на втором месте с близкой к 0% уверенности — модем, и так далее. Сетка права, так что поздравляем вас с первой нейронкой, успешно запущенной на этом устройстве!

Заключение


В конце хотелось бы перечислить главные достоинства и недостатки устройства.

Сперва плохие новости:

  • Устройство официально поддерживает работу только с Raspbian OS или Ubuntu 16.04 LTS.
  • Устройство и его SDK на данный момент поддерживают только файлы с весами нейросетей в формате Caffe и Tensorflow.
  • На устройстве можно делать только предсказания (inference), а обучать модели нельзя.


Хорошие новости:

  • Вы можете запускать нейронки на Raspberry Pi!
  • Очень простой API на python/C.
  • Низкая потребляемая мощность (1 Вт), устройство питается от USB.
  • Очень быстрый для такого компактного устройства: например, препроцессинг фотографии ~800×800 и прогон её через Inception_v1 занимают ~120–130 миллисекунд.
  • Есть коллекция уже готовых для запуска open-source моделей (так называемый Model Zoo).
  • Интересно, что вы можете подключить сразу несколько NCS, которые прямо из коробки будут работать в параллельном режиме. Впрочем, мы это пока не тестировали.


image
Так Intel предлагает использовать Мовидиусы для ускорения вычислений

Само собой, у данного устройства есть аналоги.

Один из них — и пока самый многообещающий — это Gyrfalcon Technology Laceli, имеющий производительность в 28 раз больше, а энергетическую эффективность в 90 раз выше. Единственное препятствие для покупки — это то, что устройство ещё не вышло на рынок.

Еще один конкурент, который давно присутствует на рынке — это NVIDIA Jetson TX2. Отличия:

  • Очень разные ценовые категории (559$ против 83$)
  • Разные мощности (два ядра CPU на архитектуре Denver 2, четыре ядра ARM Cortex A57 и 256-ядерный Pascal GPU против одного Myriad 2)
  • Разный форм-фактор: Jetson гораздо больше, NCS компактный
  • Оба устройства решают одну и ту же задачу — задачу внедрения нейронок на борт чего-либо: автомобиля, беспилотника и пр.


Если интересно, напишем в ближайшем будущем еще одну статью про использование Jetson TX2 для нейронных сетей. Спасибо за внимание и хорошего дня)

P. S. Intel объявил о старте конкурса по оптимизации нейросетей для Intel Movidius Neural Compute Stick. Регистрация до 26 января, окончание конкурса — 15 марта.

© Habrahabr.ru