Поскольку я так много изучал модель MTCNN (подробнее о ней здесь), я решил попробовать ее обучить. Даже если подумать об этом концептуально, обучение модели MTCNN было сложной задачей. Это каскадная сверточная сеть, то есть она состоит из 3 отдельных нейронных сетей, которые невозможно обучить вместе. Я решил начать с обучения P-Net, первой сети.

P-Net - это ваш традиционный 12-Net: он принимает изображение размером 12x12 пикселей в качестве входных данных и выводит матричный результат, сообщающий вам, есть ли лицо - и, если есть, координаты ограничивающих прямоугольников и ориентиров лица для каждое лицо. Поэтому мне пришлось начать с создания набора данных, состоящего исключительно из изображений размером 12x12 пикселей.

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

Набор данных WIDER-FACE включает 32 203 изображения с 393 703 лиц людей в различных ситуациях. Эти изображения были разделены на обучающий набор, набор для проверки и набор для тестирования. В рамках обучающей выборки изображения были разбиты по случайности:

Внутри каждой папки были сотни фотографий с тысячами лиц:

Однако все эти фотографии были значительно больше 12х12 пикселей. Мне пришлось разрезать каждый из них на несколько квадратов 12х12, некоторые из которых содержали лица, а некоторые - нет.

Я подумал о том, чтобы просто создать ядро ​​12x12, которое перемещалось по каждому изображению и копировало изображение внутри него каждые 2 пикселя, которое оно перемещало. Однако в результате у меня остались бы миллионы фотографий, на большинстве из которых нет лиц. Чтобы обеспечить лучший тренировочный процесс, я хотел, чтобы примерно на 50% моих тренировочных фотографий было изображено лицо. Кроме того, лица могли быть разного размера. Мне нужны были изображения лиц разного размера.

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

Затем я создам 4 копии каждой фотографии в разном масштабе, так что у меня будет одна копия, где высота лица на фотографии 12 пикселей, одна - высота 11 пикселей, одна - 10 пикселей, а третья - 9 пикселей. пикселей в высоту.

Лицо размером менее 9x9 пикселей слишком мало для распознавания. Чтобы проиллюстрировать мою точку зрения, вот изображение лица молодого Джастина Бибера размером 9x9 пикселей:

Для каждой масштабированной копии я обрежу как можно больше изображений размером 12x12 пикселей. Например, на этом изображении Джастина Бибера 12x11 пикселей я могу обрезать два изображения с его лицом.

С меньшим масштабом я могу обрезать еще больше изображений 12x12. Для каждого кадрированного изображения мне нужно преобразовать координаты ограничивающего прямоугольника в значение от 0 до 1, где левый верхний угол изображения равен (0,0), а правый нижний - (1,1). Это упрощает обработку вычислений и масштабирование изображений и ограничивающих рамок до их исходного размера.

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

Создание негативных изображений (без лица) проще, чем создание позитивных изображений (с изображением лица). Точно так же я создал несколько масштабированных копий каждого изображения с гранями высотой 12, 11, 10 и 9 пикселей, а затем произвольно нарисовал блоки размером 12 x 12 пикселей. Если этот прямоугольник попадал внутрь ограничивающего прямоугольника, я рисовал еще один. Если рамка не перекрывала ограничивающую рамку, я обрезал эту часть изображения.

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

Обучение было значительно проще. Используя код из исходного файла, я построил P-Net. Затем я читаю положительные и отрицательные изображения, а также набор координат ограничивающей рамки, каждое в виде массива. Я дал каждому из негативных изображений координаты ограничивающего прямоугольника [0,0,0,0].

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

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

Я запустил цикл обучения. Примерно через 30 эпох я достиг точности около 80%… что было неплохо, учитывая, что в моем наборе данных всего 10000 изображений.

Сохранив свои веса, я загрузил их обратно в полный файл MTCNN и провел тест с моим недавно обученным P-Net. Как и раньше, он все еще мог точно идентифицировать лица и рисовать ограничивающие рамки вокруг них. Огромным преимуществом модели MTCNN является то, что даже если точность P-Net снизится, R-Net и O-Net все равно смогут уточнить границы ограничивающего прямоугольника.

Вместо того, чтобы снова проходить утомительный процесс обработки данных для RNet и ONet, я нашел эту модель MTCNN на Github, в которую были включены обучающие файлы для модели. Эта модель аналогичным образом обучила только координаты ограничивающего прямоугольника (а не лицевые ориентиры) с набором данных WIDER-FACE.

Как и я, эта модель обрезала каждое изображение (до 12x12 пикселей для P-Net, 24x24 пикселей для R-Net и 48x48 пикселей для O-Net) перед процессом обучения. В отличие от моего простого алгоритма, эта команда классифицировала изображения как положительные или отрицательные на основе IoU (пересечение по объединению, т. Е. Площадь пересечения между изображением 12x12 и ограничивающей рамкой, деленная на общую площадь изображения 12x12 и ограничивающего прямоугольника. ), и включил отдельную категорию для «частичных» граней.

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

Кроме того, для обучения R-Net и O-Net они использовали анализ твердых выборок. Даже после обучения P-Net не идеален; он все равно распознает некоторые изображения без лиц как позитивные (с лицами) изображения. Эти изображения известны как ложные срабатывания. Поскольку работа R-Net заключается в уточнении границ ограничивающего прямоугольника и уменьшении количества ложных срабатываний, после обучения P-Net мы можем принимать ложные срабатывания P-Net и включать их в данные обучения R-Net. Это может помочь R-Net выявить слабые места P-Net и повысить точность. Этот процесс известен как анализ твердых выборок. Точно так же они применили жесткий выборочный анализ и в обучении O-Net.

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

Обучение этой модели заняло 3 дня. Большой набор данных сделал обучение и создание жестких выборок медленным процессом. Кроме того, при первом обучении графическому процессору не хватило памяти, что вынудило меня заново обучить R-Net и O-Net (что заняло еще один день).

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

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

Загрузите статью и ресурсы MTCNN здесь: