Привет, Хабражители. Сегодняшний пост будет о том, как не затеряться в дебрях многообразия вариантов использования TensorFlow для машинного обучения и достигнуть своей цели. Статья рассчитана на то, что читатель знает основы принципов работы машинного обучения, но пока еще не пробовал это делать своими руками. В итоге мы получим работающее демо на Андроиде, которое кое-что распознает с довольно высокой точностью. Но обо всем по порядку.   Посмотрев последние материалы — было решено заюзать Tensorflow, который сейчас набирает высокие обороты, да и статей на английском и русском становится вроде бы достаточно, чтобы не закопаться в этом всём и суметь разобраться что к чему.  Потратив недели две, изучая статьи и многочисленные экзамплы на оф. сайте, я поняла, что ничего не поняла. СЛИШКОМ много информации и вариантов того, как можно использовать Tensorflow. Голова уже пухла от того, как много они предлагают разных решений и что с ними делать, применительно к моей задаче.   Тогда я решила попробовать все, начиная от самых простых и практически готовых вариантов (в которых от меня требовалось прописать зависимость в gradle и добавить пару строчек кода) до более сложных (в которых пришлось бы самим создавать и обучать модели графов и научиться использовать их в мобильном приложении).  В конце концов пришлось юзать сложный вариант, о котором будет подробнее чуть ниже. А пока я составила для вас список вариантов попроще, которые не менее эффективные, просто каждый подходит для своей цели.   Самое простое в использовании решение — парой строчкой кода вы сможете воспользоваться:  Немного сложнее с помощью данного решения можно также использовать свою собственную TensorFlow Lite model, но конвертация в данный формат вызвала сложности, поэтому данный пункт не был испробован. Как пишут создатели этого детища — можно решить большУю часть задач, с использованием данных разработок. Но если это не относится к вашей задачи — Вам придется использовать кастомные модели.  Очень удобное средство создания и тренировки своих кастомных моделей с помощью изображений.
Из Плюсов — есть бесплатная версия, которая позволяет держать один проект.
Из Минусов — бесплатная версия ограничивает количество "входящих" изображений в 3000 шт. Чтобы попробовать и сделать средненькую по точности сеть — вполне хватит. Для более точных задач — нужно больше.
Все, что требуется от пользователя — добавить изображения с пометкой (например — image1 — это "racoon", image2 — "sun"), обучить и заэкспортить граф для дальнейшего использования.  Заботливый Microsoft даже предлагает свой семпл, с помощью которого можно опробовать свой полученный граф.
Для тех, кто уже "в теме" — граф генерируется уже в состоянии Frozen, т.е. с ним дополнительно делать\конвертировать ничего не надо.
Это решение хорошо в случае, когда у вас большая выборка и (внимание) МНОГО разных классов при обучении. Т.к. в противном случае будет много ложных определений на практике. Например, вы обучили на енотиков и солнышках, а если на входе будет человек — то он может с равной вероятность быть определенным такой системой как то, или другое. Хотя по факту — НИ то, НИ другое.   Когда нужно самим более тонко настроить модель для распознавания изображения — в дело приходят более сложные манипуляции со входной выборкой изображений.
Например, мы не хотим иметь ограничений по объему входной выборки (как в пред. пункте), или хотим более точно обучить модель, сами настроив количество epoch и других параметров обучения.
В данном подходе есть несколько примеров от Tensorflow, которые описывают порядок действий и конечный результат.
Вот несколько таких примеров: В нем приводится пример того, как создать классификатор видов цветов на основе открытой базы изображений ImageNet — подготовить изображения, а затем обучить модель. Также немного упоминается то, как можно работать с довольно интересным тулом — TensorBoard. Из его самых простых функций — он наглядно демонстрирует структуру вашей готовой модели, а также процесс обучения по многим параметрам.  Кодлаб Tensorflow for Poets 2 — продолжение работы с классификатором цветов. Показывает как при наличии файлов графа и его меток (которые были получены в предыдущем кодлабе) можно запустить приложение на андроид. Один из пунктов кодлаба — конвертация из "обычного" формата графа ".pb" в формат Tensorflow lite (который предусматривает проведение неких оптимизаций файла для уменьшения итогового размера файла графа, ибо мобильные устройства к этому требовательны).  Распознавание рукописных символов MNIST.
 В репе размещена исходная модель (которая уже подготовлена под данную задачу), инструкции по тому, как ее тренировать, сконвертировать, и как в конце запустить проект под Андроид, чтобы проверить как это все работает На основе данных примеров можно разобраться с тем, как устроена работа с кастомными моделями в Tensorflow и попробовать либо сделать свою, либо взять одну из уже пред-обученных моделей, которые собирают на гитхабе:
Модели от Tensorflow Кстати говоря о "пред-обученных" моделях. Интересные нюансы при использовании таковых: Однако все предыдущие пункты не давали нужного результата. С самого начала было трудно понять, что же нужно делать и с помощью какого подхода. Потом была найдена классная статья по Object Detection API, в которой рассказывается как можно на одном изображении найти несколько категорий, а также несколько экземпляров одной категории. В процессе работы по этому сэмплу оказались более удобными исходные статьи и видео уроки по распознаванию кастомных объектов (ссылки будут в конце). Но работа так и не смогла бы быть завершенной без статьи о распознавании Пикачу — потому что там был указан очень важный нюанс, который почему-то не в одном гайде или примере нигде не упоминается. А без него вся проделанная работа была бы впустую. Итак, теперь наконец о том, что же все-таки пришлось сделать и что получилось на выходе.  Вот тут как раз возник самый большой затык во всей работе, как ни странно — ну не хотели сэмплы Tensorflow никак работать. Все падало. Только могучий Пикачу со своей статьей сумел помочь привести все в работу.
В файлt labels.txt обязательно первой строчкой должна быть надпись "???", т.к. по умолчанию в Object Detection API номера id объектов начинаются не с 0 как обычно, а с 1. В связи с тем, что нулевой класс является зарезервированным — и нужно указывать волшебные вопросики. Т.е. ваш файл с метками будет примерно таким: А дальше — запускаем сэмпл и видим распознавание объектов и уровень confidience, с которым оно было получено.     Таким образом, в итоге получилось простое приложение, которое при наведении камеры распознает границы штампа на документе и указывает их вместе с точностью распознавания.
А если исключить то время, что было затрачено на поиски нужного подхода и попыток его запустить — то в целом работа получилась довольна быстрая и на самом деле не сложная. Просто надо знать нюансы, прежде чем приступать к работе.  Уже в качестве дополнительной секции (тут можно уже закрывать статью, если Вы устали от информации), хотелось бы написать пару лайфхаков, которые помогали в работе со всем этим. довольно часто скрипты tensorflow не работали потому, что они запускались не из тех директорий. Причем на разных ПК было по-разному: кому-то требовалось для работы запускаться из директории "tensroflowmodels/models/research", а кому-то — на уровень глубже — из "tensroflowmodels/models/research/object-detection" помните о том, что для каждого открытого терминала нужно заново выполнять экспорт пути с помощью команды  если вы используете не свой граф и хотите узнать информацию о нем (например "input_node_name", который требуется в дальнейшем при работе), выполните из корневой папки две команды:  где "/ваш локальный путь/frozen_inference_graph.pb" — это путь к графу, о котором вы хотите узнать информацию Для просмотра информации о графе можно воспользоваться Tensorboard где нужно указать путь к графу (model_dir) и путь к файлам, которые были получены в процессе обучения (log_dir). Потом просто открыть localhost в бразуере и смотреть то, что вас интересует. И самая последняя часть — по работе с python скриптами в инструкции по Object Detection API — для Вас подготовлена маленькая шпаргалка ниже с командами и подсказками. Экспорт из labelimg в csv (из object_detection директории) Далее все этапы, которые перечислены ниже, надо выполнять из одной и той же папки Tensorflow ("tensroflowmodels/models/research/object-detection" или на уровень выше — в зависимости от того, как у вас пойдет дело) — т.е все изображения входной выборки, TFRecords и прочие файлы до начала работ нужно скопировать внутрь этой директории. Экспорт из csv в tfrecord *Не забывайте менять в самом файле (generate_tfrecord.py) строчки ‘train’ и ‘test’ в путях, а также
название распознаваемых классов в функции class_text_to_int (которые должны быть продублированы в pbtxt файле, который вы создадите перед обучением графа). Обучение ** Перед обучением не забудьте проверить файл "training/object-detection.pbtxt" — там должны быть указаны все распознаваемые классы и файл "training/ssd_mobilenet_v1_coco.config" — там нужно поменять параметр «num_classes» на число ваших классов. Экспорт модели в pb  Спасибо за проявленный интерес к данной теме! Ссылки  Android Developer