Среди набора примеров для Azure на GitHub был найден один очень интересный: распознавание образов на Raspberry Pi, в офлайне. Авторами предлагается подготовить модель машинного обучения в одном из облачных сервисов Azure, затем перенести ее на компьютер, у которого большую часть времени нет подключения к Интернет, после чего распознавание образов будет работать автономно. Разработчики подготовили проект для двух платформ: ARM32 (собственно Raspberry Pi) и AMD64 (но без поддержки веб-камеры).
На волне коронавирусного хайпа мы решили адаптировать пример для распознавания, надета маска на человеке или нет. Сразу выяснилось, что шаги по адаптации примера не вполне очевидны. В этом материале рассмотрим последовательно, как этот пример, во-первых, модифицировать для работы со своей моделью машинного обучения, во-вторых, перенести его на платформу AMD64. Будем считать, что наш компьютер, на котором работает модель, управляет турникетом: если человек пришел в маске, турникет открывается, если нет — остается закрытым.
Почти у каждого облачного провайдера есть набор средств для машинного обучения, причем порог вхождения для их использования часто достаточно низкий.
В Azure Computer Vision, например, даже не нужно обучать модель перед ее использованием: есть набор облачных API, уже готовый к применению. Для более сложных задач есть Azure Custom Vision, где мы сначала обучаем модель, потом ей пользуемся. Причем знание специфической математики практически не требуется, все делается прямо в браузере мышкой. Знание пары терминов из машинного обучения все-таки понадобится, чтобы понять, насколько качественно работает модель.
Облачных предложений много, а вот пользоваться ими в реальных проектах не всегда удобно. Если все решение сделать только на облаке, это решение так и останется “привязанным” к нему даже после начального развертывания, а именно:
В то же время совсем отказываться от готовых сервисов жутко неудобно, потому что:
Итак, есть вариант “только облако”, есть “совсем без облака”. Оба варианта — крайности. Было бы удобно взять лучшее от облачных сервисов, но “спустить их на землю”. Например, однократно обучить модель на Azure Custom Vision, не углубляясь в вопросы математики, а затем использовать эту модель автономно, без подключения к Интернет.
Такое решение уже существует: Azure IoT Edge позволяет использовать предварительно экспортированную модель машинного обучения без постоянного подключения к Интернет. При этом мы получаем все преимущества и со стороны облака, и со стороны полностью наземного решения:
Подробно мы описывали IoT Edge в этой статье. Вкратце, IoT Edge включает среду выполнения — демон Linux, “внутри” которого выполняются модули, которые, в свою очередь, являются Docker-совместимыми контейнерами. Поддержка устройств IoT Edge включена в Azure IoT Hub. Среда выполнения IoT Edge единожды устанавливается на устройство, а затем набор модулей конфигурируется через облако, с портала Azure, после чего компьютер с IoT Edge может работать автономно, без подключения.
“Родной” платформой для IoT Edge по архитектурным причинам является Linux, хотя с 2019 года IoT Edge доступен и для Windows 10 Enterprise LTSC — ОС для устройств специального назначения.
Модули IoT Edge могут содержать произвольный код, или в модули можно “обернуть” следующие службы Azure:
В нашем случае интерес представляет как раз Custom Vision. В этом сервисе мы подготовим модель распознавания маски и “обернем” ее в модуль.
В IoT Edge заложен механизм обмена сообщениями с между модулями и между модулями и облаком. Сами сообщения передаются в подобии текстового формата, поэтому такой механизм плохо подходит для обмена сырыми двоичными данными (картинками), поэтому в исходном примере от Microsoft для обмена картинками с камеры между модулями используется HTTP, т.е. один из обменивающихся данными модулей является web-сервером, а другой клиентом.
Рассмотрим структуру исходного примера распознавания изображений. Рекомендую посмотреть видео, где ведущие наглядно объясняют, что и как устроено.
На схеме обработка начинается с видеопотока с обычной веб-камеры, подключенной через USB к устройству, на котором предварительно установлена среда выполнения IoT Edge.
Откуда на этом устройстве возьмется среда IoT Edge? Ее необходимо установить вручную, и после того, как она установит подключение к IoT Hub, ей можно (и нужно) управлять уже с IoT Hub. Под “управлением” я также подразумеваю установку модулей.
Модули устанавливаются по команде с IoT Hub. Причем на IoT Edge “спускается” не сам модуль, а как бы ссылка на его скачивание. Механизм устроен так, что предварительно модули нужно выложить в Container Registry (это специальный репозиторий для хранения модулей).
Модули после установки взаимодействуют, как показано на следующей схеме, взятой из того же примера:
Помимо всего прочего, телеметрия отсылается непосредственно в IoT Hub.
Если мы хотим использовать какую-то свою модель с данным примером, в описании к нему нам предлагается просто заменить модель на свою. Мы в Кварта Технологии проверили этот сценарий, но из-за ограниченности ресурсов Raspberry Pi работало такое решение ну очень медленно, так что на практике пользоваться им было очень неудобно.
Соответственно, для этого примера напрашивается более мощная платформа. AMD64 уже поддерживается, вот только в такой конфигурации реальная веб-камера почему-то не предусмотрена и предлагается пользоваться ее эмуляцией за счет зацикленного куска видео, на котором есть и яблоко, и банан. Это нас точно не устроит, поэтому во что бы то ни стало будем подключать “живую” веб-камеру, пользуясь кодом от ARM32.
Есть еще одна проблема. У компьютера на базе AMD64 нет “экранчика” SenseHat, как в Raspberry Pi, поэтому так элегантно, как на SenseHat, результат распознавания уже не отобразить, и придется придумывать что-то свое.
Заходим на Custom Vision (понадобится подписка Azure) и нажимаем New Project.
После создания проекта загружаем предварительно подготовленные картинки следующих типов:
Картинки можно найти в интернете или пофоткать всех знакомых.
Нажимаем кнопку Train, далее Advanced training и ждем, пока модель обучается. После чего на вкладке Performace можно посмотреть параметры качества функционирования модели.
Здесь важно, собственно, понимать эти параметры качества ну хотя бы в общих чертах.
Значение Probability Threshold — это вероятность назначенного тега, в зависимости от которой рассчитываются параметры качества функционирования модели. Значение Probability Threshold = 90% означает, что правильными предсказаниями будут считаться теги, вероятность которых оказалась выше 90%. Думаю, эта фраза требует пояснения. Вообще, в машинном обучении ответы обычно не дискретные (да/нет), то есть модель не может “ответить” на вопрос “на лице ли у человека маска” просто “да” или “нет”. Грубо говоря, будет что-то типа “маска на лице с вероятностью 89%”. Проблема в том, что для расчета параметров качества модели нужны как раз те самые дискретные “да” или “нет”. И вот если параметр этот самый Probability Threshold установлен 90%, то ответ “маска на лице с вероятностью 89%” превратится в дискретное “нет”, а ответ “маска на лице с вероятностью 91%” превратится в дискретное “да”.
Теперь о том, что же это за параметры качества, для которых нужны дискретные “да” или “нет”. Развернутое объяснение этих параметров и то, как они считаются, есть в этой статье. Такое глубокое математическое объяснение нам для понимания ситуации не нужно, поэтому здесь мы ограничимся качественным описанием.
Чем больше каждое из значений — тем лучше.
Внизу страницы видно, что данные параметры рассчитываются по каждому из тегов раздельно.
Модель следует опубликовать (Publish), а затем экспортировать (Export — Dockerfile — Linux). Полученный файл далее будет использоваться в модуле IoT Edge.
Из-за архитектурных особенностей примера нам понадобится платформа (а именно — процессор) с поддержкой AVX инструкций (узнать, поддерживает ли платформа AVX инструкции, можно, выполнив команду grep avx /proc/cpuinfo) — это потребуется для корректной работы библиотеки tensorflow. Если вы хотите использовать платформу без поддержки AVX, потребуется пересобрать библиотеку, что выходит за рамки данной статьи. Упростим себе жизнь и возьмем платформу с соответствующей поддержкой. Мы использовали Intel NUC на базе Core i5.
В качестве ОС будем использовать Ubuntu 20.04 LTS. Сложность заключается в том, что инструкций для установки IoT Edge для данной версии нет (слишком свежая по мнению Microsoft?), поэтому о процессе настройки расскажем достаточно подробно.
Вначале установите саму ОС с графическим окружением, затем откройте командную строку для установки Edge. По умолчанию все команды выполняются в домашнем каталоге (~).
Установим необходимые утилиты:
sudo apt-get update
sudo apt-get install wget nano
Устанавливаем конфигурацию репозитория:
wget https://packages.microsoft.com/config/ubuntu/20.04/prod.list
mv prod.list microsoft-prod.list
Копируем полученный файл в директорию sources.list.d, чтобы ОС “видела” репозитории Microsoft:
sudo cp ./microsoft-prod.list /etc/apt/sources.list.d/
Загружаем и устанавливаем публичный ключ Microsoft GPG:
wget https://packages.microsoft.com/keys/microsoft.asc
cat microsoft.asc | gpg --dearmor > microsoft.gpg
sudo cp ./microsoft.gpg /etc/apt/trusted.gpg.d/
Устанавливаем ПО для контейнеризации (обратим внимание на первую команду — ее обязательно нужно выполнить, так как мы добавили новые репозитории и apt еще “не в курсе”):
sudo apt-get update
sudo apt-get install moby-engine
Устанавливаем демон IoT Edge:
sudo apt-get install iotedge
И с удивлением обнаруживаем, что такого пакета в добавленных выше репозиториях нет (это касается только нашей Ubuntu 20.04 — на момент публикации статьи), поэтому вместо следования документации пойдем своим путем. Можем добавить репозитории от более ранней версии Ubuntu (18.04 — что, строго говоря, не очень хорошая идея) или установить пакеты вручную (правда, опять же, от более ранней версии). Пойдем вторым путем и установим нужные пакеты с GitHub. Ищем Latest release и устанавливаем его при помощи dpkg. Нам также понадобится libssl определенной версии:
wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl1.0/libssl1.0.0_1.0.2n-1ubuntu5_amd64.deb
sudo dpkg -i libssl1.0.0_1.0.2n-1ubuntu5_amd64.deb
wget https://github.com/Azure/azure-iotedge/releases/download/1.0.10.4/libiothsm-std_1.0.10.4-1_ubuntu16.04_amd64.deb
sudo dpkg -i libiothsm-std_1.0.10.4-1_ubuntu16.04_amd64.deb
wget https://github.com/Azure/azure-iotedge/releases/download/1.0.10.4/iotedge_1.0.10.4-1_ubuntu16.04_amd64.deb
sudo dpkg -i iotedge_1.0.10.4-1_ubuntu16.04_amd64.deb
Среда выполнения IoT Edge установлена, но она пока не подключена к Azure. Чтобы это сделать, наберем команду:
sudo nano /etc/iotedge/config.yaml
И в открывшемся файле увидим, что для подключения к Azure необходимо указать значение device_connection_string в разделе provisioning. Для того, чтобы получить это значение, зарегистрируем наш экземпляр IoT Edge в Azure.
Все экземпляры IoT Edge подключаются к IoT Hub, который мы сейчас и создадим на портале Azure. Если у вас нет подписки — создайте пробную.
Сама процедура создания IoT Hub и регистрации IoT Edge подробно описана в документации. Особого смысла перепечатывать ее здесь не вижу, поэтому предлагаю вам повторить то, что в ней описано:
В результате ваше устройство IoT Edge будет подключено к созданному IoT Hub, а также будет подготовлен репозиторий контейнеров.
Внутри IoT Edge нашего решения будут исполняться сразу три модуля:
Схема коммуникаций между модулями показана ниже:
Перед тем, как приступить к разработке, нам потребуется загрузить и установить соответствующие инструменты.
Важно! Последующие действия нужно выполнять на компьютере с Windows 10, а не на устройстве с IoT Edge.
Важно! В случае проблем с виртуализацией Docker выполните команду в командной строке администратора: bcdedit /set {current} hypervisorlaunchtype Auto и перезагрузите компьютер.
Важно! Включение Hyper-V сделает неработоспособной виртуализацию VirtualBox. Для того, чтобы быстро восстановить работоспособность VirtualBox, можно выполнить команду в командной строке администратора: bcdedit /set {current} hypervisorlaunchtype off, но при этом “сломается” Hyper-V и Docker.
Получите исходный код примера, выполнив команду:
git clone https://github.com/Azure-Samples/Custom-vision-service-iot-edge-raspberry-pi.git
Рекомендую также переключиться на коммит, который был использован для модификации примера:
git checkout 6b3540f9b31121321f9e75d8df0ed86397c9324f
В Visual Studio Code откройте папку с примером (File — Open Folder) и ознакомьтесь с его структурой. Вы увидите три модуля, о которых мы говорили выше. Если при открытии среда предложит установить дополнительные расширения, сделайте это.
При написании этого раздела я находился, что называется, меж двух крайностей. С одной стороны, можно просто выложить модифицированные исходники и сказать, что пример готов к применению, но тогда и объяснять будет особо нечего. С другой стороны, можно полностью описать все выполненные изменения примера, но это будет слишком громоздко.
Вместо этого было решено выбрать нечто среднее. Для файлов с минимальными изменениями — опишу сами изменения. Для файлов со значительными изменениями — дам ссылку на модифицированные файлы, заодно расскажу, что менялось.
Итак, поехали.
Необходимо установить параметры реестра (репозитория) контейнеров, взятые с портала Azure:
Данный файл следует удалить с файловой системы.
Поскольку на AMD64 мы хотим использовать веб-камеру, которой изначально для данной платформы не предусмотрено, нам потребуется модификация, в которой будут указаны все необходимые компоненты. Модифицированный файл можно найти в приложенном архиве.
Поскольку мы перенесли решение на более мощную платформу (по сравнению с Raspberry Pi), уменьшим временной интервал, за который накапливаются кадры для анализа. Для этого ищем строку time.sleep(1.0) и заменяем 1.0 на 0.1.
Здесь потребуется подобрать версии библиотек для AMD64. Модифицированный файл можно найти в приложенном архиве.
Данный файл содержит метки, которые получает каждое изображение. Эти метки должны соответствовать меткам из сервиса Custom Vision, поэтому содержимое файла должно быть следующим:
MaskNotOnFace
MaskOnFace
Двоичный файл модели из Custom Vision — следует заменить существующий на подготовленный нами ранее.
Такого файла в примере нет, нам нужно его создать.
SenseHatDisplay — модуль отображения результата распознавания. Но на нашей платформе AMD64 никакого шилда SenseHat нет, поэтому из данного модуля весь код, взаимодействующий, собственно, с SenseHat, уберем, и будем реализовывать простейший веб-сервер на Python, который сможет прямо в браузере показывать результат распознавания.
Файл можно найти в приложенном архиве.
В раздел platform нужно внести изменения, а именно добавить amd64:
"amd64": "./amd64.Dockerfile",
Добавить с заменой существующих следующие файлы, которые можно найти в приложенном архиве. Файлы содержат код и страницы веб-сервера, отображающего результат распознавания.
Веб-сервер достаточно “хитрый”. Он отдает клиенту страницу, в которой выполняются сразу две важных вещи:
Подчеркну, что фактически получаются два веб-сервера — один с видеопотоком, второй с результатом распознавания. Причем страницу, с которой идет обращение к этим серверам, отдает второй сервер. Сама эта страница доступна по адресу http://127.0.0.1:8000.
Для сборки потребуется подключение к Интернет.
На нашем IoT Edge устройстве логинимся в UI и прямо браузером заходим на веб-страницу по адресу http://localhost:8000, где наблюдаем веб-страницу, как на картинке. Надеваем маску и смотрим в камеру, система определяет, что маска на нас.
Дело за малым — подключить исполнительное устройство, которое открывает наш условный турникет.
К огромному сожалению, моделей в маскобикини, чтобы проверить срабатывание тега MaskNotOnFace, у нас не нашлось, но на тестовых картинках все работало хорошо.
Если модули собрались и отлажены, а устройство в сети, вмешательство на стороне IoT Edge не требуется. Но иногда на этапе запуска возникают проблемы (так я, например, узнал, что без AVX инструкций и/или пересборки библиотеки tensorflow модуль классификатора не работает). IoT Edge предлагает разные способы диагностики. Подробно о них можно прочитать здесь. Самое главное, что может пригодиться:
Для того, чтобы обновить модуль на устройстве IoT Edge, нужно либо инкрементировать его версию при публикации, либо удалить существующий и его файлы из реестра модулей (на портале Azure), иначе IoT Edge не увидит изменения.
Дальше можно отключить компьютер с IoT Edge от Интернета и убедиться, что все работает так же хорошо.
При всем перечисленном мы, конечно, не рассмотрели всех возможностей IoT Edge, например, мы никак не обработали телеметрию на облаке, а могли бы вести, например, журнал “проходов через турникет” и считать какую-нибудь статистику и даже сохранять ее локально при помощи SQL Edge, а затем синхронизировать с облаком.
Мы также совсем не рассмотрели возможности управления устройством IoT Edge с портала Azure, так как это было незначимо для темы данной статьи.
Среди возможных улучшений — более плавная визуализация видеопотока, так как он все еще состоит из хотя и быстро, но все же сменяющихся картинок — такова архитектура примера.
Мы убедились, что при помощи сервисов Azure можем комбинировать все плюсы как облачной, так и наземной разработки, и при этом получать решение, которое без проблем будет работать автономно.
Если у вас еще остались вопросы по облачным технологиям Microsoft и Интернету вещей — обращайтесь к нам в Кварта Технологии.
Файлы к статье можно скачать по ссылке.
Автор статьи — Сергей Антонович, ведущий инженер Кварта Технологии. Связаться с ним можно по адресу sergant (at) quarta.ru.
VK объявляет о приобретении 40% компании Intickets.ru (Интикетс). Это облачный сервис для контроля и управления продажей билетов на мероприятия. Сумма…
OpenAI готовится запустить собственную поисковую систему на базе ChatGPT. Информацию об этом публикуют западные издания. Ожидается, что новый поисковик может…
Центр управления связью общего пользования (ЦМУ ССОП) Роскомнадзора рекомендовал компаниям из реестра провайдеров ограничить доступ поисковых ботов к информации на российских сайтах.…
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…
Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…