Предыстория

В конце 2017 года я начал проявлять интерес к такой области, как машинное обучение. По специальности я Android Engineer, и в этой статье я расскажу о своем опыте работы, совместно с дипломированным Data Scientist, над проектами из области МО.

Как-то раз я пытался решить проблему, связанную с классификацией изображений в одном из наших приложений. Нужно было отличить допустимые изображения от недопустимых на основе определенного набора правил. Без промедления я модифицировал данный пример из Deeplearning4J (dl4j) и попытался использовать его для решения проблемы. Результаты не оправдали моих ожиданий, но, тем не менее, я не был разочарован.

Мой способ с использованием примера из dl4j оказался неудачным из-за той точности, что я получил, и из-за окончательного размера обученной модели. Для мобильных устройств нужна модель с компактным размером файла, иначе приложение будет работать крайне медленно.

Знакомство с моим учителем

 

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

Мы начали с коротких учебных занятий. Другие члены моей команды также проявили интерес и присоединились к нашим занятиям. Наш преподаватель познакомил нас с Jupyter Notebooks и Cloud Machine Learning Engine. В скором времени мы вовсю были заняты делом, пытаясь классифицировать изображения с помощью цветочного набора данных.

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

Подготовка тренировочных данных — это не так-то просто

 

Обе задачи требовали большого количества тренировочных данных. Хорошая новость заключалась в том, что у нас было много данных. Плохая новость — данные были не отсортированы/ не аннотированы. Наконец я понял, что подразумевают эксперты в области МО, когда говорят о том, что больше всего времени уходит на подготовку тренировочных данных, а не на обучение самой модели.

Для задачи с классификацией нам нужно было разместить сотни тысяч изображений по разным классам. Это было очень долгая и утомительная работа. Спасло положение только то, что я применил свои навыки в Java Swing и создал GUI (графический интерфейс пользователя), чтобы облегчить эту нудную задачу для всех, кто вручную классифицировал изображения.

Процесс сегментации был немного сложнее или, скорее, запутаннее. Нашей команде повезло найти несколько моделей, которые уже хорошо разбирались в сегментации, но, к сожалению, их размер нам не подходил. Также мы хотели, чтобы наша модель могла работать на Android устройствах с очень низкими характеристиками. В какой-то момент у нашего data scientist возникла блестящая идея — использовать огромную модель для генерации тренировочных данных, которые в дальнейшем будут использоваться для создания нашей собственной MobileNet (прим. редакции: MobileNet — название одной из архитектур сверточной сети).

Обучение моделей

В конце концов мы перешли на AWS Deep Learning AMI. У нас уже был опыт работы с AWS, поэтому это большой плюс, что они предложили пользователям такой сервис. Наш data scientist взял на себя весь процесс по обучению модели для сегментации изображений, а я стоял рядом с ним и делал заметки 🙂

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

Я занимался обучением модели для классификации изображений. Для этого я использовал свой Macbook Pro, поскольку от меня требовалось обучить только последний слой нейронной сети, а не всю сеть полностью, как в случае с моделью для сегментации изображений.

Все готово к использованию

Обе модели оказались в нашей производственной среде после скрупулезных тестов ?. Одному из членов команды было поручено создать обертку (wrapper) библиотеки Java. Это было сделано для того, чтобы можно было избежать всей сложности, связанной с заполнением модели изображениями и извлечением значимых результатов из тензора вероятностей (tensor of probabilities). Тензор вероятностей — это массив, содержащий результат прогноза, сделанного моделью на одном изображении. Я также принял небольшое участие в этом процессе — часть кода, написанного мною ранее, отредактировали и повторно использовали.

Проблемы, проблемы повсюду

Проблемы делают нашу жизнь интереснее и ярче. Их преодоление — то единственное, что наполняет их смыслом. —Аноним

Я помню то время, когда моей самой большой проблемой была работа с трехмерными массивами. То время прошло, но я до сих пор приближаюсь к этим массивам с осторожностью. Работа над проектами по машинному обучению с нашим data scientist была тем стимулом, в котором я нуждался, чтобы продолжить свой тернистый путь в мире МО.

Моей самой большой проблемой при работе над этими проектами стала попытка создать из исходного кода Tensorflow библиотеку для Java для 32-битных систем, используя Bazel. У меня не получилось.

Я сталкивался и с другими проблемами, одна из которых была моим частым гостем: преобразование решений задач на Python в Java. Поскольку в Python встроена поддержка data science (наука о данных) задач, код в Python выглядит более строгим и лаконичным. Я, буквально, рвал на себе волосы, когда пытался преобразовать команду для Java: масштабировать двумерный массив и добавить его в качестве прозрачного слоя к изображению. Когда мы наконец справились, все были в неописуемом восторге.

Теперь модели в нашей производственной среде, в основном, работали великолепно, однако, когда они выдавали неправильный результат, этот неправильный результат был до абсурдного неправильным. Это напомнило мне цитату, на которую я наткнулся в одной статье, посвященной превращению моделей МО в реальные продукты и услуги:

…фактически, все ваши модели будут быстро ухудшаться по качеству без постоянной подачи новых данных. Данное явление носит название concept drift и оно означает, что прогнозы, предлагаемые статическими моделями машинного обучения, с течением времени становятся менее точными и менее полезными. В некоторых случаях это может произойти даже за считанные дни.— David Talby

Получается, что итоговой модели нет, так как ее постоянно придется совершенствовать. Это интересно.


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

 

Перевод статьи Ben Daniel A.I Worked With A Data Scientist As A Software Engineer. Here’s My Experience.

Предыдущая статьяИспользование вебсокетов в промис-стиле
Следующая статьяОвладей Python, создавая реальные приложения. Часть 1