Кейс: Хабиб vs МакГрегор или Распознавание лиц на Python
Учимся представлять фотографии в виде матриц, обрабатывать их, детектить лица и натравливать на них нейронку.
13К открытий14К показов
Рассказывает команда IT Resume
Детекция (т.е. нахождение) и распознавание лиц — очень популярная задача в современном мире: в метро уже давно следят за нашими передвижениями, а в загородных домах все чаще ставят «умные дверные глазки».
Так уж сложилось, что сейчас уже нельзя просто написать программу для распознавания лиц и присвоить себе должность Senior Data Scientist — таких знаний требуют даже от начинающих специалистов.
Если Вы еще не игрались с распознаванием лиц, но хотите развиваться в области нейронных сетей (ну или просто Вам интересна эта область), то эксперты IT Resume подготовили для вас этот гайд — давайте вместе пройдем все шаги:
- научимся загружать и представлять фотографии в виде матриц;
- проведем обработку исходных фотографий;
- задетектим лица на фотографии;
- обработаем изображения нейронной сетью;
- посмотрим — сможет ли сеть понять, что мы ей дали два фото одного и того же человека.
Для работы нам потребуется:
- Google Colab — среда для работы с Python в браузере. Они еще доступ к GPU дают (а для нейронных сетей это очень нужно).
- И все ?
Итак, начнем.
Этап 1. Подключение модулей
Перед тем, как начать работу, давайте сменим среду выполнения на «Ускорение GPU». В будущем нам это понадобится для работы нейронной сети. Для этого в Google Colab нажимаем «Среда выполнения» → «Сменить среду выполнения» → «Аппаратный ускоритель GPU».
Теперь подключим необходимые библиотеки. В Colab большинство библиотек уже установлено, поэтому нам осталось их только импортировать:
cv2
— для загрузки и обработки изображений;dlib
— для детекции лиц;numpy
— для работы с матрицами.
Помимо этого, с помощью команды pip install face_recognition
мы устанавливаем библиотеку face_recognition
— с ее помощью мы будем обрабатывать лицо нейронной сетью.
Примечание Вообще сделать полную обработку можно всего за несколько строчек кода, потому что в библиотеке face_recognition
многие процессы (например, детекция лиц) уже завернуты в функции. Но мы намеренно некоторые вещи будем делать «с нуля», чтобы вы лучше во всем разобрались.
Этап 2. Первичная настройка
Теперь нам нужно произвести небольшую настройку, чтобы потом полноценно использовать все инструменты и кодовую базу.
Начнем с настройки детектора лиц. Сначала скачиваем файл с готовой моделью с помощью команды wget
(да, именно этой командой Цукерберг запустил Фэйсбук в фильме Социальная сеть) и распаковываем файл в формат .dat.
Далее создаем детектор лиц и передаем скачанную модель в shape_predictor
, который будет предсказывать ключевые точки человеческого лица — контур головы, глаза, нос и рот.
Отлично, теперь мы готовы переходить к содержательной части — обработке фотографий.
Этап 3. Загрузка и обработка фотографий
Перед тем, как загружать фотографию в переменную Python, ее надо загрузить в файловое хранилище Google Colab. Для этого достаточно нажать на иконку Папки на левом сайдбаре и выбрать Upload.
Мы, например, загрузим фотографию Конора МакГрегора.
Отлично, теперь надо «прочитать» изображение в переменную Python. Это можно сделать несколькими способами, но нам удобнее представить изображение сразу в виде матрицы. Это можно сделать с помощью функции imread
из модуля cv2
.
Если вы загружаете цветную картинку, то «матрица» будет иметь размерность 3*height*width
, где 3 — количество цветовых каналов (RGB), а width
и height
— размерность картинки в пикселях. Проверить это можно с помощью метода shape
. Каждое число в матрице — значение пикселя по конкретному цветовому каналу.
Кстати говоря, если вы хотите посмотреть на загруженную картинку, то вам нужно:
- Импортировать команду
cv2_imshow
:from google.colab.patches import cv2_imshow
. - Передать в функцию
cv2_imshow
нужную картинку:cv2_imshow(img)
.
В некоторых задачах имеет смысл обрабатывать не цветное изображение, а черно-белое. Например, на детекцию лиц наличие цвета мало влияет — контуры лица и так хорошо видны. А вот для нейронной сети это может быть принципиальный момент — мало ли, люди выглядят одинаково, а цвет кожи разный.
Поэтому давайте переведем нашу цветную картинку в черно-белую:
Теперь переходим к следующему этапу — детекция лица.
Этап 4. Детекция лица
Детектор лиц у нас уже настроен, поэтому можем переходить непосредственно к детекции. Делать это будем в 2 этапа:
- Ищем прямоугольники, в которых находятся лица.
- По этим прямоугольникам предсказываем контуры и ключевые точки лица.
С помощью detector
мы получим координаты нужного прямоугольника. Если лиц несколько, то и наборов точек будет несколько. Чтобы выбрать конкретное лицо, нужно указать индекс (в нашем случае — ноль).
Чтобы посмотреть на результат, можно нарисовать рамку вокруг лица с помощью метода rectangle
и посмотреть фото с помощью cv2_imshow
. Только будьте осторожны — рамка останется на фото навсегда, так что лучше потом загрузить изображение заново.
Теперь по найденным квадратам нужно «предсказать» ключевые точки лица. Для этого используем predictor
, а потом извлекаем координаты точек.
Здесь, чтобы получить координаты точек, мы использовали сразу несколько полезных — операций Python:
— лямбда-функции;
— функцию map;
— распаковку.
Если вы планируете связать свою работу с Python, то обязательно освойте все эти приемы — они сильно упростят вам жизнь.
На выходе у нас получилось 68 точек. Не будем сильно в этом гайде заморачиваться с тем, как нанести это на фото, но получится что-то в таком духе:
Теперь у нас есть вся необходимая информация, чтобы обработать изображение нейронной сетью — и изображение, и ключевые точки лица. Переходим к следующему этапу.
Этап 5. Обработка нейронной сетью
Основная идея обработки сетью заключается в том, что из исходного «большого» изображения выделяются только ключевые признаки, которые впоследствии и помогут нам отличить одного человека от другого. Другими словами, многомерная матрица-картинки преобразуется в относительно небольшой числовой вектор, который характеризует лицо с картинки.
Итак, получить итоговый вектор очень просто — достаточно вызвать функцию face_encodings
.
Примечание Обратите внимание, что в качестве аргументов мы передали только изображение, а полученные ранее ключевые точки мы не использовали. Причина очень проста — функция face_encodings
делает все те же самые действия, которые мы с вами проделали вручную ранее для понимания процесса «изнутри».
На выходе мы получаем вектор размерности 128, т.е. 128 чисел, которые описывают лицо на фотографии. Что значит каждое из этих чисел — неизвестно: это некоторая абстракция, восстановить и осмыслить которую невозможно — слишком уж много математических преобразований лежит внутри этого процесса.
Однако, от этого вектора нам толку мало — чтобы оценить эффективность «нейросетевых технологий», нужно сравнить два вектора для двух разных фотографий. Давайте немного поэксперементируем — будем подавать разные фото на вход и сравнивать с нашим изначальным фото МакГрегора.
Этап 6. Сравнение векторов
Чтобы сравнивать лица между собой, мы будем действовать следующим образом:
- Загружаем новое фото и производим обработку, которую уже разобрали на предыдущих этапах. На выходе получаем вектор.
- Сравниваем вектора между собой.
- На основании расстояния принимаем решение — один и тот же человек на фото или разные.
Встает вопрос — что значит «сравнить вектора»? Самый простой способ — посчитать расстояние в некоторой метрике. Мы выберем обычную евклидову метрику. Вычислять ее без лишнего кода нам позволит функция pdist
из scipy.spatial.distance
.
Итак, сначала загрузим еще одну фотографию Конора.
Сохраняем полученный вектор для первой фотографии в vector1
, для второй — в vector2
и вычисляем расстояние:
Получаем ответ — 0,48. Это достаточно близкое расстояние, из чего делаем вывод, что это один и тот же человек. Сеть справилась отлично!
Ну хорошо, еще пару экспериментов — давайте возьмем снова Конора, но усложним задачу — пусть он будет в очках.
Результат — 0,56. Снова в яблочко (разработчик библиотеки face_recognition
рекомендует придерживаться порога 0,6 — если больше 0,6, то это другой человек).
Ну что ж, а может сеть просто всех определяет как Конора? Давайте подсунем ей другого бойца — Хабиба Нурмагомедова. Что наша сеть на это скажет?
Снова проводим уже известную процедуру и ответ… — 0.72. По утвержденному ранее порогу, делаем вывод: Хабиб — не Конор. Сеть снова нас не подвела, и мы со спокойной душой можем переходить к более сложным проектам.
Эпилог
Мы с вами разобрали основной инструментарий, который вам понадобится для старта в области face recognition (да и в нейронных сетях, в целом). Однако это далеко не предел — мы затронули лишь верхушку айсберга, опустив очень много моментов как программных, так и математических.
Вот несколько вещей, которые мы рекомендуем вам сделать, чтобы прокачаться в области Computer Vision (компьютерное зрение):
- Научитесь выстраивать процесс распознавания с нуля, без использования оберток (чем является библиотека
face_recognition
). Начните хотя бы с изучения исходников этой библиотеки на GitHub — там ничего сверхсложного нет. - Попробуйте разные нейронные сети. Погуглите state-of-the-art решения и посмотрите — чем будет различаться результат.
- Изучите структуру нейронных сетей (например, сверточных) с математической точки зрения. Это можно сделать с помощью многочисленных туториалов и официальной документации библиотек (например, PyTorch).
Есть много и других точек роста, но начните с этих — остальные мысли придут в процессе ?
Желаем удачи и будем рады помочь в комментариях!
P.S. Наш ноутбук с кодом в Google Colab Вы можете найти здесь.
13К открытий14К показов