Я программист между стартапами. Я провел некоторое время в Google, создавая диаграммы Google Финансов, Множественные почтовые ящики в Gmail и Пометка в Google Maps, а совсем недавно я основал торговую компанию под названием Spring.

Я строитель, и в перерывах между концертами мне нравится работать над сторонними проектами.

Несколько месяцев назад я задумал создать приложение Face Filters For Dogs для камеры. Вы направляете его на свою собаку, и она накладывает фильтры на морду.

Есть 92 миллиона фотографий с тегами #dogsofinstagram - так что он может даже найти несколько пользователей - создание вещей, которые хотят люди, является дополнительной мотивацией.

Мне нужно было

  • построить модель глубокого обучения, которая извлекает черты лица собаки
  • запустить его на iPhone поверх живого видео
  • и используйте ARKit, чтобы показывать 3D-фильтры сверху (наклейки не так круты)

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

Я надеюсь, что те, кто плохо знаком с глубоким обучением, сочтут это полезным.

Шаг 1. Глубокое обучение в основном готово, но с некоторыми особенностями.

Первый вопрос, на который мне нужно было ответить, был «возможно ли это вообще?». Можно ли решить мою проблему? С чего начать?

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

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

Разочарованный чтением сообщений в блогах, я обратился к более фундаментальным онлайн-курсам, чтобы начать с основ. Это оказалось действительно хорошим решением.

В ходе этого процесса я узнал, что:

  • Курс Coursera по сверточным нейронным сетям Эндрю Нг (третий в серии курсов по глубокому обучению) - отличное место для изучения основных концепций и инструментов глубокого обучения, применяемых к компьютерному зрению. Без него я бы ничего не смог сделать.
  • Keras - это высокоуровневый API поверх TensorFlow, и его проще всего использовать для экспериментов с моделями глубокого обучения. Сам TensorFlow слишком низок и запутан для новичка. Я уверен, что Caffe / PyTorch тоже великолепны, но Керас действительно сделал эту работу за меня.
  • Conda - отличный способ управлять средами Python во время игры. Nvidia-docker тоже хорош, но необходим только после того, как вы получите графический процессор.

Когда вы начинаете, сначала пройдите через основы. Трудно выучить базовые концепции из интернет-уроков. Обратитесь к курсу (или книге, если это больше ваш стиль) и изучите основные основные концепции. Это сделает вашу жизнь намного проще в продвижении вперед.

Шаг 2: выяснение того, как реализовать Landmark Extraction

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

Классификация объектов и Обнаружение объектов сегодня уже нет в продаже. То, что я пытаюсь сделать, - это ни то, ни другое - оказывается, в литературе используется термин обнаружение ориентиров. Мне очень помогло определение правильного термина для того, что я делал.

Теперь - новые вопросы. Какая модель подойдет? Сколько данных мне нужно? Как мне пометить данные? Как работает обучение? Что такое хороший минимально жизнеспособный рабочий процесс разработки?

Первой целью было заставить * что-нибудь * работать. Позже я смогу поработать над качеством. Иди, прежде чем бегать.

Что я узнал:

  • Создание собственного пользовательского интерфейса для маркировки данных - действительно хорошая идея. Стандартные этикетировщики для меня не работали, только для Windows или слишком много делали. Гибкость оказалась действительно полезной позже, когда мне нужно было внести изменения в маркированные данные (например, добавить новые ориентиры).
  • Скорость маркировки имеет значение. Я получил около 300 изображений в час. Это одно изображение каждые 12 секунд. На получение 8000 снимков ушло 26 часов. Каждая секунда имеет значение, если вы хотите пометить реальные объемы данных. Создание моего собственного теггера потребовало предварительных затрат, но действительно помогло снизить затраты.
  • Пометка данных вручную дает вам хорошее представление о том, что входит в модель.
  • Предварительная обработка изображений для обучения сначала казалась мелочью, но оказалась критически важной, и мне потребовалось несколько дней, чтобы понять, как это исправить. Ознакомьтесь с этим вопросом о переполнении стека - вызов preprocess_image в нужном месте показал разницу между работой и полной неработоспособностью. : facepalm:

Это ощущение тонкого черного ящика, которое работает только в том случае, если нужные детали находятся в нужных местах, было постоянным почти на каждом этапе.

Отслеживание ошибок, выявление проблем, сужение проблемы - естественные задачи в обычной разработке программного обеспечения - сегодня не так просто при разработке глубокого обучения.

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

Примерно через три недели у меня было кое-что на месте: я мог пометить данные, обучить на них модель, запустить эту модель в Jupyter Notebook на фотографии и получить реальные координаты (с сомнительным размещением :-)) в качестве вывода.

Шаг 3. Убедитесь, что модель работает на iOS

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

Модели Keras / TensorFlow изначально не работают на iOS, но у Apple есть собственная среда для работы с нейронной сетью - CoreML. Запуск .mlmodel на iOS можно выполнить с помощью учебного кода. Я был потрясен тем, насколько это было легко.

Но даже этот простой шаг перевода (с .h5 на .mlmodel) не обошелся без проблем.

Как оказалось, вся эта цепочка инструментов глубокого обучения все еще находится в разработке. Ситуация быстро меняется на земле с глубоким уклоном.

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

Моя модель работала на реальном телефоне со скоростью 19 кадров в секунду - это было удивительным достижением! Имея основы, я мог сосредоточиться на качестве.

Шаг 4. Сделайте так, чтобы модель работала хорошо

Уф, это заняло время. Как получить готовую к работе производительность модели глубокого обучения? Больше данных? Разные верхние слои? Различные функции потерь? Различные параметры активации для слоев? Устрашающе!

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

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

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

Что я узнал, пытаясь сделать это:

  • Это может показаться очевидным, но использование TensorBoard было на порядок улучшением в моих итерациях разработки.
  • Отладка данных изображения из моего DataGenerator показала мне ошибки обработки изображений, которые влияли на мою модель. Как в тот раз, когда я зеркально отражал изображение, но я не менял местами левый глаз на правый. : facepalm:
  • Общение с людьми, которые активно тренируют моделей и имеют опыт, сэкономило мне много времени. Румынская группа машинного обучения и несколько очень щедрых друзей (спасибо Cosmin Negruseri, Matt Slotkin, Qianyi Zhou и Ajay Chainani) оказались критически настроенными. Было невероятно иметь кого-нибудь, чтобы спросить, когда я застрял.

  • Как правило, делать что-либо, что не по умолчанию, было плохой идеей. Например, когда я попробовал верхние слои из этого сообщения в блоге о соревнованиях по рыболовству, в которых использовалось activation='relu' - слои оказались хорошими, но activation='relu' было плохой идеей. Или когда я попробовал свою собственную L1 loss функцию потерь, она оказалась хуже, чем более стандартная MSE loss.
  • Было необходимо написать DataGenerator - увеличение данных имеет значение.
  • Когда вы запускаете учебные пособия, обучаете или тренируете первую модель на нескольких сотнях изображений, процессор в порядке. GPU был бы отвлечением.
  • С реальным набором данных (8000 изображений) и DataGenerator (80 000 изображений) обучение на графическом процессоре становится критически важным. Даже в этом случае тренировочный пробег занимает 24 часа.
  • Графические процессоры Amazon дороги для личного развития. При 24 часах на итерацию и ~ 1 долларе в час это очень быстро складывается. Спасибо, Cosmin, за то, что позволил мне подключиться к вашему ПК по SSH и бесплатно использовать ваши графические процессоры. ;-)

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

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

Но, как и любой другой продукт, последние 20% занимают 80% времени, и я думаю, что это будет работа, которую мне придется включить в следующую версию.

Если вам немного стыдно за то, что вы отправляете, вы, вероятно, слишком долго его выкладывали, верно? Особенно актуально для сайд-проектов.

Шаг 5: создайте приложение для iOS, фильтры и свяжите все вместе

Имея в руках достаточно хорошую модель, теперь на Swift, ARKit и, как оказалось, SpriteKit для 2D-контента. iOS и ее фреймворки продолжают меня впечатлять. То, что вы можете делать в наши дни на телефоне, действительно потрясающе, если рассматривать это в перспективе.

Само приложение действительно простое - большая кнопка записи, несколько движений для переключения фильтров, кнопка общего доступа.

Большая часть работы заключалась в изучении ARKit и (к сожалению) выяснении его ограничений. Как втягивать 3D-модели, как удалять и добавлять их из сцен, освещения, анимации, геометрии.

Что я узнал в процессе:

  • ARKit хорош, пока это не так. Да, добавить 3D-контент очень просто. Да, это весело, и API отличный. И да, как только вы добавляете что-то в сцену и оставляете там - это работает.

  • ARHitTestResult обещает, что, учитывая пиксель в вашем изображении, он вернет вам его трехмерные координаты - и это работает, но действительно неточно. В 70% случаев результаты оказываются в нужном месте, а в 30% - вне пределов досягаемости. Действительно помешал моим планам прикрепить красивые фильтры к лицу. :-(
  • План резервного копирования: построение 2D-фильтров. SpriteKit, игровой движок Apple для 2D-игр, действительно прост в использовании - со встроенным физическим движком. Весело играть и учиться (хотя и поверхностно).

Технология ARKit первого поколения в сочетании с CoreML поразила меня.

В течение нескольких недель я смог запустить свою модель глубокого обучения в прямом эфире с камеры, извлечь ориентиры на лицах, показать 3D-контент с помощью ARKit, 2D-контент с помощью SceneKit, и все это с приличной точностью.

Всего два года назад для аналогичной технологии (на человеческих лицах) SnapChat пришлось купить компанию за 150 миллионов долларов. Теперь iOS бесплатно предоставляет обнаружение ориентиров по человеческому лицу, и, в отличие от моих результатов ARHitTestResult, точность на высоте. Безумно, как быстро эта технология становится товаром.

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

Общий вывод

Я чувствую, что действительно получил хорошее представление о том, что такое Deep Learning, о чем на самом деле идет речь об искусственном интеллекте, о том, где сегодня появились возможности iPhone, ARKit, SpriteKit, Swift - и это лишь некоторые из них.

Сегодня вы не можете использовать готовую модель глубокого обучения для чего-либо, что не является базовым, но это не так уж и далеко в будущем.

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

Мне не нужно было вдаваться в подробности внутреннего устройства нейронных сетей, и мне не нужно было напрямую касаться какого-либо TensorFlow.

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

Я пришел к выводу, что Apple должна работать над дополненной реальностью вне телефона. Когда они запустят свой продукт Magic-Leap-Equivalent, создание дополненной реальности для него будет невероятно простым - ARKit уже впечатляет.

После этого упражнения я стал оптимистично относиться к глубокому обучению, особенно к компьютерному зрению. Это похоже на волшебство.

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

Спасибо за чтение, надеюсь, вы нашли это полезным! И если у вас есть предложения, пожалуйста, не сомневайтесь - я бы хотел улучшить свое приложение!

Загрузите его в App Store и дайте мне знать, что вы думаете.

p.s. Огромное спасибо Cosmin Negruseri, Matt Slotkin, Qianyi Zhou и Ajay Chainani за помощь в моих усилиях и за чтение этого черновика! Огромное спасибо Энди Бонс за оригинальную идею для этого приложения!