Вы и Брэд Питт похожи на 99% |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2018-07-17 19:42 Мы в отделе аналитики онлайн-кинотеатра Okko (Мама, привет, я теперь работаю на Rambler) любим как можно сильнее автоматизировать подсчёты сборов фильмов Александра Невского, а в освободившееся время учиться новому и реализовывать классные штуки, которые почему-то обычно выливаются в ботов для Телеграма. К примеру, перед началом чемпионата мира по футболу 2018 мы выкатили в рабочий чат бота, который собирал ставки на распределение итоговых мест, а после финала подсчитал результаты по заранее придуманной метрике и определил победителей. Хорватию в четвёрку не поставил никто. Недавнее же свободное от составления ТОП-10 российских комедий время мы посвятили созданию бота, который находит знаменитость, на которую пользователь больше всего похож лицом. В рабочем чате идею все настолько оценили, что мы решили сделать бота общедоступным. В этой статье мы кратко вспомним теорию, расскажем о создании нашего бота и о том, как сделать такого самому. Немного теории (в основном в картинках) Подробно о том, как устроены системы распознавания лиц я рассказывал в одной из предыдущих своих статей. Интересующийся читатель может перейти по ссылке, а я изложу ниже лишь основные моменты. Итак, у вас есть фотография, на которой, возможно, даже изображено лицо и вы хотите понять, чьё же оно. Для этого вам необходимо выполнить 4 простых шага:
Выделение лица И хотя свёрточные нейронные сети в последнее время уже научились находить лица на изображении не хуже классических методов, они всё-ещё уступают классическому HOG-у по скорости и удобству использования. HOG — Histograms of Oriented Gradients. Каждому пикселю исходного изображения этот парень ставит в соответствие его градиент — вектор, в направлении которого яркость пикселей изменяется сильнее всего. Преимущество такого подхода в том, что ему не важны абсолютные значения яркости пикселей, достаточно лишь их отношения. Поэтому и нормальное, и затемнённое, и плохо освещённое, и шумное лицо отобразится в примерно одинаковую гистограмму градиентов. Считать градиент для каждого пикселя нет необходимости, достаточно посчитать средний градиент для каждого маленького квадратика Выделение ключевых точек Ключевые точки — точки, которые помогают идентифицировать лицо в пространстве. Слабым и неуверенным в себе дата саентистам обычно нужно 68 ключевых точек, а в особо запущенных случаях и того больше. Нормальным же и уверенным в себе пацанам, зарабатывающим 300к в секунду, всегда было достаточно пяти: внутренние и внешние уголки глаз и нос. Извлечь такие точки можно, например, каскадом регрессоров. Выравнивание лица Клеил в детстве аппликации? Тут всё точно так же: строишь аффинное преобразование, которое переводит три произвольные точки в их стандартные позиции. Нос можно оставить как есть, а для глаз посчитать их центры — вот и три точки готовы. Преобразование изображения лица в вектор С момента публикации статьи про FaceNet прошло уже три года, за это время появилось множество интересных схем обучения и функций потерь, но среди доступных OpenSource решений доминирует именно она. Видимо, всё дело в комбинации простоты понимания, реализации и приличных достигаемых результатах. Спасибо хоть на том, что архитектуру за эти три года таки сменили на ResNet. FaceNet учится на тройках примеров: (anchor, positive, negative). Anchor и positive примеры принадлежат одному человеку, negative же выбирается как лицо другого человека, которое сеть почему-то располагает слишком близко к первому. Функция потерь спроектирована таким образом, чтобы исправить это недоразумение, сблизить нужные примеры и отодвинуть от них ненужный. Выход последнего слоя сети называется эмбедингом — репрезентативным представлением лица в некотором пространстве малой размерности (как правило, 128-мерном). Сравнение лиц Прелесть хорошо обученных эмбедингов в том, что лица одного человека отображается в некоторую небольшую окрестность пространства, отдалённую от эмбедингов лиц других людей. А значит, для этого пространства можно ввести меру схожести, обратную расстоянию: евклидову или косинусному, в зависимости от того, с помощью какой дистанции сеть обучали. Таким образом, нам заранее нужно построить эмбединги для всех людей, среди которых будет производиться поиск, а затем, для каждого запроса, найти среди них ближайший вектор. Или, по-другому, решить задачу нахождения Какую библиотеку использовать? Выбор открытых библиотек, которые реализуют различные части пайплайна велик. Находить лица и ключевые точки умеют Делаем собственного бота Данная секция уже описывалась буквально в каждом руководстве по созданию ботов, но раз и мы пишем такое же, придется повториться. Пишем @BotFather и просим у него токен для нашего нового бота. Токен выглядит примерно так: Надеюсь, ни у кого на данном этапе не возникнет раздумий при выборе языка программирования. Конечно же, писать надо на Хаскелле. Начнём с главного модуля.
Как видно из кода, в дальнейшем мы будем использовать специальный DSL для написания телеграм ботов. Код на этом DSL пишется в отдельных файлах. Установим доменный язык и всё необходимое.
Начать писать бота с
Запустим бота. В отладочных целях это можно делать командой Такой простой бот способен поддержать минимальную беседу, а следовательно, легко может устроиться работать фронтенд разработчиком. Но фронтенд разработчиков и так слишком много, поэтому убьём его поскорее и приступим к реализации главной функциональности. В целях простоты наш бот будет отвечать только на сообщения, содержащие фотографии и игнорировать любые остальные. Изменим код на следующий.
Когда картинка попадает на сервера Telegram, она автоматически подгоняется под несколько заранее заданных размеров. Бот в свою очередь может скачать изображение любого размера из тех, что содержатся в списке
Изображение скачано и находится в памяти. Для его интерпретации и представления в виде матрицы интенсивности пикселей воспользуемся библиотеками
Следующий код необходимо добавить в блок
Настало время dlib. За пределами функции создадим детектор лиц.
А внутри функции используем его.
Второй параметр функции означает увеличение, которое необходимо применить перед попыткой обнаружения лиц. Чем он больше, тем более мелкие и сложные лица детектор сможет обнаружить, но тем дольше он будет работать.
Переходим к следующему этапу — поиску ключевых точек. Скачиваем обученную модель и выносим её загрузку за пределы функции.
Находим ключевые точки.
Дело осталось за малым: выровнять лицо, прогнать его через ResNet и получить 128-мерный эмбединг. К счастью, dlib позволяет сделать всё это одним вызовом. Нужно только скачать предобученную модель.
Только посмотрите, в какое прекрасное время мы живём. Вся сложность свёрточных нейронных сетей, метода опорных векторов и аффинных преобразований, применённых к распознаванию лиц, инкапсулирована в три библиотечных вызова. Так как мы пока не умеем делать ничего осмысленного, давайте возвращать пользователю среднее значение его эмбединга, умноженное на тысячу.
Чтобы наш бот умел определять на кого из знаменитостей похож пользователей, нам теперь необходимо найти хотя-бы по одной фотографии каждой знаменитости, построить по ней эмбединг и куда-нибудь его сохранить. В наш учебный бот мы добавим всего 10 знаменитостей, найдя их фотографии руками и сложив в директорию Если вы хотите иметь в базе миллион знаменитостей, всё будет выглядеть точно так же, только файлов побольше и искать их руками уже вряд ли получится. Теперь создадим утилиту
Добавим загрузку эмбедингов в код нашего бота.
И методом полного перебора найдём, на кого же всё-таки похож наш пользователь.
Обратите внимание, что в качестве расстояния мы используем евклидову дистанцию, т.к. сеть в dlib была обучена именно с помощью неё. Вот и всё, поздравляю! Мы с вами создали простейшего бота, который умеет определять, на кого из знаменитостей похож пользователь. Осталось найти побольше фотографий, добавить брендирования, масштабируемости, щепотку логгирования и всё, можно выпускать в продакшен. Все эти темы слишком объёмные, чтобы подробно рассказывать про них с огромными листингами кода, поэтому я просто изложу основные моменты в формате вопроса-ответа в следующем разделе. Полный код учебного бота доступен на GitHub. Рассказываем про нашего бота Сколько у вас в базе знаменитостей? Где вы их нашли? Самым логичным решением при создании бота показалось взять данные о знаменитостях из нашей внутренней контентной базы. Она в формате графа хранит фильмы и все сущности, которые с фильмами связаны, в том числе актёров и режиссёров. Для каждой персоны нам известны её имя, логин и пароль от iCloud, связанные фильмы и alias, который можно использовать для генерации ссылки на сайт. После очистки и извлечения только необходимой информации остаётся
Таких записей в каталоге оказалось 22000. Кстати, не каталог, а каталог. Где найти фотографии для всех этих людей? Ну знаете, то тут, то там. Есть, например, прекрасная библиотека, которая позволяет загружать картинки-результаты запроса из гугла. 22 тысячи человек — не так уж и много, используя 56 потоков нам удалось скачать фотографии для них меньше чем за час. Среди скаченных фотографий нужно отбросить битые, шумные, фотографии в неправильном формате. Затем оставить только те, где есть лица и где эти лица удовлетворяют определённым условиям: минимальному расстоянию между глаз, наклоном головы. Всё это оставляет нас с 12000 фотографий. Из 12 тысяч знаменитостей пользователи на данный момент обнаружили только 2. То есть существуют примерно 8 тысяч знаменитостей пока ещё ни на кого не похожих. Не оставляйте это просто так! Открывайте телеграм и найдите их всех. Как определить процент схожести для евклидовой дистанции? Отличный вопрос! Действительно, евклидово расстояние, в отличии от косинусного, не ограничено сверху. Поэтому возникает резонный вопрос, как показать пользователю нечто более осмысленное, чем "Поздравляем, расстояние между вашим эмбедингом и эмбедингом Анжелины Джоли составляет 0.27635462738"? Один из членов нашей команды предложил следующее простое и гениальное решение. Если построить распределение расстояний между эмбедингами, оно окажется нормальным. А значит, для него можно посчитать среднее и стандартное отклонение, а затем для каждого пользователя по этим параметрам считать сколько процентов людей менее похожи на своих знаменитостей, чем он. Это эквивалентно интегрированию функции плотности вероятности от Вот точная функция, которую мы используем:
Неужели нужно перебирать список всех эмбедингов, чтобы найти совпадение? Конечно нет, это не оптимально и занимает кучу времени. Простейший способ оптимизировать вычисления — использовать матричные операции. Вместо того, чтобы вычитать вектора один из другого, можно составить из них матрицу и вычитать из матрицы вектор, а затем посчитать L2 норму по строкам.
Это уже даёт гигантский прирост производительности, но, оказывается, можно ещё быстрее. Поиск можно значительно ускорить, немного проиграв в его точности, используя библиотеку nmslib. Она использует метод HNSW для приближенного поиска
Параметры
Параметр
В нашем случае Как сделать моего бота готовым к продакшену? 1. Асинхронность Для начала, необходимо сделать функцию
Теперь фреймворк сам запустит ваш обработчик в отдельном потоке в своём пуле. Размер пула задаётся при создании А теперь проанализируйте нашу функцию Я не упомянул 2. Многопроцессность Простейший способ разобраться с
3. Железо Если ваш бот должен постоянно читать фотографии с диска, позаботьтесь о том, чтобы этим диском был SSD. Или вообще смонтируйте их в оперативную память. Так же важен пинг до серверов телеграма и качество канала. 4. Flood control Телеграм не позволяет ботам отправлять больше 30 сообщений в секунду. Если ваш бот популярен и им одновременно пользуется куча народу, то очень легко поймать бан на несколько секунд, который обернётся разочаровнием от ожидания для множества пользователей. Для решения этой проблемы
Для её использования нужно определить собственного бота и подменить его при создании
5. Web hooks В продуктовом окружении в качестве способа получения обновлений от серверов Телеграма вместо Long Polling всегода стоит использовать Web Hooks. Что это вообще такое и как это использовать можно почитать здесь. 6. Мелочи Во время общения с сервером телеграма ежесекундно разбираются тонны тонны сообщений в формате Полезной мелочью стала настройка времени ожидания для всех блокирующих IO-операций: загрузки и отправки фотографий, отправки сообщений, получения обновлений. Его увеличение не сказалось на производительности, но сильно повысило стабильность бота и уменьшило число ошибок. 6. Аналитика Нельзя улучшить то, что нельзя измерить. Собирайте статистику по действиям пользователя при использовании бота, замеряйте время ответа, время ожидания, собирайте подробную информацию по каждой произошедшей ошибке. Так вы всегда сможете корректно оценивать пользовательский опыт, заранее замечать аварийные ситуации и быстро их исправлять. Мы, например, настроили импорт логов в наш BI-tool Splunk и постоянно следим за ситуацией. Вот и всё, о чём бы нам хотелось рассказать в этой статье. Мы вспомнили основы распознавания лиц, показали вам как создать собственного простого бота для распознавания лиц на основе открытых технологий и постарались кратко рассказать про создание нашего собственного бота. Автоматизируйте всё что автоматизируется, уделяйте время проектам для саморазвития и приходите домой пораньше. Ну и конечно же заходите посмотреть, что у нас получилось: @OkkoFaceBot. Источник: habr.com Комментарии: |
|