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

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

Мы собираемся использовать Haarcascade и OpenCV для обнаружения лиц во входном потоке веб-камеры в реальном времени. Затем мы переобучаем искусственную нейронную сеть inception v3 для классификации мужских и женских лиц. В качестве обучающих данных мы собираемся очистить некоторые изображения из поиска Bing Images. Впоследствии мы будем использовать эту медленную начальную модель v3 для автоматической классификации большого набора данных из примерно 15000 изображений лиц, которые затем мы будем использовать для обучения гораздо более быстрой нейронной сети, которая значительно повысит производительность живого классификатора.

В этом проекте мы в основном будем полагаться на Tensorflow и OpenCV. Ссылки на все соответствующие библиотеки и онлайн-ресурсы указаны в приложении.

Давайте начнем!

1.) Входной поток камеры

Прежде всего, нам нужно передать входной поток нашей веб-камеры в наш скрипт python. После установки openCV с помощью pip через

pip install opencv-python

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

Когда мы запускаем наш скрипт python, появится небольшое окно, содержащее прямой видеопоток с нашей веб-камеры. В цикле «while True» у нас есть доступ к текущему кадру, который хранится либо в цвете в переменной «img», либо в оттенках серого в переменной «gray». Мы будем использовать версию с оттенками серого позже, когда будем классифицировать лица.

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

2.) Каскадное распознавание лиц

Теперь, когда у нас настроен входной поток, мы хотим выполнить распознавание лиц. Хотя мы могли бы обучить ИНС и для этой цели, вместо этого мы будем полагаться на Haar Cascade. На это есть две основные причины: во-первых, я хочу применять машинное обучение только к проблемам, которые очень сложно решить с помощью классических алгоритмов. Но обнаружение лиц с использованием каскада Хаара очень эффективно и бесшумно, поэтому я буду полагаться на существующие алгоритмы для решения новых проблем. Во-вторых, цель этого репо - не создавать и классифицировать наборы данных вручную, поскольку это тихая скучная и несложная работа. Вместо этого мы будем использовать алгоритмы, которые выполняют всю работу за нас, поскольку я предпочитаю кодировать алгоритм на 10 часов, а не вручную вырезать лица из изображений в течение 5 часов, просто для обучения модели машинного обучения.

Каскадные алгоритмы Хаара также являются формой машинного обучения, но они не используют нейронные сети. Основополагающий принцип каскада хаара был предложен Полом Виолой и Майклом Джонсом в их очень межстрочной статье « Быстрое обнаружение объектов с использованием усиленного каскада простых функций » легко понимают, но при этом гениально эффективны и умны.

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

Рис. 1. Каскадные особенности Хаара. Авторское право: OpenCV.org

Каскадные алгоритмы хаара выбирают первое подмножество изображения определенного размера и идентифицируют все эти простые функции. Для алгоритма распознавания лиц каскад хаара идентифицирует более 200 функций. Одной из таких особенностей может быть линия между бровью и глазом, а другой - резкий контраст между радужной оболочкой. Наконец, он сравнивает идентифицированные им черты лица с моделью, которая содержит такие описания черт лиц. Когда идентифицированные им особенности совпадают в определенной степени с описанием оптимальных характеристик модели, каскадный алгоритм Хаара отмечает подмножество, которое он в настоящее время сканирует, как «лицо».

Рисунок 2: Распознавание лиц. Авторское право: OpenCV.org

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

Рисунок 3: Демонстрация каскадного распознавания лиц хаара. Авторское право: Адам Харви

Каскад haar, который мы будем использовать для нашей цели, - это каскад фронтальной грани по умолчанию, который вы можете загрузить прямо из репозитория github OpenCV. Обратите внимание, что, хотя каскады можно использовать бесплатно, они подпадают под лицензию Intel Corporation.

Сначала мы пишем небольшой метод, который позволяет нам вручную загружать каскад haar для распознавания лиц из репозитория github. Код на Python для этого довольно прост:

Мы используем os для создания папки под названием «cascade» в нашем рабочем каталоге, затем мы используем запросы для записи файлового потока на наш локальный диск.

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

Рисунок 4: Демонстрация каскадного обнаружения лиц Хаара. Авторское право: SRF

Мы снова используем OpenCV для импорта модели классификации. После преобразования входного изображения в оттенки серого мы обнаруживаем все лица в нескольких масштабах и сохраняем координаты (координаты x и y, высота и ширина обнаруженного лица) в списке, который мы позже рисуем поверх кадра. Каждый раз, когда мы обнаруживаем лицо, мы сбрасываем таймер exclude_frames, который отслеживает, сколько кадров мы еще не идентифицировали. Если мы не идентифицировали лицо для более чем 15 кадров, что примерно соответствует половине секунды, мы сбрасываем прямоугольник, который мы нарисовали вокруг лица. Это сделано для предотвращения мерцания: иногда достаточно моргания глаз, чтобы каскадный классификатор потерял лицо, поэтому мы используем тот факт, что в большинстве случаев лица не исчезают просто так, поэтому даже мы думали, что потеряв лицо, держим прямоугольник на месте полсекунды. Когда мы снова нашли лицо за это время, мы соответствующим образом корректируем положение прямоугольника. Если мы снова не изменим форму лица, мы удалим прямоугольник, установив его положение равным одному пикселю в верхнем левом углу изображения.

3.) Поиск и загрузка изображений

Хорошо, следующим шагом будет загрузка изображений с мужскими и женскими лицами. Мы будем использовать эти изображения для обучения нашей модели inception v3. Конечно, мы могли бы просто выполнить поиск Google Images вручную, а затем загрузить первые X-изображения, которые, кажется, полностью удовлетворяют наши потребности - но зачем нам делать что-то вручную, что мы также могли бы кодировать на python? Давайте напишем короткий скрипт, который выполняет поиск Bing Images (да, Bing. Мне не удалось использовать Google Images, поскольку обе поисковые системы на самом деле не хотят, чтобы мы очищали их результаты поиска, но Google слишком умен для меня Не удалось придумать, как их обмануть - но мне потребовалось всего 2 минуты для Bing) и загрузить для нас первые X-изображения.

Поскольку эта задача не связана с нашим фактическим обучением ИНС, я решил написать быструю библиотеку для части поиска изображений Bing и загрузить ее в PyPi. Вы можете найти репозиторий здесь и ссылку на PyPi здесь.

Позвольте мне очень быстро объяснить вам, как работает BingImages. Когда вы отслеживаете свою сетевую активность во время поиска изображений Bing, вы можете заметить, что они выполняют асинхронный вызов своего REST API, который затем отвечает HTML-сайтом, содержащим список ссылок на изображения. Просто подделав REST-вызов и сопоставив шаблон ответа, я смог извлечь ссылки и загрузить их на локальный диск. В BingImages все это делается одной строкой кода:

Рисунок 5. Демонстрация фона BingImages.

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

После того, как мы загрузили изображения, мы отфильтровываем все изображения с неправильным расширением файла или слишком низким качеством (размер слишком мал). Затем мы переименовываем изображения в соответствии с шаблоном именования img_X.jpg.

4.) Подготовьте изображения для обучения

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

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

Сначала мы пишем метод, который принимает входные изображения и возвращает изображения лиц на этом конкретном изображении.

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

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

Рисунок 6. Данные тренировки лица для мужчин и женщин. Авторские права: разные, но, конечно, не я.

5.) Переобучение модели inception v3

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

С другой стороны, есть предварительно обученные сети, такие как «ImageNet» или «Inception V3», модели, созданные, настроенные и обученные исследовательскими группами из Google Brain с почти бесконечным количеством ресурсов и данных обучения. Такие модели могут точно классифицировать изображения из тысяч классов, и модели были настроены лучшими экспертами в области искусственного интеллекта для получения максимально возможного результата.

Рис. 7. Модель Inception V3 от Google Brain. Авторское право: Medium

Что, если бы мы могли взять такую ​​продвинутую модель и переобучить ее, чтобы классифицировать наши классы за нас? Что ж, в этом и заключается суть трансферного обучения. Как вы знаете, нейронные сети состоят из слоев нейронов. В то время как первые слои идентифицируют абстрактную информацию, более поздние слои способны распознавать функции более высокого уровня, например, если вы не знакомы с нейронными сетями и слоем, я настоятельно рекомендую вам проверить мой другой репозиторий на тему Введение в Deep Dreaming »

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

Есть замечательная статья, написанная Максимом Окуабом и др. al. под названием Изучение и передача среднеуровневых представлений изображений с помощью сверточных нейронных сетей. Это объясняет передачу обучения тихо, поэтому я процитирую здесь соответствующий абзац:

«Архитектура CNN содержит более 60 миллионов параметров. Непосредственное обучение такому количеству параметров всего из нескольких тысяч обучающих изображений проблематично. Ключевая идея этой работы заключается в том, что внутренние слои CNN могут действовать как общий экстрактор представления изображения среднего уровня, который может быть предварительно обучен на одном наборе данных (исходная задача, здесь InceptionV3), а затем повторно использован на другие целевые задачи (здесь классификация лиц), как показано на рисунке 8. Однако это сложно, поскольку метки и распределение изображений (тип объектов, типичные точки обзора, условия визуализации и т. д.) в исходном и целевом наборах данных могут быть Очень разные. Для решения этих проблем мы (i) проектируем архитектуру, которая явно переназначает метки классов между исходными и целевыми задачами, и (ii) разрабатываем процедуры обучения и тестирования, вдохновленные детекторами скользящего окна, которые явно имеют дело с различным распределением размеров объектов, локации и беспорядок сцены в исходных и целевых задачах ».

Источник: Максим Окуаб и др. др .: « Изучение и передача среднеуровневых представлений изображений с использованием сверточных нейронных сетей »

*

Рисунок 8: Переобучение нейронной сети. Авторские права: « Изучение и передача среднеуровневых представлений изображений с использованием сверточных нейронных сетей »

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

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

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

6.) Применение классификатора лиц к прямой трансляции с камеры

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

Классифицировать лицо не так просто, как сохранить его на диск и затем вызвать функцию «классифицировать».

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

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

7.) Закрепление нашей классификации

Единственная проблема, с которой мы сталкиваемся с этим решением, заключается в том, что используемая нами модель тензорного потока, называемая inception v3, довольно медленная. Классификация лица занимает около 2 секунд, что по-прежнему работает тихо, но этого недостаточно для обнаружения живого изображения. Поэтому нам необходимо найти способ ускорить работу нашей сети - и лучший способ сделать это - обучить новую нейронную сеть под названием MobileNet, также созданную Google, но сделанную максимально быстрой с помощью наших других , медленнее Сеть.

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

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

То, что мы МОЖЕМ найти в Интернете, - это большие наборы данных изображений, которые мы можем скачать бесплатно - изображения людей, лиц и многое другое. Проблема с этими наборами заключается в том, что они не классифицируются по нашим потребностям: когда мы загружаем большой набор изображений лиц, все изображения мужчин и женщин смешиваются. Затем мы можем либо раскопать их вручную и отделить самцов от самок, либо сделать это разумно и использовать для этой задачи нашу медленную, но надежную модель inception v3!

8.) Получение больших наборов данных из Интернета

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

Один из самых больших наборов данных с открытым исходным кодом, который мне удалось найти, - это набор данных Labeled Faces in the Wild. Он содержит около 13 000 изображений в оттенках серого с лицами разных знаменитостей, включая Роджера Федерера, Мишель Обаму или даже Усаму бен Ладена. Еще один хороший сборник изображений предлагает Стирлинг, и его можно скачать здесь. Теперь давайте снова напишем сценарий для загрузки, распаковки и сортировки всех этих изображений - всего 15 000+.

После загрузки архивов мы распаковываем их и копируем все файлы в новое место с заданной схемой именования img_X.jpg.

Рисунок 9: Пример из набора данных LFW. Авторское право: Массачусетский университет

9.) Классифицируйте наборы данных, используя начальную модель v3.

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

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

Рис. 10. Вырезать грани из набора данных LFW. Авторское право: Массачусетский университет

10.) Переобучение более быстрой модели MobileNet

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

Примерно через два дня модель завершила обучение и ее можно было классифицировать.

11.) Заключительные живые тесты с более быстрой моделью MobileNet

Теперь давайте протестируем новую модель MobileNet с нашей классификацией в реальном времени. Теоретически процесс классификации теперь должен быть чрезвычайно быстрым и занимать менее полсекунды на CPU, а менее 1/30 секунды на GPU.

И действительно, классификация лица занимает очень мало времени, и через несколько кадров лицо уже классифицируется. Обученная модель столкнулась с некоторыми трудностями. Во-первых, данные обучения были довольно асимметричными: примерно 25% женщин и 75% мужчин, что позволяет модели предсказывать мужчин с гораздо большей точностью, чем женщины. Кроме того, средний возраст людей, представленных в обучающей выборке, составлял от 30 до 40 лет, что заставляет нейронную сеть искать такие особенности, как морщины или неровную кожу, для идентификации мужчин - вот почему часто молодых мужчин ошибочно идентифицируют как женщин, поскольку они свойства лица ближе к женщинам среднего возраста, чем к мужчинам среднего возраста.

Рисунок 11: Живая классификация лиц. Авторское право: SRF.

Последние мысли

С помощью Tensorflow мы смогли создать быстрый и надежный классификатор в реальном времени без необходимости вручную создавать набор данных входных изображений. Наш код можно легко повторно использовать и обучать другим чертам лица: морщинкам, возрасту, длинным / коротким волосам, очкам и многому другому - при условии, что функции обучения находятся в одном из автоматически загружаемых наборов данных. Алгоритм начинается всего с двух слов и справляется со всей работой самостоятельно: от первоначального получения нескольких надежных базовых обучающих изображений до обучения модели inception-v3, до загрузки большого набора данных, подготовки его к тому, чтобы сделать его надежным. входной набор данных для сети MobileNet, затем, наконец, переобучение более быстрой сети MobileNet и быстрая классификация из входящего потока в реальном времени.

Для дальнейшего улучшения алгоритма мы могли бы попытаться настроить параметры обучения (итерации, шаги обучения) или сделать исходный набор изображений более надежным. Без двойной проверки начальной обучающей выборки мы сталкиваемся с опасностью использования изображений в качестве триангулирующих изображений, которые напрямую не описывают наши особенности. Это связано с поисковой системой изображений Bing: при поиске «женского лица» мы получаем изображения женских лиц очень высоко в потоке результатов, что заставляет нас обучать сеть для неправильных данных.

Если вам нужен специалист в области разработки программного обеспечения или искусственного интеллекта, посетите мою Компанию по разработке программного обеспечения в Цюрихе.