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

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

Давай получим данные

Первое, что нужно сделать в любой задаче машинного обучения, - это собрать данные. Нам нужны тысячи изображений с обозначенными выражениями лица. Общедоступный набор данных FER [1] - отличная отправная точка с 28 709 помеченными изображениями. Мы будем использовать подмножество их ярлыков в качестве целевых эмоций:

  • Злой
  • С отвращением
  • Счастливый
  • Грустный
  • Удивлен

Однако, поскольку разрешение этих изображений составляет всего 48 x 48, было бы неплохо также иметь набор данных с более богатыми функциями. Для этого мы будем использовать пакет python google_images_download для запроса и очистки данных из Картинок Google.

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

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

Чтобы увеличить количество изображений, можно выполнить несколько запросов для каждой эмоции с использованием синонимов. Например, наряду со словом «счастливый» мы можем также запросить «улыбающийся», «веселый» и «приподнятый».

Большинство запросов следует структурировать как «‹emotion› человеческое лицо». Оказывается, что отсутствие слова «человек» в запросе приводит к тому, что большинство изображений являются смайликами 😊

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

Здесь следует отметить несколько моментов:

  1. Чтобы использовать эту библиотеку, необходимо загрузить драйвер Chrome. См. Эту страницу для подробностей.
  2. Google Images ограничивает количество возвращаемых элементов (часто менее 1000).

Отлично, теперь у нас есть два разных источника обозначенных выражений лица!

В поисках лиц

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

К счастью, есть библиотеки с открытым исходным кодом с предварительно обученными моделями распознавания лиц. Для этого проекта мы будем использовать библиотеку facenet-pytorch, которая предоставляет многозадачную CNN [2], предварительно обученную на наборах данных VGGFace2 и CASIA-Webface.

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

У этого есть два приложения:

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

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

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

Подготовка базовой модели

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

Цель здесь - упростить обучение нашей модели, задав ее параметры хорошей отправной точкой. Он может использовать существующие экстракторы функций, полученные от ImageNet, и настроить их для работы с этой новой задачей.

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

Вместо этого давайте заменим первый (трехканальный) сверточный слой в модели произвольно инициализированным одноканальным сверточным слоем. Мы будем использовать Resnet-50 [3] в качестве нашей модели.

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

Здесь изображение RGB подается на вход предварительно обученной модели Resnet-50. Изображение также преобразуется в оттенки серого и подается в качестве входных данных в модифицированный «Gray Resnet-50», где первый сверточный слой теперь принимает одноканальный вход.

Затем два выходных вложения проходят через функцию потерь L2. Хотя выполняется много вычислений, единственные параметры, обновляемые на этапе обратного распространения, - это первый одноканальный сверточный слой в модели «Gray Resnet».

Этот процесс не контролируется, что означает, что мы можем точно настроить модель для любого набора данных, не беспокоясь о поиске меток. В итоге я использовал один и тот же скребок Google Images для загрузки десяти изображений на этикетку. См. Этот ресурс для всех 1000 этикеток ImageNet.

На рис. 4 сравнивается исходная модель и модифицированная версия на двух разных изображениях, каждое из которых имеет цветную версию и версию в градациях серого. Для пары с щеглом модель «Grey Resnet» менее уверена в том, что птица является щеглом, потому что она не могла видеть характерные желтые перья птицы.

Для пары с бородавочником модель «Grey Resnet» более уверена в своем прогнозе, чем исходная модель. В качестве предположения, возможно, это связано с тем, что оригинальная модель фокусируется на цвете меха (у бородавочников и кабанов похожий коричневый мех), тогда как «Серый реснет» может фокусироваться на структурных различиях.

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

Тренировка на лицах

Теперь, когда у нас есть базовая модель, давайте применим трансферное обучение для классификации эмоций! Это будет включать двухэтапную настройку нашей предварительно обученной модели «Gray Resnet».

Первый этап включает точную настройку набора данных FER. Это будет промежуточным этапом перед обучением модели на «диких» данных. Есть надежда, что модель сможет научиться определять простые особенности из набора данных FER из-за грубого разрешения изображений (48 x 48).

На втором этапе модель берется из первого, а затем дорабатывается на «диких» данных. Здесь модель расширит предыдущее представление, чтобы учиться на более богатых функциях, присутствующих в «диких» данных.

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

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

На рисунке 5 ниже показаны результаты проверки данных FER с разделением поездов на тест 80:20. Общая точность модели составляет 87,2%, и похоже, что модель наиболее успешна при эмоциях «радость» и «удивление». С другой стороны, модель больше всего борется с различием между «злым» и «грустным». Возможно, это потому, что обе эмоции обычно связаны с хмурым взглядом.

На рисунке 6 ниже показаны результаты проверки «диких» данных Google Images с разделением 70:30 на тестовый поезд.

На первый взгляд может показаться, что производительность модели ухудшилась, так как общая точность упала до 63,9%. Это потому, что пространство функций для нашей модели изменилось. Изображения в этом наборе «диких» данных намного более разнообразны и зашумлены, что затрудняет их классификацию, чем научный тест FER. Фактически, прямое применение модели на основе данных FER (первый этап) без точной настройки на «диких» данных дает точность менее 51%.

Применение обученной модели

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

На рис. 1 детектор эмоций применен к составу «Друзей» (изображение для удобства скопировано ниже). На этом изображении показано, как модель выбирает между «счастливым» и «грустным» лицом. В частности, более изогнутые улыбки и обнаженные зубы приводят к большей уверенности в «счастливом», чем те, у которых это не так.

На рисунке 7 ниже модель применяется к персонажам Гарри Поттера. Вот пример каждой из пяти целевых эмоций.

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

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

Заключительные мысли

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

Обратите внимание: в зависимости от того, сколько данных возвращается парсером изображений Google, может быть хорошей идеей потратить некоторое время и вручную проверить результаты. Например, в моем случае было возвращено более 5000 изображений, и я потратил около 30 минут, просматривая данные и удаляя все неправильно маркированные / бессмысленные изображения.

Вот некоторые потенциальные способы улучшить проект:

  1. Использование предварительно обученной модели распознавания лиц в качестве базовой модели (вместо ImageNet)
  2. Больше экспериментов с этапами тонкой настройки (например, сколько слоев должно быть разрешено для обучения?)
  3. Использование данных / моделей лицевых ориентиров в тандеме с изображениями лиц

База кода: https://github.com/martin-chobanyan/emotion

использованная литература

[1] И. Дж. Гудфеллоу, Д. Эрхан, П. Л. Карриер, А. Курвиль, М. Мирза, Б. Хамнер, В. Цукерски, Ю. Танг, Д. Талер, Д.-Х. Ли и др., «Проблемы репрезентативного обучения: отчет о трех соревнованиях по машинному обучению» на Международной конференции по обработке нейронной информации. Springer, 2013 г.

[2] Цай, Чжэнни, Циншань Лю, Шаньминь Ван и Брюс Ян. «Совместная оценка положения головы с помощью многозадачных каскадных сверточных сетей для выравнивания лиц». 2018 24-я Международная конференция по распознаванию образов (ICPR), 2018

[3] Хэ, Кайминь, Сянъюй Чжан, Шаоцин Жэнь и Цзянь Сунь. «Глубокое остаточное обучение для распознавания изображений». Конференция IEEE по компьютерному зрению и распознаванию образов (CVPR), 2016 г., 2016 г.