ВНИМАНИЕ: Эта статья может вызвать положительные эмоции у пользователей TF Lite Micro. Будьте готовы, мы предупреждали вас.

Мотивация — Развертывание машинного обучения на микроконтроллерах

Вы когда-нибудь пытались развернуть модель машинного обучения (ML) на встроенном устройстве? Повышение производительности микроконтроллеров за последние годы делает выполнение алгоритмов машинного обучения на микроконтроллерах жизнеспособным вариантом для отдельных случаев использования. И жизнеспособные варианты использования растут с каждым днем. Помимо производительности вычислений, также необходима инфраструктура компилятора с поддержкой машинного обучения. TensorFlow Lite для микроконтроллеров (TFL4uC) — это платформа C++ с открытым исходным кодом от Google, позволяющая разработчикам генерировать код для определенных микроконтроллеров из графов Tensorflow (TF). Но не все операции TF поддерживаются TFL4uC (на самом деле — по состоянию на 11/2022 — только 96 из 1457!). Одной из отсутствующих операций раньше была эффективная операция долговременной кратковременной памяти (LSTM)!

На рисунке выше показан возможный рабочий процесс для развертывания модели машинного обучения TensorFlow во встроенной системе. Существует три основных пакета программного обеспечения с различными аппаратными целями: (1) TensorFlow (TF) предназначен для центров обработки данных, рабочих станций и настольных ПК; (2) TensorFlow Lite (TFLite) более легкий и оптимизированный для мобильных устройств под управлением Android/iOS. И TF, и TFLite поставляются со средой выполнения, требующей операционной системы. Операционная система добавляет значительные накладные расходы только на развертывание вашей модели; (3) Введите TensorFlow Lite для микроконтроллеров (TFL4uC). TFL4uC генерирует автономный исполняемый файл для конкретного целевого оборудования. Только необходимые операторы сохраняются в топологическом порядке в сериализованной структуре данных. Больше не нужна ни операционная система, ни среда выполнения! Если ваша модель помещается в памяти, она уходит. Ну, почти …

Ограниченная поддержка оператора TFL4uC

В TFL4uC поддерживается только ограниченное подмножество операций TF. Если в вашей модели есть неподдерживаемая операция, вам не повезло. До недавнего времени TFL4uC знал только развернутые реализации LSTM. Развернутые LSTM потребляют много памяти, поэтому было невозможно развернуть даже очень простые модели LSTM на микроконтроллерах с оперативной памятью менее МБ. Но почему LSTM актуальны? Потерпите нас для короткого обхода.

Распознавание человеческой деятельности (HAR)

Классификация деятельности человека (например, бег, сидение, езда на велосипеде и т. д.) может быть выполнена на основе данных акселерометра. Это используется, например, в фитнес-часах. Фитнес-часы очень чувствительны к стоимости и поэтому всегда имеют мало памяти. LSTM оказался эффективным подходом для этого приложения. В целом модели LSTM широко используются для решения задач на основе данных временных рядов. Нам было интересно создать собственный детектор активности и посмотреть, сможем ли мы запустить его на Arduino Nano.

Мы использовали набор данных UCI HAR в качестве обучающих данных для модели Keras LSTM. В качестве базовой модели мы выбрали модель LSTM из этой Любопытно статьи. Но мы удалили двунаправленный слой, чтобы упростить модель. 10 296 образцов UCI состоят из данных акселерометра по трем осям (оси X, Y и Z), полученных со смартфона с частотой 50 Гц для шести различных видов деятельности. После применения шумовых фильтров сигналы датчиков дискретизируются в скользящих окнах с фиксированной шириной 2,56 с и перекрытием 50%. Таким образом, каждая выборка состоит из 128 значений на окно. Примеры двух разных действий, сидения и лежания, можно увидеть на двух графиках ниже.

Различные виды деятельности имеют свою подпись. Это позволяет классифицировать их. А с помощью ML мы можем построить классификатор, просто представив примеры. Следующий фрагмент кода демонстрирует подготовку данных. Обратите внимание, что форматирование и предварительная обработка набора данных UCI здесь не показаны.

Для каждой из трех осей (оси x, y и z) у нас есть 128 значений ускорения. Таким образом, входная форма модели установлена ​​​​на: 128 временных шагов и 3 функции. Далее мы выбираем размер пакета 1. Количество LSTM-ячеек (= размерность выходного пространства) устанавливается равным 12. Мы обратим внимание на опцию развертывания позже — давайте пока пропустим это.
Путем наложения плотного слоя с шестью нейронами и функциями активации softmax на слой LSTM вычисляется значение вероятности для каждого из шести действий. Фрагмент ниже показывает слои модели, которые затем обучаются.

Выходные данные выше показывают прогресс в течение первых четырех периодов обучения. Потери при обучении и проверке за эпохи показаны на рисунке ниже. После 20 эпох модель сошлась, и у нас есть обученная модель TF. Безусловно, точность модели не идеальна, но достаточна для наших экспериментов.

Аппаратное обеспечение — Arduino Nano 33 BLE Sense

Наша цель — развернуть нашу модель HAR на Arduino Nano 33 BLE Sense, что можно увидеть на рисунке ниже.
Плата оснащена системой-на-кристалле (SoC) nRF52840 с 32-битным процессорным ядром ARM Cortex-M4, 256 КБ SRAM, 1 МБ флэш-памяти и работает на тактовой частоте 64 МГц. Кроме того, плата оснащена различными датчиками, в том числе акселерометром, микрофоном, датчиком жестов и датчиком влажности. Подгонка модели ML к памяти объемом 256 КБ — довольно сложная задача. Но если бы не было проблем, нам было бы не о чем здесь сообщать.

Для полноты картины: мы также проводили эксперименты на ПК (процессор Intel Core i5–6200 с тактовой частотой 2,40 ГГц и 16 ГБ памяти). Код C++ выполнялся в контейнере Docker на базе Linux.

Развертывание LSTM до сентября 2022 г.

Теперь вы знаете, что такое распознавание человеческой деятельности и как LSTM помогают в классификации действий. Мы пытаемся развернуть простой LSTM на Arduino Nano 33 BLE Sense. Вернемся к исходному вопросу использования TFL4uC для поставленной задачи.

Чтобы перенести обученную модель TF на TFL4uC, необходимо сначала преобразовать ее в модель TFLite. Это делается в несколько строк (см. фрагмент кода ниже). За нас работает Конвертер TF Lite.

Мы протестировали функциональность на ПК, адаптировав пример микроречи (загрузив нашу пользовательскую модель и выполнив вывод). Команда make, показанная на скриншоте ниже, должна скомпилировать пример микроречи (для ПК). Однако до недавнего времени эта команда приводила к ошибке кода операции, как показано ниже:

Сообщение сообщает нам, что операция UNIDIRECTIONAL_SEQUENCE_LSTM отсутствует. Давайте исследуем модель дальше, чтобы понять ее структуру. С помощью Netron Analyzer мы строим график потока данных свернутой модели LSTM, который показан ниже. UNIDIRECTIONAL_SEQUENCE_LSTM — это один оператор в графе потока данных. TFL4uC не может сопоставить операцию с машинным кодом. Тупик.

Разворачивается на помощь. Мы развернули слой LSTM модели TF, установив для аргумента «развернуть» значение «true», и снова обучили модель. Затем мы преобразовали его в модель TFLite. С помощью Netron проверяем, что изменилось. На приведенных ниже графиках теперь показаны части развернутой модели LSTM. Развертывание приводит к огромному графу модели (2,312 против 23 операторов). Однако теперь можно построить и выполнить (развернутую) модель LSTM на ПК.

Пример микроречи и другие также доступны в виде библиотеки Arduino от TensorFlow. Мы снова адаптировали этот пример для загрузки и запуска нашей пользовательской развернутой модели LSTM.
После прошивки кода на Arduino Nano ответа не последовало. Это было похоже на синий экран — и он им оказался.
Более подробное изучение развернутой модели показывает, что ей требуется 398 кБ памяти. Скомпилированный исходный код сохраняется в области флэш-памяти объемом 1 МБ. При загрузке модели в оперативную память микроинтерпретатором TFL4uC она превышает доступную память. Поскольку мы не добились дальнейшего уменьшения размера модели, выполнение вывода на развернутом LSTM Arduino Nano было невозможным.

сентябрь 2022 г.

8 сентября 2022 года в 14:01:39 по центральноевропейскому времени новая версия TFL4uC была размещена в репозитории tflite-micro github. Сравнение с предыдущей версией показало: операция UNIDIRECTIONAL_SEQUENCE_LSTM поддерживается. Наконец-то у нас есть недостающая операция для эффективной реализации LSTM! Я с нетерпением ждал этого момента более двух лет! Улыбнитесь и скажите да вслед за мной :-).

Сейчас мы попробовали снова. И вот! Мы могли построить и выполнить свернутую модель LSTM. Мы отслеживали потребление памяти и времени развернутой и развернутой модели LSTM. Результаты можно увидеть в таблице ниже.

Для измерения затрат времени на ПК один образец подавался на модель 1000 раз. Это повторяется 500 раз, чтобы получить среднее значение измерений. Мы наблюдали среднее время выполнения 708 мс для развернутого LSTM на ПК. Деление на 1.000 приводит к данному результату в таблице.
Процедура аналогична измерению затрат времени на Arduino. Но — чтобы сохранить время эксперимента на приемлемом уровне — в модель подается только десять отсчетов, а измерение повторяется 100 раз. памяти) модели.

Помните — развернутой модели требовалось не менее 398 КБ! Свернутая модель LSTM теперь требует примерно в 40 раз меньше памяти (10 КБ), чем развернутая! Кроме того, выполнение на ПК вдвое быстрее. Но самое главное — модель теперь помещается в память Arduino Nano BLE, и мы можем ее успешно запустить. Мы измерили среднее время выполнения 132 мс на выборку. Хотя это в 370 раз медленнее, чем время выполнения на ПК (357 мкс), нормализация его по тактовой частоте (64 МГц против 2,4 ГГц) уменьшает разницу до 9,8. Это дань уважения, которую мы должны заплатить за более простой набор инструкций (и, возможно, менее оптимизированную реализацию ядра LSTM).

Самое главное: если вы сравните время выполнения 132 мс с требованием реального времени 2,56 с, мы уже достаточно быстры. Без всякой оптимизации. В качестве следующего шага можно дополнительно изучить компромисс между временем вычислений, объемом памяти и точностью. Более сложные модели могут привести к большей точности, но также и к более медленному времени вычислений. Но это уже другая история…

В этой статье показан путь от модели TF LSTM до реализации в реальном времени на Arduino Nano, а также взлеты и падения на этом пути. Возможно, мы могли бы мотивировать вас следовать по нашим стопам. Наслаждайтесь новой операцией и следите за обновлениями, чтобы в TFL4uC появилось больше операций TF. Места достаточно, так как из 1457 основных операций TF в настоящее время только 158 изначально поддерживаются TF Lite и только 96 поддерживаются от TFL4uC.

Вы также столкнулись с отсутствующей операцией в TFL4uC? Расскажите в комментариях и подумайте о подаче соответствующего запроса на github.

Спасибо Manfred Mücke и Christoph Gratl за обсуждение, корректуру и предложение этой интересной работы.