Я уже писал большую статью о том как запускать нейронные сети на телефонах. Точнее, статья была про разные аппаратные платформы и библиотеки выполнения нейронных сетей. Но, она абсолютно не рассматривала вопрос запуска нейронных сетей. Ведь библиотеку можно позвать из разных сред, можно из Java разрабатывая на Android studio/Eclipse/Idea. Можно на с++ модулях. Можно из JS, сделав веб-страничку (кстати, на эту тему я тоже делал ролик, а на Хабре была не моя неплохая статья на эту тему). А можно и другими способами.
В этой статье я чуть подробнее расскажу те способы которые мне нравятся и понятны.
Статья будет крайне субъективна. Понятно, что разрабатывая всю жизнь на Java под Android Studio – вам проще будет вызвать нейронку там. Но, если вам, как и мне, не очень знакома мобильная разработка, это может быть интересно. Среднее время запустить все что я тут привожу – один вечер. А это значит – возможность экспериментировать, создать быстрый прототип или самому проверить идею.
Почему не java
Когда-то, свое первое приложение на телефон с распознаванием автомобильных номеров я делал именно под Java. Был это год 2012 где-то. Потом, через год с мелочью мы сделали на эту тему небольшую работу и попробовали развить стартап. Как сейчас помню, что потратил неделю на него.
С тех пор я пару раз пробовал повторить успех и запустить TFLite или его аналоги через Android Studio. Но, оба раза ломался на второй вечер. Процесс лишь усложнялся с 2012 года. Бесконечные конфигурационные файлы, указать все в десяти местах. Указать кучу параметры для сборки, указать версию андроида, и.т.д., и.т.п.
Аааа, паника.
Да, наши заказчики часто запускают TFlite через Java. Но сами мы лишь завариваем модели, не лазя внутрь.
Unity
Но, году в 2018-2019 произошло первое озарение. По одной из задаче, которой я занимался, надо было запустить программу на Unity. Поставил Unity на винду. Все работает минут через 20 установки. И вдруг, вижу сверху кнопочку “запустить на Android”. Воткнул телефон, нажал, оно заработало.
Ха-ха, подумал я. Как это возможно?
При этом, я знал что под Unity есть TensorFlow. Сделать проект с нуля, с распознаванием данных с камеры на TensorFlow у меня заняло где-то полтора часа. Я был в экстазе. Но, надо понимать, что:
- Это был не TFlite – это какая-то специальная сборка под Unity
- Не было поддержки нормальной аппаратной части (GPU или NNAPI)
- Unity это все же игровая платформа. Хотите захватить картинку с камеры? Расположите её как объект в 3д пространстве:)
К сожалению, первые две проблемы делают возможным использовать Unity лишь на простые задачи. Делали.
Готовя эту заметку я нашел достаточно неплохую реализацию полноценного TFlite под Unity. Надо будет попробовать насколько это работает. Обещают что поддерживается аппаратная часть нормально. И под Android и под IOS.
Пара слов про JS
Второй способ просто использовать модели на мобильных платформах появился в 2019 году, но пользоваться им мы стали лишь в начале 2020. В своей статье я описывал плюсы и минусы такого подхода. В целом – это очень неплохой способ для большинства не нагруженных моделей.
Я смог запустить onnxjs и tfjs где-то за пару часов, написав какую-то свою простейшую программу (на базе этих примеров). Даже при учете того что никогда не писал на JS
Минус этого подхода – приложение не нативно (возможно нет доступа к всем функциям телефона, хотя тут я не специалист). Оnnxjs идет с опозданием от onnx конвертора.
Но я видел уже много замечательных проектов сделанных таким образом.
Flutter!
В какой-то момент я почитал пару статей про Flutter. И проперся. По сути он делал то же самое что Unity, но для телефонов. Простейшее приложение создается из коробки и пишется в пару строчек.
Больше всего это мне напомнило детство, когда я увидел в восьмом классе Visual Basic и понял, что не надо больше мучиться с непонятными консолями чтобы запустить свою программу. Можно нажать кнопку и сразу будет такая же форма как у взрослых дядей.
Тут почти то же самое. Все требуемые пакеты выкачиваются сами и почти мгновенно. Синтаксис чем-то похож на C#, который я когда-то неплохо знал.
TFlite доступен. Но тут важно не перепутать. Есть два tflite под flutter. Один – набор готовых сетей за рамки которого сложно выйти. Достаточно кустарно, но запускается. Зато просто написан. Если вам подойдет какая-то из сетей, то норм. Подключить новую почти не реально.
Второй – какой-то полуофициальной, где-то на официальном форуме его советуют (и Flutter и TFlite – детища гугла). Тут полноценная поддержка TFlite и любой модели. Авторы так же выложили TFLite_Helper – библиотеку для простейшего препроцессинга изображения. Это значительно ускоряет, не заставляя тратить время на что-то простое..
Что мне ужасно понравилось – весь код абсолютно читаемый (в отличие от java), очень удобный дебаг, который я сходу понимаю (в отличие от того же js), очень удобная конфигурация проектов (чем то напоминает pip автоматический или nuget).
Да, после питона много кода лишнего и некрасивого (но так как я прогал когда-то давно на Delphi/C# – как то нормально это все воспринимается).
Да, 2/3 программы будет занимать интерфейсная часть и отрисовка. Но где не так.
Я запустил пример на базе tflite_flutter, который использует какой-то мобилнет. В целом, без особых проблем подключил какой-то другой аналогичный детектор (взял что-то из списка). Специально обучать ничего не стал, скорее это был тест на поиграть и что все работает.
Итого
Как результат могу сказать:
- За последний год запускать нейронки на мобильниках стало значительно проще. Это не вызывает отвращения.
- Уже не надо быть крутым мобильным разработчиком чтобы что-то сделать
- Возможно для какого-то из следующих проектов которые я делаю ради забавы я уже буду рассматривать мобильную платформу
Что использовать как среду для написания? Unity я не тестировал, скорее всего как-нибудь опробую. Из остальных двух – думаю что надо смотреть свои предпочтения по кодингу. Мне очевидно проще заходит flutter. Но смотря как просто и быстро многие пишут на JS – может быть это и разумнее. Плюс, он поддерживает куда больше платформ.
И, по старинке, видео: