У нас была задача отсортировать профили людей по возрасту и полу. Нам нужно было сегментировать базу потенциальных клиентов для запуска тестовых рекламных компаний, для каждой рекламной компании мы подбирали индивидуальные видео которые лучше всего подошли бы людям определенного возраста и пола.
Если вам интересны такие темы и вы хотите и дальше видеть новые публикации и развитие данного модуля, то просим вас поставить нам звездочку ⭐ на Github!
Ссылка на модуль: https://github.com/mowshon/age-and-gender
Содержание статьи:
- Модель для определения формы лица
- Модель для предсказывания возраста
- Модель для определения пола человека по лицу
- Перенос C++ кода на Python
- Структура С++ класса AgeAndGender
- Установка age-and-gender на Ubuntu & Debian
- Пример определения пола и возраста человека
- 🔴 Онлайн проверка возраста и пола по фотографии
После анализа доступных библиотек, мы нашли интересный репозиторий на Github: https://github.com/davisking/dlib-models
Автор Davis E. King @davisking, он же создатель замечательной библиотеки dlib, предоставил уже натренированную модель на несколько тысяч лиц людей. Но, вот беда… код написан на C++ а рабочей альтернативы на Python мы не нашли.
Модель для определения формы лица (shape_predictor_5_face_landmarks.dat)
Это 5-точечная модель, которая определяет уголки глаз и дно носа. Она обучена на наборе данных из 5-точечных ориентиров от 7198 лиц людей. Автор @davisking создал этот набор данных, загружая изображения из Интернета и комментируя их с помощью инструмента imglab от dlib.
Ссылка на скачивание: https://github.com/davisking/dlib-models/blob/master/shape_predictor_5_face_landmarks.dat.bz2
Модель для предсказывания возраста (dnn_age_predictor_v1.dat)
Первоначальный источник для создания модели пришел из документа Z. Qawaqneh: «Глубокая сверточная нейронная сеть для оценки возраста на основе модели VGG-Face». Тем не менее, наши исследования привели нас к значительным улучшениям в CNN модели, что позволило нам оценить возраст человека, превосходящего существующие результаты, с точки зрения точности результата.
Таким образом, эта модель является определителем возраста, использующим архитектуру ResNet-10, и обучается с использованием частного набора данных из примерно 110 тыс. различных изображений людей с комментарием в виде их возраста.
Эта модель прогнозирования возраста предоставляется компанией Cydral Technology бесплатно и распространяется по лицензии Creative Commons Zero v1.0 Universal.
Ссылка на скачивание: https://github.com/davisking/dlib-models/blob/master/age-predictor/dnn_age_predictor_v1.dat.bz2
Модель для определения пола человека по лицу (dnn_gender_classifier_v1.dat)
Эта модель является гендерным классификатором, обученным с использованием частного набора данных из примерно 200 000 различных изображений лиц, и она была сгенерирована в соответствии с определением сети и настройками, заданными в «Минималистической модели на основе CNN для прогнозирования пола по изображениям лиц«. Даже если набор данных, использованный для обучения, отличается от того, который использовался Г. Антиповым, результаты классификации по оценке LFW в целом схожи (± 97,3%).
Эта гендерная модель предоставляется бесплатно компанией Cydral Technology и распространяется по лицензии Creative Commons Zero v1.0 Universal.
Ссылка на скачивание: https://github.com/davisking/dlib-models/blob/master/gender-classifier/dnn_gender_classifier_v1.dat.bz2
Перенос C++ кода на Python
Изначально, @davisking предоставил два C++ файла которые показывали как работать с натренированными им моделями:
Они выводили результат сразу в консоль, но вот использовать код в рабочем проекте даже на C++ было крайне неудобно. Используя pybind11 мы имеем возможность применить код на C++ в нашем коде на Python. Мы не будем акцентироваться долго на pybind11, но если вы хотите ознакомиться с ним, то рекомендуем статью: Создаем С++ Python расширения с помощью pybind11
Структура С++ класса AgeAndGender
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <pybind11/pybind11.h> #include <pybind11/numpy.h> #include <math.h> #include "dlib/data_io.h" #include "dlib/string.h" #include <dlib/image_transforms.h> #include <dlib/dir_nav.h> #include <dlib/dnn.h> #include <dlib/data_io.h> #include <dlib/image_processing/frontal_face_detector.h> namespace py = pybind11; using namespace dlib; const char* VERSION = "1.0.1"; class AgeAndGender { public: virtual ~AgeAndGender() { } virtual void load_shape_predictor(std::string filename); virtual void load_dnn_gender_classifier(std::string filename); virtual void load_dnn_age_predictor(std::string filename); virtual py::list predict( const py::array_t<unsigned char>& photo_numpy_array, py::list face_bounding_boxes ); virtual std::vector<dlib::rectangle> from_py_list_with_tuple_to_vector_with_rectangles(py::list face_bounding_boxes); private: shape_predictor sp; agender_type gender_predictor_net; apredictor_t age_predictor_net; frontal_face_detector detector; }; PYBIND11_MODULE(age_and_gender, m) { m.doc() = "Predict Age and Gender using Python"; m.attr("__version__") = VERSION; py::class_<AgeAndGender>(m, "AgeAndGender") .def("load_shape_predictor", &AgeAndGender::load_shape_predictor) .def("load_dnn_gender_classifier", &AgeAndGender::load_dnn_gender_classifier) .def("load_dnn_age_predictor", &AgeAndGender::load_dnn_age_predictor) .def( "predict", &AgeAndGender::predict, py::arg("photo_numpy_array"), py::arg("face_bounding_boxes") = py::list() ) .def(py::init<>()); } |
Полный код можно увидеть тут: https://github.com/mowshon/age-and-gender/blob/master/src/main.cpp
- Метод
load_shape_predictor()
принимает путь к файлуshape_predictor_5_face_landmarks.dat
; - Метод
load_dnn_gender_classifier()
принимает путь к файлуdnn_gender_classifier_v1.dat
для загрузки модели гендерной классификации; - Метод
load_dnn_age_predictor()
принимает путь к файлуdnn_age_predictor_v1.dat
для загрузки модели предсказывания возраста; - Метод
predict()
принимает два аргумента, первый обязательный в виде матрицы пикселей изображения, второй не обязательный в виде списка из лиц которых удалось найти на изображении.
Компиляция и установка модуля для определения возраста и пола
Это не обычный модуль которого можно установить без каких либо дополнительных зависимостей. Для удачной компиляции модуля, нам нужно установить:
- CMake >= 3.14 — кроссплатформенная система автоматизации сборки программного обеспечения из исходного кода;
- Компилятор gcc или c++.
- python-dev;
- setuptools.
Установка age-and-gender на Ubuntu & Debian
Рекомендуем любые новые проекты и тестирование модулей делать в виртуальном окружении, этим самым вы не засорите свой системный интерпретатор ненужными модулями. Первым делом создаем виртуальное окружение и активируем её.
1 2 |
python3 -m venv venv source venv/bin/activate |
Устанавливаем необходимые зависимости:
1 |
sudo apt install cmake libjpeg-dev g++ build-essential libfreetype6-dev |
Скачиваем файлы с github и выполняем установку:
1 2 3 |
git clone git@github.com:mowshon/age-and-gender.git cd age-and-gender python setup.py install |
В папке example есть тестовый файл example.py запустив которого вы увидите как скрипт определил возраст членов семьи Билла Гейтса.
1 2 |
cd example/ python example.py |
Пример определения пола и возраста человека в Python
В качестве примера, мы решили протестировать весьма забавный конспирологический спор о двойниках президента Российской Федерации. Мы скачали из интернета изображение с несколькими вариантов клонов В. Путина и предложили нейронной сети определить пол и возраст всех лиц на фото.
Использованные файлы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from age_and_gender import * from PIL import Image, ImageDraw, ImageFont data = AgeAndGender() data.load_shape_predictor('shape_predictor_5_face_landmarks.dat') data.load_dnn_gender_classifier('dnn_gender_classifier_v1.dat') data.load_dnn_age_predictor('dnn_age_predictor_v1.dat') img = Image.open('putin.png').convert("RGB") result = data.predict(img) font = ImageFont.truetype("Lemon.ttf", 10) for info in result: shape = [(info['face'][0], info['face'][1]), (info['face'][2], info['face'][3])] draw = ImageDraw.Draw(img) gender = info['gender']['value'] if gender == 'male': gender = 'Мужчина' else: gender = 'Женщина' gender_percent = int(info['gender']['confidence']) age = info['age']['value'] age_percent = int(info['age']['confidence']) draw.text( (info['face'][0] - 10, info['face'][3]), f"{gender} (~{gender_percent}%)", fill='white', font=font, align='center', stroke_width=3, stroke_fill='black' ) draw.rectangle(shape, outline="red", width=5) img.show() |
Результат применения нейронной сети:
Мы, конечно, понимаем, что это фотографии с разных ракурсов и разные периоды жизни человека. В этом и кроется главный минус определения возраста, нейронная сеть была натренирована на определенный (ограниченный) сет данных и имеет погрешность. Мимика, шрамы и эмоции так-же могут повлиять на результат.
Онлайн проверка возраста и пола по фотографии
Для того, чтобы протестировать данный модуль, вам не нужно его устанавливать, достаточно воспользоваться ниже предоставленной формой. Загрузите изображение с лицами людей и увидите результат.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»