Практические уроки по обнаружению изображений.

Недавно мой коллега (Леон Инь) и я (Иван Шер) создали классификатор изображений, который может определять, является ли изображение скоплением людей или нет. Создание классификаторов изображений становится проще благодаря последним достижениям в области программного обеспечения с открытым исходным кодом и доступу к графическим процессорам. Однако это тонкий процесс, в котором каждая деталь должна соответствовать друг другу. В этом посте мы рассмотрим некоторые уроки и стратегии, которые мы извлекли при создании классификатора изображений. Цель этого поста - помочь читателю создать свои собственные классификаторы и получить правильные детали. Многие из этих вещей многим опытным инженерам по машинному обучению покажутся базовыми, но, тем не менее, они важны.

Получение данных для вашего классификатора

Если вы хотите создать классификатор для конкретной задачи, обычно достаточно собрать несколько тысяч изображений. Мы можем обойтись без этого небольшого количества данных, настроив модели, предварительно обученные на Imagenet. Imagenet - это набор данных с более чем миллионом изображений, организованных в тысячи классов. Несколько популярных архитектур нейронных сетей, предварительно обученные на Imagenet доступны на Керасе. Чтобы собрать данные для нашего классификатора изображений, мы создали сборщик изображений, который извлекает изображения из поиска изображений Google. Ниже приведены некоторые уроки, которые мы извлекли из сбора 100К изображений и маркировки 3К.

Обязательно конвертируйте изображения в трехканальный .jpg.

Предварительно обученные нейронные сети Imagenet принимают изображения в формате .jpg с 3 входными «цветовыми каналами» (красный, зеленый и синий). Многие изображения, которые мы собрали из Интернета, были либо .png, либо нечитаемыми .jpg. Мы предположили, что все изображения .jpg в порядке, и не знали, что у png есть другое количество цветовых каналов. После прочтения и предварительной обработки наших изображений мы были готовы передать их в нейронную сеть для обучения и начали получать странные ошибки о деформированных изображениях. Мы использовали Pillow, чтобы прочитать все изображения, превратить их в 3 цветовых канала и сохранить как .jpg. Вот созданный нами метод, который делает это:

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

Собирайте метаданные как об изображениях, так и о самих изображениях.

Знайте, откуда берутся ваши данные. Точно так же, как вы должны быть осторожны с тем, что вы вкладываете в свое тело, вы должны скептически относиться к тому, что вы вкладываете в свою модель. После того, как у нас появился поток и доступность данных, мы начали воспринимать это как должное. Не поленитесь! Автоматизируйте архивирование метаданных с самого начала. Позже вы сможете проверить происхождение своего тренировочного набора. Это помогает поддерживать дискуссии о справедливости и прозрачности систем машинного обучения. Более того, когда вы работаете в исследовательском учреждении, эта информация жизненно важна для воспроизводимости.

Называйте изображения максимально автоматизированными, но будьте осторожны.

Маркировка данных может быть утомительной задачей; часть науки о данных, которую мы все хотим автоматизировать. Однако вы обнаружите, что составление всестороннего обучающего набора - самый важный шаг в конвейере машинного обучения. Не полагайтесь на ярлыки, созданные поисковыми запросами. Мы извлекли изображения из Google Images и обнаружили, что до 50% изображений при любом заданном поиске не соответствовали нашим ожиданиям. Если можете - запачкайте руки и определите четкие критерии того, что вы ищете, а затем воспользуйтесь платформой краудсорсинга. Это даст больше времени для работы над важным. Тем не менее, мы всего лишь люди и неизбежно будем неправильно маркировать изображения (мы, конечно, сделали!). Это может показаться утомительным, но просмотрите все (или большую случайную выборку) своих этикеток. Это предотвратит головную боль в дальнейшем от попыток интерпретировать странное поведение после обучения модели. Мы создали блокнот Jupyter, который помогает циклически перемещаться по изображениям и прикреплять к ним ярлыки.

Блокнот с полным изображением этикеток находится здесь, на nbviewer.

Уроки:

- Не думайте, что что-то из Интернета - это хорошо; проверьте все свои данные, прежде чем они войдут в вашу модель

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

- Некоторые точки данных (изображения) будут повреждены или не подлежат восстановлению; просто выбросьте их.

- Запишите все детали сбора данных, даже те детали, которые в данный момент кажутся несущественными (дата, время, сценарий / метод сбора).

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

Тюнинг модели в Керасе

Мы обучили нашу модель, сначала снизив бинарную кросс-энтропию примерно до 0,01. Это говорит нам о том, что имеющаяся у нас модель способна представить эти данные. Затем мы использовали методы регуляризации, такие как исключение и увеличение данных, чтобы наша модель лучше обобщалась на новые данные.

Во время тренировки придерживайтесь простых функций потерь.

Не позволяйте оптимистичным показателям омрачить ваше суждение. Иногда ваша модель может рано возвращать многообещающие метрики, такие как потери, точность и площадь под кривой приемника. Эти показатели могут ввести в заблуждение и упустить из виду ошибки в вашей модели. Мы предлагаем использовать бинарную кросс-энтропию, поскольку она измеряет достоверность прогноза модели. Большинство задач классификации возвращают значение между [0,1], где [0, 0,5] - отрицательный класс (neg), а (0,5, 1] ​​- положительный класс (pos). Точность не различает между .51 (a слабая позиция) и .99 (сильная позиция). Это несоответствие укусит вас в задницу, когда ваша модель будет проверена. Используйте двоичную кросс-энтропию в качестве функции потерь и показателя успеха.

Ничего не считайте святым: не принимайте только результаты из статьи или модельной архитектуры вашего предыдущего проекта.

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

Основываясь на литературе и онлайн-обсуждениях, мы предположили, что пакетная нормализация (батчнорм) находится между плотным слоем и функцией активации. Однако мы наткнулись на препятствие, пытаясь уменьшить потери нашей модели ниже 0,05. Независимо от того, какие гиперпараметры и регуляторы мы настраивали, мы не могли преодолеть фундаментальную проблему архитектуры, вызванную нашей реализацией плотных блоков. И только после того, как мы начали изменять архитектуру, мы нашли правильный порядок операций в нашей функции плотного блока (density_block_two).

Вот сравнение различных размещений батчнорма в обучении после 10 тренировочных раундов:

Вы заметите, что в объявлениях функций разница кажется небольшой и несущественной; диаграммы говорят нам, что использование density_block_two лучше, чем density_block_one (у density_block_none нет батчнорма). Мы могли бы сэкономить время, если бы с самого начала обладали более гибким мышлением. Исследуй вещи самостоятельно. Самостоятельно измеряйте результаты. Экспериментируйте с каждой деталью. Вы можете увидеть полную записную книжку с подробным описанием пакетных нормализационных тестов здесь.

Некоторые гиперпараметры взаимосвязаны; знай их.

Размер пакета и скорость обучения тесно связаны. Мы узнали это, экспериментируя с большими изображениями. Чтобы уместить большие изображения в память, мы уменьшили размер пакета до 2 (600 x 600) с 16 (244 x 244), не изменяя скорость обучения. Это означает, что слои нашей модели корректируют свои веса каждые 2 изображения. Такое поведение слишком нестабильно для изучения каких-либо значимых закономерностей, что приводит к стагнации нашего двоичного значения кросс-энтропии. Избегайте этой ситуации; знать отношения между вашими гиперпараметрами.

Правило обратных вызовов модели.

Они помогают автоматически сохранять лучшую модель в течение 100 тренировочных раундов. Они также могут помочь вам в таких вещах, как мониторинг вашей скорости обучения и ее изменение, когда ваши потери не улучшаются (это называется отжигом). Это поможет вам настроить модель более легким прикосновением, когда вы приблизитесь к минимальным потерям. Они также могут помочь вам использовать настраиваемые функции потерь, чтобы вы могли напрямую измерить или выполнить обратное распространение по любому критерию оценки. Мы пытались сделать все вышеперечисленное самостоятельно, и это было довольно сложно. Маленькие ошибки требуют больших затрат; вы можете сэкономить много времени, используя обратные вызовы, встроенные в Keras. Обратный звонок.

Прочтите исходный код.

Мы возились с настраиваемыми функциями предварительной обработки для ResNet50, InceptionV3 и VGG. Не делай этого! Все эти модели имеют разные входные форматы. Мы видели, как люди облажались по всему Интернету - на Kaggle, Stackoverflow и на форумах сообщества. Несмотря на отсутствие документации, функции предварительной обработки включены в класс модели всех предварительно обученных моделей Keras. Копание в исходном коде избавило бы нас от множества проблем с определением, проверкой и настройкой наших собственных функций предварительной обработки. Источник приложений Keras.

Всегда проверяйте свои прогнозы.

Проверяйте прогнозы на непротиворечивость: двукратное прогнозирование одних и тех же данных должно давать те же результаты. Если вы замечаете различия или замечаете, что одни и те же изображения каждый раз получают разные прогнозы, вам следует немедленно исследовать их. Это означает, что вы что-то напутали, случайно перемешали ярлыки во время обучения или что Keras не работает должным образом. На момент написания pred_generator иногда возвращал фанковые результаты в Keras v 2.0.5. Проверяйте качество прогнозов: распечатайте изображения и их прогнозы рядом. Он почти всегда покажет вам, в чем ваша модель хороша, а в чем нет. Мы совершили ошибку, пытаясь улучшить нашу модель, не делая этого; в этот момент вы просто пробуете случайные вещи без указания направления. Не делай это; проверьте свои прогнозы!

Уроки:

- Не думайте, что у вас уже есть подходящая архитектура. Еще раз проверьте все, измените все, поэкспериментируйте со всем на ранней стадии.

- Используйте простую функцию потерь, например двоичную перекрестную энтропию, особенно на ранних этапах обучения.

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

- Не пытайтесь самостоятельно управлять процессом обучения или сохранения модели; используйте обратные вызовы.

- Проверяйте исходный код при запуске проекта, и вы можете сэкономить несколько часов. Исходный код модели Keras.

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

Развертывание: чем меньше и проще, тем лучше

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

Лучшая модель - это самая простая модель.

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

Полный блокнот с использованием нашей модели толпы можно посмотреть здесь.

Ансамбль в производстве нереален.

Ансамбль - это метод объединения прогнозов от разных моделей для получения более точных прогнозов. Хотя это популярная тактика на Kaggle, если доступность вызывает беспокойство - это не вариант. Каждая добавляемая модель увеличивает время вывода на фиксированную величину (использование 5 моделей занимает в 5 раз больше времени, чем 1 модель). Рекомендуем избегать ансамблей и в производстве придерживаться единичных моделей.

Уроки:

- Лучше простое, не усложняйте модели. Это делает их непригодными для использования

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

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

Вывод

Мы надеемся, что эти уроки, которые мы усвоили при создании классификатора изображений, будут полезны сообществу и могут уменьшить некоторые неопределенности, связанные с этой задачей. В течение дня мы работаем в лаборатории SMaPP в Нью-Йоркском университете в качестве специалистов по анализу данных. Если вы хотите это проверить, посетите нашу страницу на github. Если вы хотите увидеть больше интересных статей о машинном обучении и науке о данных, yvan’s blog is here и leon’s site is here.

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