Написав нейронную, сеть которая делает какую-то очередную красивую штуку, разработчик задумывается как превратить её в удобный инструмент и впоследствии коммерциализировать. Для того чтобы сеть, созданная чтобы упростить жизнь домохозяйкам, была востребована, её нужно упаковать в удобное и простое в использовании пользовательское приложение. Иначе, домохозяйки при виде командной строки и чёрного экрана терминала упадут в обморок. Для коммерциализации приложения и этого мало: требуется создание каналов коммуникаций (сайт, страницы в соц. сетях), площадок для обсуждений (форумы, группы в соц. сетях), позитивного имиджа (статьи на тематических ресурсах, доклады).
В этой статье рассмотрим, как упаковать нейронную сеть для приложения под Android. Проделав этот пусть хочется поделиться знанием мест, где лежит множество подводных камней. Надеюсь, этот материал сэкономит время тому, кто будет заниматься этой же самой задачей.
В качестве пререквезита для дальнейшего использования материала предположим, что у вас уже есть сеть на Keras и мобильное приложение для Android. На Хабре есть прекрасные статьи, как их писать:
Упаковать весь пройденный путь в одну статью не получится: это несколько месяцев разработки. Поэтому, это будет цикл из нескольких статей. В этой статье я приведу обзор возможностей для архитектур интеграции Android-приложения и нейронной сети, опишу их сильные и слабые стороны. В следующих статьях я подробно разберу варианты архитектур, приведу код для вызова нейронной сети для получения прогноза.
В проекте, который мне посчастливилось реализовать, я использовал Android Studio и Java, а также сеть на keras и python. Для того чтобы осуществить грамотно экспорт сети пришлось глубоко окунуться в tensorflow. В этой статье я также буду основываться на этих технологиях.
Помимо Android приложения, построение пользовательского уровня для нейронной сети возможно следующими способами:
Возможные архитектуры для Android приложения с нейронной сетью
Возможности интеграции Android приложения и нейронной сети по истине велики. Ниже приведена диаграмма, на которой приведены известные автору способы интеграции нейронной сети в приложение.
Как видим, есть два основных пути интеграции:
У каждого способа есть свои сильные и слабые стороны, а также серьёзные ограничения.
при выборе технологии, необходимо прежде всего учитывать её ограничения
Если ограничения не учитывать, может оказаться что работа была проделана зря. Выбрав дешёвый путь, можно упереться в не расширяемое ограничение, получив перспективу всё переделывать.
Желание сэкономить на серверах, например, может привести к итоговому удорожанию за счёт стоимости рабочего времени разработки и позднему выходу на рынок. Например, в моём случае, пока я исследовал как интегрировать сеть внутрь приложения без сервера из экономии (проект то некоммерческий!), вышла сеть iCassava.
Не то чтобы эта сеть была конкурентом, скорее даже наоборот — она разогреет рынок, но, всё же, пальма первенства утеряна. В индустрии ИИ развитие происходит крайне быстро, пока вы всего неделю ковыряетесь с какой-то строчкой кода, кто-то уже может занять ваше место на рынке.
Сильными и очень привлекательными сторонами при размещении сети внутри приложения являются:
Ограничением же для размещения сети внутри приложения является память. При чём как оперативная память целевого устройства, так и размер приложения.
внедрение в приложение 1-й сети получающее на вход изображение 100*100, приложение падало по причине нехватки ОЗУ.
Не то чтобы оно постоянно падало, но, если на телефоне запущены соц. сети, браузер, е-мейл клиент и т.д. что встречается крайне часто, приложение могло упасть совершенно непредсказуемо. При том сама сеть могла работать, но сделать новую фотку уже не получается.
Польстившись на бесплатность вычислений, внедрив в приложение все 3-х сети с хорошим входным вектором, объём дистрибутива достиг 1гб. Для мобильного устройства это недопустимо.
Это даже будет работать, но пользователь качнёт его случайно по платному каналу и напишет отзыв в отзовик поставив 2 балла из 5, после чего других пользователей у вас не будет.
В случае проекта, на борту приложения осталась всё же сеть первичной классификации, получающая на вход изображение 48*48 пикселей. Она работала мгновенно, бесплатно, занимает 10 мб. Но она почти не на что не способна.
К сожалению, экспорт модели в С++ не был мной достаточно изучен в связи с тем что эта возможность требует слишком много времени на её разработку. В теории, всё должно быть очень хорошо: в С++ вы можете управлять памятью как вам угодно и т.д. Но по времени разработки это ад. Для реализации моего проекта у меня просто не было столько времени, и так подобный проект вышел у другой организации раньше, чем у меня, а если я буду несколько недель разбираться с С++, писать эффективное управление памятью, а потом как интегрировать код С++ в Java, я точно опоздаю в рынок.
Самой главной сильной стороной расположения сети на сервере является преодоление ограничения, связанного с памятью и размерами приложения клиентской части. Сейчас для серьёзно сети альтернативы просто нет. Может быть, для десктопного решения и можно сеть внедрять внутрь, но для мобильного решения внутрь можно внедрять только слабосильную сетку.
Недостатками серверного решения являются:
К сожалению, как описано выше, альтернатив, в большинстве случаев, нет: если сеть умещается в память, то размещайте её в памяти. Если же нет, то иное невозможно.
Для серверов и облачных решений есть несколько технологий размещения нейросети: вы можете арендовать сервер или воспользоваться каким-то встроенным сервисом выполнения сетей.
Преимущества и недостатки решений можно перечислить и суммировать быстро по шкале Автономность * Стоимость. Чем выше автономность, тем выше стоимость решения в особенности стоимость администрирования решения. Размещая сеть на сервисе выполнения сети вы делаете это почти мгновенно: нажимаете мышью кнопку «загрузить» и сеть уже там. Но вы зависите от поставщика.
Самое популярное на сегодняшний день решение. Сочетает в себе относительную простоту настройки, лёгкость деплоймента. Если есть деньги (это не ваш диплом), то в целом не дорого. Docker можно разместить в облаке или купить целый VDS, поставить на нём всё самому.
Преимуществом решения является наивысшая стабильность, зрелость технологии, переносимость на другие решения. Недостатком является то, что, когда ваша сеть простаивает, она всё равно потребляет память и процессорную мощность, вы за это платите облаку. Вместо того чтобы жить на 256мб, сети нужны гигабайты. Ну и вы это всё хозяйство поддерживаете.
Изучая Docker задаёшься вопросом: когда же сделают полноценный способ выполнения сетей, чтобы не надо было знакомиться с непонятно чем. Автор статьи избалован фирмой Microsoft, я привык что у программы есть какие-то окошки где вы можете задать основные параметры. Классно, если у вас есть лишняя неделя разбираться с особенностями командной строки, или вы вообще специализируетесь на одной технологии и готовы спать с докером ночью. Если же вам приходится сегодня работать с Аэрокосмическими технологиями, потом с Oracle, иногда с Drupal, заняться стратегическим маркетингом и фандрайзингом, вы ищете более лёгкой жизни.
Не знаю, как это работает на Google AI Platform, но там есть кнопка «Загрузить сеть», нажав на которую и выбрав файл, вы получаете полнофункциональное решение. Вам не надо ставить Docker, платить за VDS, оно как-то там само исполняется и, сдаётся мне, гораздо эффективнее использует память для системы в целом: система вряд ли держит отдельную виртуальную машину для каждой сети, выделяет ЦП только когда надо.
Технология пока не зрелая. Она официально почти что “beta” или только вышла из “beta”. Редко но бывают глюки неясного свойства. Особенно проблематичны задержки после длительного неиспользования: видимо сеть как-то кэшируется и если она ушла из кеша то вернуть её туда занимает несколько минут.
Google ограничивает размер модели 250 МБ. В целом, если их попросить, они могут расширить этот лимит. Но по умолчанию это ограничение есть. Для меня это стало проблемой: моя сеть занимала ровно 253 мб. Пришлось подсократить кол-во нейронов в dence слое, как раз.
В моём решение был создан промежуточный уровень на Google cloud functions (аналог flask), которые принимали REST вызовы. Однако это совершенно не оптимально:
То, что описано выше, мне предстоит реализовать в недалёком будущем.
На диаграмме выше осталась нераскрытой возможность использования Flask и поднятия сети прямо в нём. На flask обычно пишутся прокси к Tf Serving, но, имея полноценный питон, можно загрузить keras модель прямо в нём. Для промышленного использования, такой вариант самый прожорливый и медленный. Вы же не знаете заранее сколько у вас будет пользователей?
До появления Google Ai Platform, где загрузка модели делается щелчком мыши, это был хороший способ для быстрого создания рабочего прототипа. Если вы хотите демонстрировать приложение на лэптопе, это почти идеально: быстро, вы всё контролируете.
Это далеко не все возможности как можно развернуть нейросеть в продакшене для Android приложения. Не рассмотрена возможность создания нейросети на Java с выносом Java кода на сервер. Индустрия быстро развивается, новые способы появляются постоянно.
В этой статье рассмотрим, как упаковать нейронную сеть для приложения под Android. Проделав этот пусть хочется поделиться знанием мест, где лежит множество подводных камней. Надеюсь, этот материал сэкономит время тому, кто будет заниматься этой же самой задачей.
В качестве пререквезита для дальнейшего использования материала предположим, что у вас уже есть сеть на Keras и мобильное приложение для Android. На Хабре есть прекрасные статьи, как их писать:
- Как обойти капчу: нейросеть на Tensorflow,Keras,python v числовая зашумленная капча
- Создаём развивающее приложение при помощи Android Studio
Упаковать весь пройденный путь в одну статью не получится: это несколько месяцев разработки. Поэтому, это будет цикл из нескольких статей. В этой статье я приведу обзор возможностей для архитектур интеграции Android-приложения и нейронной сети, опишу их сильные и слабые стороны. В следующих статьях я подробно разберу варианты архитектур, приведу код для вызова нейронной сети для получения прогноза.
В проекте, который мне посчастливилось реализовать, я использовал Android Studio и Java, а также сеть на keras и python. Для того чтобы осуществить грамотно экспорт сети пришлось глубоко окунуться в tensorflow. В этой статье я также буду основываться на этих технологиях.
Помимо Android приложения, построение пользовательского уровня для нейронной сети возможно следующими способами:
- сайт на популярной CMS или движке таком как Django, Flask, ASP.
- приложение для мобильного телефона или планшета не Android, например Apple.
- десктоп приложение для Windwos или Unix
- Web сервис – только для машинного интерфейса
- приложение для средств VR и дополненной реальности – скоро это направление станет мейнстримом
- приложение для менее-распространённых платформ (например для телевизора)
- приложение для пром. использования (для станков)
Возможные архитектуры для Android приложения с нейронной сетью
Возможности интеграции Android приложения и нейронной сети по истине велики. Ниже приведена диаграмма, на которой приведены известные автору способы интеграции нейронной сети в приложение.
Как видим, есть два основных пути интеграции:
- Сеть внутри приложения
- Сеть на сервере
У каждого способа есть свои сильные и слабые стороны, а также серьёзные ограничения.
при выборе технологии, необходимо прежде всего учитывать её ограничения
Если ограничения не учитывать, может оказаться что работа была проделана зря. Выбрав дешёвый путь, можно упереться в не расширяемое ограничение, получив перспективу всё переделывать.
Желание сэкономить на серверах, например, может привести к итоговому удорожанию за счёт стоимости рабочего времени разработки и позднему выходу на рынок. Например, в моём случае, пока я исследовал как интегрировать сеть внутрь приложения без сервера из экономии (проект то некоммерческий!), вышла сеть iCassava.
Не то чтобы эта сеть была конкурентом, скорее даже наоборот — она разогреет рынок, но, всё же, пальма первенства утеряна. В индустрии ИИ развитие происходит крайне быстро, пока вы всего неделю ковыряетесь с какой-то строчкой кода, кто-то уже может занять ваше место на рынке.
Размещение сети внутри приложения
Сильными и очень привлекательными сторонами при размещении сети внутри приложения являются:
- бесплатность – не надо платить за облако, администрировать и т.д.
- скорость отклика (нет запроса по сети)
- возможность работать там, где сети нет
Ограничением же для размещения сети внутри приложения является память. При чём как оперативная память целевого устройства, так и размер приложения.
внедрение в приложение 1-й сети получающее на вход изображение 100*100, приложение падало по причине нехватки ОЗУ.
Не то чтобы оно постоянно падало, но, если на телефоне запущены соц. сети, браузер, е-мейл клиент и т.д. что встречается крайне часто, приложение могло упасть совершенно непредсказуемо. При том сама сеть могла работать, но сделать новую фотку уже не получается.
Польстившись на бесплатность вычислений, внедрив в приложение все 3-х сети с хорошим входным вектором, объём дистрибутива достиг 1гб. Для мобильного устройства это недопустимо.
Это даже будет работать, но пользователь качнёт его случайно по платному каналу и напишет отзыв в отзовик поставив 2 балла из 5, после чего других пользователей у вас не будет.
В случае проекта, на борту приложения осталась всё же сеть первичной классификации, получающая на вход изображение 48*48 пикселей. Она работала мгновенно, бесплатно, занимает 10 мб. Но она почти не на что не способна.
К сожалению, экспорт модели в С++ не был мной достаточно изучен в связи с тем что эта возможность требует слишком много времени на её разработку. В теории, всё должно быть очень хорошо: в С++ вы можете управлять памятью как вам угодно и т.д. Но по времени разработки это ад. Для реализации моего проекта у меня просто не было столько времени, и так подобный проект вышел у другой организации раньше, чем у меня, а если я буду несколько недель разбираться с С++, писать эффективное управление памятью, а потом как интегрировать код С++ в Java, я точно опоздаю в рынок.
Размещение сети на серверах и/или в облаках
Самой главной сильной стороной расположения сети на сервере является преодоление ограничения, связанного с памятью и размерами приложения клиентской части. Сейчас для серьёзно сети альтернативы просто нет. Может быть, для десктопного решения и можно сеть внедрять внутрь, но для мобильного решения внутрь можно внедрять только слабосильную сетку.
Недостатками серверного решения являются:
- доступ по сети: пока 5G не внедрено повсеместно, могут быть задержки.
- есть много мест, где сети нет вообще. И это не только там, куда вы ходите в тур. поход. Ещё на этапе заброски, например, в сторону Эльбруса, выехав из Краснодара, вы столкнётесь с проблемой, что сеть там в целом есть, но скачать нельзя ничего.
- сервер платный. Для корп. сектора — это не деньги. Однако, если вы студент и пишите диплом, а на ваш диплом могут зайти миллионы, вы задумаетесь.
К сожалению, как описано выше, альтернатив, в большинстве случаев, нет: если сеть умещается в память, то размещайте её в памяти. Если же нет, то иное невозможно.
Для серверов и облачных решений есть несколько технологий размещения нейросети: вы можете арендовать сервер или воспользоваться каким-то встроенным сервисом выполнения сетей.
Преимущества и недостатки решений можно перечислить и суммировать быстро по шкале Автономность * Стоимость. Чем выше автономность, тем выше стоимость решения в особенности стоимость администрирования решения. Размещая сеть на сервисе выполнения сети вы делаете это почти мгновенно: нажимаете мышью кнопку «загрузить» и сеть уже там. Но вы зависите от поставщика.
Архитектура на основе Docker
Самое популярное на сегодняшний день решение. Сочетает в себе относительную простоту настройки, лёгкость деплоймента. Если есть деньги (это не ваш диплом), то в целом не дорого. Docker можно разместить в облаке или купить целый VDS, поставить на нём всё самому.
Преимуществом решения является наивысшая стабильность, зрелость технологии, переносимость на другие решения. Недостатком является то, что, когда ваша сеть простаивает, она всё равно потребляет память и процессорную мощность, вы за это платите облаку. Вместо того чтобы жить на 256мб, сети нужны гигабайты. Ну и вы это всё хозяйство поддерживаете.
Изучая Docker задаёшься вопросом: когда же сделают полноценный способ выполнения сетей, чтобы не надо было знакомиться с непонятно чем. Автор статьи избалован фирмой Microsoft, я привык что у программы есть какие-то окошки где вы можете задать основные параметры. Классно, если у вас есть лишняя неделя разбираться с особенностями командной строки, или вы вообще специализируетесь на одной технологии и готовы спать с докером ночью. Если же вам приходится сегодня работать с Аэрокосмическими технологиями, потом с Oracle, иногда с Drupal, заняться стратегическим маркетингом и фандрайзингом, вы ищете более лёгкой жизни.
Архитектура на основе Google AI Platform
Не знаю, как это работает на Google AI Platform, но там есть кнопка «Загрузить сеть», нажав на которую и выбрав файл, вы получаете полнофункциональное решение. Вам не надо ставить Docker, платить за VDS, оно как-то там само исполняется и, сдаётся мне, гораздо эффективнее использует память для системы в целом: система вряд ли держит отдельную виртуальную машину для каждой сети, выделяет ЦП только когда надо.
Технология пока не зрелая. Она официально почти что “beta” или только вышла из “beta”. Редко но бывают глюки неясного свойства. Особенно проблематичны задержки после длительного неиспользования: видимо сеть как-то кэшируется и если она ушла из кеша то вернуть её туда занимает несколько минут.
Google ограничивает размер модели 250 МБ. В целом, если их попросить, они могут расширить этот лимит. Но по умолчанию это ограничение есть. Для меня это стало проблемой: моя сеть занимала ровно 253 мб. Пришлось подсократить кол-во нейронов в dence слое, как раз.
В моём решение был создан промежуточный уровень на Google cloud functions (аналог flask), которые принимали REST вызовы. Однако это совершенно не оптимально:
- tensorflow позволяет указывать внутри модели обслуживающую функцию. Более детально можно разобраться изучив детали класса tf.estimator.
- GRPC вызовы эффективнее вызовов REST по объёму передаваемых данных.
То, что описано выше, мне предстоит реализовать в недалёком будущем.
Архитектура на основе Flask
На диаграмме выше осталась нераскрытой возможность использования Flask и поднятия сети прямо в нём. На flask обычно пишутся прокси к Tf Serving, но, имея полноценный питон, можно загрузить keras модель прямо в нём. Для промышленного использования, такой вариант самый прожорливый и медленный. Вы же не знаете заранее сколько у вас будет пользователей?
До появления Google Ai Platform, где загрузка модели делается щелчком мыши, это был хороший способ для быстрого создания рабочего прототипа. Если вы хотите демонстрировать приложение на лэптопе, это почти идеально: быстро, вы всё контролируете.
Другие возможности
Это далеко не все возможности как можно развернуть нейросеть в продакшене для Android приложения. Не рассмотрена возможность создания нейросети на Java с выносом Java кода на сервер. Индустрия быстро развивается, новые способы появляются постоянно.
n_kapyrin
Спасибо за несколько полезных соображений и кейвордов. Надеюсь, Вы сохраните такой же краткий и технический стиль повествования, когда дойдете до деталей своего решения.