Что я сделал?

Я создал приложение для Android, чтобы использовать ИИ для классификации автомобилей, очень похожее на приложение «хот-дог/не хот-дог, но лучше...

Зачем я это сделал?

Мне очень нравятся автомобили. Не так много, как Джереми Кларксон из Top Gear, но прилично. Я иду по улице и часто вижу машину, которую не узнаю. Это Jaguar F-type или Aston Martin Vantage? В частности, менее известные автомобили, такие как узнаваемые автомобили, такие как Fisker Karma, когда я впервые увидел, подумал, что это похоже на какой-то потрясающий футуристический спортивный автомобиль, и мне пришлось спросить моего друга, что это было позже в тот же день. Так что, как правило, мне интересны машины, и мне нравится знать, на что я смотрю, и, может быть, насколько это смехотворно недоступно, поэтому я могу плакать.

Как я его создал?

Я использовал Java для приложения и Python/Flask для сервера. Он использует API ML в облаке и запрашивается с помощью запроса POST. Приложение состоит из двух основных действий — экрана приветствия (с возможностью сделать снимок или загрузить изображение) и экрана результатов, на котором отображаются обнаружения. Сервер размещен на AWS Elastic Beanstalk, и его обслуживание стоит около 14 долларов в месяц. Сервер использует модель Torch, которая выполняет обнаружение и классификацию загруженных изображений и возвращает объект json с ограничивающей рамкой и прогнозами.

Я хочу помочь читателю лучше понять общий процесс создания приложения для Android с API ML, рассказав о своем опыте. (Я не буду вдаваться в подробности в этом посте, но могу сделать это, если этот пост получит много внимания в будущем). Этот проект можно разбить на 3 основных компонента работы:

  1. Приложение для Android — пользовательский интерфейс, графика, поток управления
  2. Машинное обучение — детектор и классификатор автомобилей, парсинг и маркировка данных
  3. API облачного сервера — метод обслуживания запросов приложений практически в любом месте.

Я использовал несколько итеративный процесс для создания приложения, но в целом он выглядел следующим образом:

  1. Концептуализация
  2. Простое приложение
  3. Получите много данных и обучите детектор
  4. Обучите модель классификатора
  5. Заставьте модель машинного обучения работать в производственном режиме
  6. Локальное размещение серверного API для модели ML
  7. Переместите API сервера на облачный хост
  8. Подключите приложение к серверу в облаке
  9. (Необязательно) Собрать данные о моделях автомобилей
  10. Улучшить интерфейс приложения
  11. Релиз в Google Play!

1.Концептуализация

Это была та часть, где я думал о том, что я хочу построить, какие потребности я буду решать. Я видел потребность в способе быстрого распознавания автомобилей на вашем телефоне, и я не знал слишком много существующих инструментов для этого. Тогда я решил отделить серверный API от приложения, чтобы я мог довольно легко вносить изменения в одно, не меняя другое.

2. Простое приложение (Android, Java)

Раньше я не занимался дизайном приложений для Android, поэтому сначала создал пару обучающих приложений для начинающих из сообщений в блогах или GitHub. Учебники, в которых демонстрировалось использование модели машинного обучения или использование функций камеры, оказались здесь полезными для изучения основ. Обладая этими знаниями, я создал небольшое приложение с двумя действиями (два экрана) — экраном приветствия для загрузки изображения и экраном результатов обнаружения. На данный момент я вставил некоторые результаты-заполнители, потому что я еще не создал API.

3. Получите много данных и обучите детектор (Python)

Эта часть заняла немного времени, но здесь мне нужно было сделать две вещи. Я знал, что мне нужно большое количество изображений для обучения классификатора изображений. Детектору автомобилей также необходимо знать, ГДЕ находится автомобиль на изображении для обучения. Поэтому я разбил сбор данных на два этапа:

а) Собрал изображения Flikr с поиском по ключевым словам, таким как Ford Mustang 2018 или Honda Civic, и использовал поисковый запрос в качестве метки классификации для извлеченного результата. Я использовал это скрапинг-репозиторий пользователя Github Ultralytics. Я собрал около 1000 автомобилей для каждого из моего рукописного списка из 353 наиболее распространенных классов автомобилей (на основе популярных моделей AutoTrader). Всего около 350 000 изображений. Я также изменил размер изображений, прежде чем помещать их на свой жесткий диск, чтобы избежать слишком быстрого заполнения моего жесткого диска.

б) Использовал инструмент маркировки ограничивающей рамки, чтобы вручную пометить около 2000 ограничивающих рамок в очищенных изображениях. Обучил детектор YOLOv3 и запустил обученный детектор на моих полных 350000 изображений и взял верхнюю ограничивающую рамку, найденную на каждом изображении (чтобы удалить возможные неправильные метки в случаях, когда есть несколько автомобилей, и только один из них является целевым классом) .

Этот процесс дал мне около 300 000 обрезанных и помеченных (марка и модель автомобиля) изображений автомобилей, И обученный детектор YOLOv3, который я мог использовать позже.

4. Обучение модели классификатора (Python, Torch)

Используя 300 000 обрезанных изображений, я смог обучить модель классификатора на этих изображениях с 353 классами. Дизайн модели был основан на этом репо с некоторыми изменениями.

Одна проблема заключается в том, что я много читал изображения с жесткого диска и тренировался в течение нескольких дней. Мой жесткий диск вышел из строя через несколько дней после этого обучения, и я подумал, что все на нем пропало. К счастью, мне удалось передать свой жесткий диск профессионалу, восстановить разработку приложения и данные и ничего не потерять. Однако я призываю к осторожности при обучении на жестком диске с большими наборами данных. Подумайте о том, чтобы сначала создать резервную копию своих данных, и, если это возможно, если набор данных достаточно мал, загрузите свои данные в ОЗУ и обучите их таким образом. Конечно, с массивными наборами данных это часто невозможно. Просто предупреждение.

5. Заставьте модель машинного обучения работать в производственном режиме (Python, Torch))

Чтобы модель работала в продакшене, я использовал факельную трассировку детектора автомобилей и классификатора (по сути, это сохраняет прямой проход модели). Конвейер представляет собой что-то вроде получения изображения, изменения размера изображения, отправки его через детектор YOLO, классификации любых обнаруженных ограничивающих рамок и вывода этих ограничивающих рамок с предсказаниями класса.

6. Локальное размещение серверного API для модели машинного обучения (Python, Flask, Torch)

Чтобы локально разместить серверный API, я настроил относительно простое приложение Python Flask с одним методом POST, который использует модель ML в рабочем режиме из шага 5 (см. выше) и возвращает объект json. Затем я написал простую клиентскую программу, которая запрашивает локальный сервер. Обе эти программы работали на одном компьютере. Затем я протестировал этот API из своего приложения для Android, оба работали локально. Некоторое время я не получал никакого ответа от сервера на приложение, и после нескольких дней отладки понял, что мне нужно включить cleartextTrafficPermitted=”true”, что как-то связано с разрешением API-интерфейсов протокола с более низким уровнем безопасности, я думаю . Но это сработало, и этого было достаточно для начинающего приложения. Пожалуйста, напишите в комментариях, если вы считаете, что мой подход был неправильной идеей!

7. Переместите API сервера на облачный хост (AWS, Python, Flask)

Эта часть была относительно сложной и требовала некоторого размышления. Существует МНОЖЕСТВО вариантов размещения облачных API — Google Cloud, AWS, Azure, PythonAnywhere и т. д. и т. д. Сначала я попробовал PythonAnywhere из-за относительно простого пользовательского интерфейса, но оказалось, что у него есть препятствие при использовании Torch. Мне удалось установить torch в моем облачном экземпляре, но возникла ошибка обработки тензора torch, которую я не смог устранить и не выдал сообщения об ошибке.

Поэтому после этого сбоя и недели или около того потерянного времени я перешел на AWS Elastic Beanstalk, инстанс с автоматическим масштабированием, идеально подходящий для веб-серверов и API. Я не эксперт в этом, но, кажется, это работает для меня. Я последовал их руководству и загрузил исходный пакет. Сначала это не работало, и было трудно устранять неполадки, но я зарегистрировался в их бизнес-аккаунте службы поддержки и получил несколько полезных отзывов (после чего я снова понизил рейтинг, чтобы сэкономить деньги). Некоторые ключевые проблемы для меня заключались в том, что у меня была лишняя папка в иерархии моего исходного пакета, поэтому он не мог найти нужный файл application.py в корневой папке пакета. Если бы я порекомендовал кому-то, кто начинает работу с Elastic Beanstalk, я бы посоветовал начать с его примера приложения Flask и строить на его основе, чтобы в случае сбоя вашего кода вы лучше понимали, что вызвало изменение.

В любом случае, в конце концов я разобрался со всеми перегибами на сервере, разместил его и проверил консоль AWS, чтобы не увидеть ошибок.

8. Подключите приложение к серверу в облаке (Android, Java)

Эта часть была относительно простой. Здесь вам просто нужно заменить URL-адрес и порт локального сервера API в приложении Android на URL-адрес облачного сервера. Если вы не получили ответ, проверьте журналы вашего сервера и посмотрите, нет ли ошибок. Кроме того (очевидно, но неважно), запустите свое приложение в режиме отладки и убедитесь, что вы получаете ненулевой ответ сервера. Еще один метод устранения неполадок, с которого стоит начать, — отправить серверу только ответ 200 или простой предварительно сгенерированный результат обнаружения, для работы которого не требуются модели машинного обучения.

9. (Необязательно) Собрать данные о моделях автомобилей (Python, Selenium)

Я хотел включить некоторую дополнительную информацию и идентификацию автомобилей, таких как цена и мощность, поэтому я использовал скрипт Selenium для автоматического поиска в Google терминов об автомобилях с добавленным словом цена или лошадиная сила. Затем я взял результат Google и поместил его в dataframe/csv. Все, что было не так легко собрать, я вручную гуглил и вводил сам (около 30% данных было нелегко собрать). Это — хороший учебник для тех, кто начинает работать с Selenium и Google.

10. Обновить пользовательский интерфейс приложения (Android, Java)

Это самое интересное! Здесь я добавил некоторые фоновые визуальные эффекты в свое приложение, изменил кнопки вокруг (сделал их больше и больше разнесены на основе предварительных отзывов пользователей) и добавил красную рамку вокруг обнаружения ограничивающей рамки для автомобиля, чтобы показать, какой автомобиль идентифицируется . Используя Google Ad Mob, я добавил межстраничное объявление прямо перед результатами обнаружения автомобиля, чтобы получить эти сладкие 25 центов дохода от рекламы (в основном просто из любопытства, как это работает). Если вам интересно узнать об этих объявлениях, по ним есть множество руководств. Просто не забудьте использовать тестовые объявления во время разработки, чтобы избежать закрытия вашей учетной записи разработчика (они пытаются помешать людям играть в систему и нажимать на свои собственные объявления).

Краткая заметка о рекламе — реклама раздражает — согласен. Разработчики часто добавляют их, чтобы получить немного денег от своего приложения и не взимать плату за приложение. У меня были противоречивые мысли о том, стоит ли включать рекламу, но в конце концов я решил пойти на это. Я читал некоторые отчеты о том, что межстраничные объявления приносят больше дохода, чем баннеры, и, по моему скромному мнению, межстраничные объявления при правильном размещении менее навязчивы, чем баннеры и другие типы рекламы. Если вы не согласны, дайте мне знать ваши мысли в разделе комментариев!

11. Релиз в Google Play!

Наконец-то мы закончили? Правильно??? Неправильный! Чтобы выпустить приложение, необходимо выполнить несколько основных шагов. Вам нужно создать и подтвердить учетную запись разработчика, зарегистрировать приложение в консоли Google, создать Политику конфиденциальности (я полагаю, что моя требовала этого, потому что она позволяла пользователю загружать изображения, моя была в основном скопирована и вставлена ​​​​из образца, который я найти в Интернете и добавить на сайт Google), настроить учетную запись Google Ad Mobs и платежную информацию, загрузить подписанный пакет приложений Android (учебники можно найти в Интернете) и подождать около 5 рабочих дней, пока ваше приложение будет одобрено Google Play. Магазин. Помимо Google Play Store, существуют и другие торговые площадки для Android, вы даже можете разместить свой собственный веб-сайт для распространения APK/AAB, хотя это может быть больше работы. Google Play иногда может отказывать приложениям в доступе в свой магазин по разным причинам, например, из-за предполагаемого отсутствия безопасности и конфиденциальности. Мое приложение очистилось, поэтому я вздохнул с облегчением.

Кто-то также может захотеть выполнить поэтапное развертывание своего приложения. Вы можете сделать это в Google Play — в разделе «Внутреннее тестирование» вы можете добавить небольшой набор внутренних тестировщиков. Никто, кроме этих людей, не сможет найти ваше приложение в Play Store. Это хороший способ бета-тестирования вашего приложения и устранения недостатков с небольшой базой пользователей.

Сводка

Я создал свое первое приложение для Android, использующее ML API в облаке! Этот проект научил меня многому об API, процессе машинного обучения, доставил массу удовольствия и много работы. Если вам нравится идея сделать это, я рекомендую начать с малого и повторять. Не стесняйтесь комментировать или обращаться ко мне за руководством или идеями сотрудничества.