Распознавание лиц с использованием нейронных сетей. Нейронную сеть научили распознавать лица на видео по одной фотографии-образцу

В этот журнал я пишу обо всем, с чем сталкиваюсь впервые. В этот раз я поддался всеобщей истерии, и речь пойдет о сверточных нейронных сетях. Еще в этот раз я постараюсь подробно описать ход своих мыслей, а не просто перечислить результаты и способы их достижения. Поэтому будет "многа букаф".
Я очень долго сопротивлялся таким "грязным, искусственным" нейросетям, предпочитая "чистый, естественный" SVM. Серьезные пацаны уже давно решают проблемы используя сверточные нейронные сети. Нужна какая-то не сложная задача, желательно уже решенная мной в другой парадигме, чтобы опробовать на ней новую для меня технологию. Решено: распознаем лица. Для разогрева видео конечного продукта:
https://www.youtube.com/watch?v=mwDbGpAZdxU

Инструментарий

Как известно, нейронные сети обучаются намного эффективнее на GPU, чем на CPU. У меня нет десктопа с видеокартой. Благо, несколько лет назад покупая ноутбук, я купил игровой закладывался на то что мне понадобится освоить вычисления на GPU, и купил с видеокартой nvidia geforce gt 650m 2Gb. Итак, что я имел на момент начала работы: просто шикарный для новичка цикл статей machine learning is fun , определенный опыт в компьютерном зрении, материалы сайта face-rec.org . Нужно определиться с инструментарием. Конечно, это будет язык с++, библиотека компьютерного зрения opencv , а вот с фреймворком для распознавания лиц все оказалось сложнее. Оказалось, что OpenFace , используемый Адамом, написан на питоне и использует torch, который в свою очередь написан на lua. Мне принципиально нужно монолитное решение на с++. Быстро нашелся легковесный dlib в котором на тот момент имелся качественный детектор лиц, имелся инструментарий для работы со сверточными сетями, в том числе с использованием GPU, но не имелось функционала распознавания лиц. То что надо!
Начнем его разворачивать. Нужно скачать исходники и собрать с помощью cmake. Помучавшишь, разобрался, что для использования видеокарты, необходимо установить CUDA Toolkit и cuDNN с сайта Nvidia. Путь установки не должен содержать пробелов. Чтобы мой проект начал использовать dlib, я посмотрел параметры в тестовых примерах. Кроме списка библиотек, там нужно указать определение препроцессора DLIB_USE_CUDA и выставить параметры оптимизации. Также установил полезную утилиту GPUZ чтобы наблюдать за использованием видеокарты при обучении.

Прогнал несколько тестовых конфигураций нейросеток для известного датасета MNIST :


  • Двухслойный перцептрон обучался полчаса на одном ядре процессора Точность на обучающей выборке и на тестовой: (0.9908, 0.9792).

  • Сеть LeNet (Лекун) обучалась почти 6ч на одном ядре процессора а на видеокарте - 15 минут! Достигнутая точность (0.99975, 0.9915).

  • Сеть ResNet - 1ч и 15 минут на видеокарте, точность (0.9938).

  • Сеть Inception - около 4 часов на видеокарте, точность (0.999217, 0.9904).

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

Постановка задачи и первый вариант решения
Перейдем теперь к основной задаче. Я хочу построить достаточно надежный классификатор небольшой группы лиц (до 100 человек), опираясь на 3-5 фотографий каждого. Классификатор должен нормально "переваривать", очень вариативные изображения. Ведь в зависимости от угла обзора, условий освещения, наличия головного убора, очков, выражения лица будут получены очень разные изображения. Понятно, что при такой маленькой обучающей выборке (3-5 фото одной пероны) имеет смысл применять только линейный классификатор. И нужен очень качественный дескриптор, который мы применим предварительно, назначение которого подчеркнуть различия между фотографиями разных людей и сходства между разными фотографиями одного человека.

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


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

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


Первая конфигурация очень простая, на подобие Lenet , включает в себя пару сверточных слоев и три полносвязных:
static const size_t MINI_BATCH_SIZE = 128 ; //128; const unsigned long descriptor_size = 128 ; static const cv:: Size DATASET_IMAGE_SIZE = { 128 , 128 } ; //Сетка на подобие LeNet //LeCun, Yann, et al. "Gradient-based learning applied to document recognition." //Proceedings of the IEEE 86.11 (1998): 2278-2324. using net_type = dlib:: loss_multiclass_log < dlib:: fc < 2 , dlib:: fc < 128 , //!!!ТУТ ПРОПУСТИЛ RELU dlib::relu> >>> >>> >> >> > > > ;
Обучение выглядит следующим образом:

Std:: cout << "net initialization..." << std:: endl ; net_type net; //The code below uses mini-batch stochastic gradient descent with an initial learning rate of 0.01 to accomplish this. std:: cout << "trainer initialization..." << std:: endl ; dlib:: dnn_trainer < net_type> trainer(net) ; //dnn_trainer trainer(net, adam(0.0005, 0.9, 0.999), {0, 0, 0, 0}); trainer.set_learning_rate (0.01 ) ; //1e-3 trainer.set_min_learning_rate (MIN_LEARNING_RATE) ; trainer.set_mini_batch_size (MINI_BATCH_SIZE) ; trainer.be_verbose () ; trainer.set_synchronization_file ("lenet_faces_sync" , std:: chrono :: seconds (180 ) ) ; //Обучение std:: vector < dlib:: matrix < unsigned char >> mini_batch_samples; std:: vector < unsigned long > mini_batch_labels; dlib:: rand rnd(time (0 ) ) ; std:: cout << "traning..." << std:: endl ; while (trainer.get_learning_rate () >= MIN_LEARNING_RATE) { dataset.GetInputSamplePairBatch (mini_batch_samples, mini_batch_labels, MINI_BATCH_SIZE) ; win1.set_image (mini_batch_samples[ 0 ] ) ; win2.set_image (mini_batch_samples[ 1 ] ) ; trainer.train_one_step (mini_batch_samples, mini_batch_labels) ; } // When you call train_one_step(), the trainer will do its processing in a // separate thread. However, this also means we need to wait for any mini-batches that are // still executing. Calling get_net() performs the necessary synchronization. trainer.get_net () ; std<< std:: endl ; net.clean () ; //Очищаем сеть от вспомогательной информации dlib:: serialize ("lenet_faces.dat" ) << net; //И сохраняем ее. Для загрузки deserialize("lenet_faces.dat") >> net;

После окончания обучения сетка используется как дескриптор. На отдельной тестовой выборке обучается и тестируется линейный классификатор в пространстве векторов, полученных из откликов второго полносвязного слоя нейросети на пару изображений. В тестовой выборке порядка 1500 изображений для 15 разных персон. Обучение классификатора осуществляется на 5 изображениях на одну персону. Тестирование - на всех.
//Обучение классификатора std:: cout << "Traning classifier..." << std:: endl ; TSVMClassifier classifier({ cv:: ml :: SVM :: POLY ,2 ,2 } ) ; static const long NL = 5 ; long i = 0 ; std:: vector < long > isum (dataset.ClassNumber () ) ; cv:: Mat descr(1 , descriptor_size, CV_32FC1) , train_data(dataset.ClassNumber () * NL, descriptor_size, CV_32FC1) , train_classes(dataset.ClassNumber () * NL, 1 , CV_32SC1) , test_data(dataset.Size () , descriptor_size, CV_32FC1) , test_classes(dataset.Size () , 1 , CV_32SC1) , predicted_classes(dataset.Size () , 1 , CV_32FC1) , averaged = cv:: imread ("../AveragedMan.jpg" , CV_LOAD_IMAGE_GRAYSCALE) ; dlib:: matrix < unsigned char > averaged_dlib(DATASET_IMAGE_SIZE.height , DATASET_IMAGE_SIZE.width ) , sample_dlib; //Подготовка усредненного лица TFaceDetector FaceDetector("shape_predictor_68_face_landmarks.dat" ) ; std:: vector < dlib:: rectangle > face_rects = FaceDetector.Detect (averaged) ; dlib:: array < dlib:: matrix < unsigned char > > faces; FaceDetector.ExtractFaces (averaged, face_rects, faces) ; if (faces.size () == 1 ) resize_image(faces[ 0 ] , averaged_dlib) ; dlib:: image_window win; //Обучаем на 5 объектах каждого класса, а тестируем на всех for (unsigned long idx = 0 ; idx < dataset.Size () ; idx++ ) { try { sample_dlib = dataset.GetSample (idx) ; win.set_image (sample_dlib) ; std:: cout << dataset.GetLabelIdx (idx) << " " << dataset.GetLabelByIdx (dataset.GetLabelIdx (idx) ) << std:: endl ; } catch (exception & e) { TException * E = dynamic_cast < TException * > (& e) ; if (E) std:: cout << E- > what() << std:: endl ; else std:: cout << e.what () << std:: endl ; continue ; } ; net(dataset.MakeInputSamplePair (& averaged_dlib, & sample_dlib) ) ; for (unsigned long iv = 0 ; iv < dlib:: layer < 2 > (net) .get_output () .size () ; iv++ ) descr.at < float > (iv) = dlib:: layer < 2 > (net) .get_output () .host () [ iv] ; descr.copyTo (test_data.row (idx) ) ; test_classes.at < long > (idx) = (long ) dataset.GetLabelIdx (idx) ; if (isum[ test_classes.at < long > (idx) ] < NL) { //train_data.push_back(descr); //train_classes.push_back(test_classes.at(idx)); descr.copyTo (train_data.row (i) ) ; train_classes.at < long > (i) = test_classes.at < long > (idx) ; isum[ test_classes.at < long > (idx) ] ++ ; i++ ; } } std:: cout << train_data.cols << " " << train_data.rows << " " << train_classes.cols << " " << train_classes.rows << std:: endl ; classifier.Train (train_data, train_classes) ; classifier.Save ("classifier.txt" ) ; //Тестирование линейного классификатора std:: cout << "Testing linear classifier..." << std:: endl ; classifier.Predict (test_data, predicted_classes) ; unsigned long num_right = 0 , num_wrong = 0 ; for (unsigned long idx = 0 ; idx < dataset.Size () ; idx++ ) if (test_classes.at < long > (idx) == (long ) predicted_classes.at < float > (idx) ) num_right++ ; else num_wrong++ ; std:: cout << "training num_right: " << num_right << std:: endl ; std:: cout << "training num_wrong: " << num_wrong << std:: endl ; std:: cout << "training accuracy: " << num_right/ (double ) (num_right+ num_wrong) << std:: endl ; std:: cin >> c;

Сам процесс обучения выглядит вот так:


Видно, что загрузка видеокарты, как и процессора минимальна. Возможно ли ускорить вычисления используя имеющиеся ресурсы более полно? Обрабатывалось порядка 10 пар в секунду. Узким местом стало даже не чтение с диска, как я предполагал а детектирование лиц. Был вариант заранее пройтись детектором по всем изображениям и сохранить результат на диск, и дальше уже работать с ним. Но этот вариант мне не понравился тем, что на диске придется хранить две здоровенные базы, так как детектор я могу в будущем поменятьи вынужден хранить "сырые" необработанные изображения. Есть еще вариант кэширования. Вся выборка разбиватеся на блоки, умещающиеся в оперативной памяти. Выбираем случайным образом блок и обучаемся на случайных его подмножествах изображений до тех пор, пока каждое изображение не будет использовано n раз. Затем переключаемся на следующий блок. Таким образом можно уменьшить количество чтений с диска в n раз.

Распараллелил детектирование лиц используя пул потоков из той же библиотеки dlib, получил выигрыш по времени в 5-6 раз.
struct TR { TDataset * Dataset; bool Positive; dlib:: matrix < unsigned char > SamplePair; unsigned long Label; } ; ... if (UseMultiThreading) { std:: vector < TR> trv; std:: vector < dlib:: future < TR>> fv(batch_size) ; for (unsigned long i = 0 ; i < batch_size; i++ ) { trv.push_back (TR() = { this , positive} ) ; fv[ i] = trv[ i] ; //Можно, конечно же обойтись и без всяких лямбд ThreadPool- > add_task_by_value( (TR & val) { val.Dataset - > GetInputSamplePair(val.Positive , val.SamplePair , val.Label ) ; } , fv[ i] ) ; positive = ! positive; } ; //Каждому потоку нужен свой экземпляр детектора, потому что может быть разного размера и тд. ThreadPool- > wait_for_all_tasks() ; for (unsigned long i = 0 ; i < batch_size; i++ ) { batch_sample_pairs.push_back (fv[ i] .get () .SamplePair ) ; batch_labels.push_back (fv[ i] .get () .Label ) ; //batch_sample_pairs.push_back(tfv[i].SamplePair); //batch_labels.push_back(tfv[i].Label); } ; } else { for (unsigned long i = 0 ; i < batch_size; i++ ) { GetInputSamplePair(positive, sample_pair, label) ; batch_sample_pairs.push_back (sample_pair) ; batch_labels.push_back (label) ; positive = ! positive; //Чередуем положительные и отрицательные примеры } ; }

Теперь процесс обучения выглядит так:

Судя по загрузке процессора, GPU и жесткого диска, существенно ускорить теперь получится только заменой железа.

P.S. Ненавижу Livejournal за ограничение размера статей. Частично поэтому запускаю свой сайт delirium.su , где планирую, помимо прочего, вести полную версию блога.

Решетневские чтения. 2017

РЕШЕНИЕ ЗАДАЧ РАСПОЗНАВАНИЯ ЛИЦ И МИМИКИ С ПОМОЩЬЮ СВЕРТОЧНЫХ НЕЙРОННЫХ СЕТЕЙ

Д. В. Плотников*, Е. А. Сопов

Сибирский государственный университет науки и технологий имени академика М. Ф. Решетнева Российская Федерация, 660037, г. Красноярск, просп. им. газ. «Красноярский рабочий», 31

Е-шаП: [email protected]

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

Ключевые слова: сверточная нейронная сеть, распознавание лиц, распознавание мимики.

SOLVING THE FACE AND FACIAL EXPRESSION REGOGNITION TASKS USING CONVOLUTIONAL NEURAL NETWORKS

D. V. Plotnikov*, E. A. Sopov

Reshetnev Siberian State University of Science and Technology 31, Krasnoyarsky Rabochy Av., Krasnoyarsk, 660037, Russian Federation Е-mail: [email protected]

This paper performs experimental research of convolutional neural networks performance operated with face and facial recognition tasks.

Keywords: convolutional neural network, face recognition, facial expression recognition.

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

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

В качестве тестовых задач были выбраны следующие: «The ORL Database of Faces» и «The Facial Expression Recognition 2013».

База данных «The ORL Database of Faces». Первой тестовой задачей послужила проблема распознавания лиц. База данных представляет собой 400 фотографий сорока разных людей (рис. 1). Все фото представлены в градации серого. Формирование тестовой выборки происходит следующим образом: необходимо случайным образом выбрать по одной фотографии каждого человека. Разрабатываемый алгоритм должен на основе 360 обучающих фотоснимков классифицировать остальные 40, т. е. определить людей, изображенных на них.

База данных «The Facial Expression Recognition 2013». Второй тестовой задачей послужила проблема распознавания эмоций. БД представляет собой набор изображений людей с разными выражениями лиц. Человек на изображении может быть: сердитый, испытывающий отвращение, испытывающий страх, счастливый, грустный, удивленный или спокойный.

Рис. 1. Примеры фотографий, взятые из БД «The ORL Database of Faces»

Математические методы моделирования, управления и анализа данных

Рис. 2. Примеры фотографий, взятых из БД «The Facial Expression Recognition 2013»

Структура сверточной нейронной сети для работы с «The ORL Database of Faces»

Номер слоя Слой Параметры

Количество ядер Размер ядер Функция активации

1 Сверточный слой 1 20 5x5 Гиперболический тангенс

3 Сверточный слой 2 50 5x5 Гиперболический тангенс

Размер свертки Функция свертки

2 Субдискретизирующий слой 1 2x2 Функция максимума

4 Субдискретизирующий слой 2 2x2 Функция максимума

Количество нейронов Функция активации

5 Полносвязный слой 1 500 Гиперболический тангенс

6 Полносвязный слой 2 40 Гиперболический тангенс

Структура 1 Структура 2

Рис. 3. Динамика эффективности обучения CNN (Структура 1 и Структура 2)

Выборка состоит из 28709 обучающих и 7178 тестовых примеров. Каждое изображение имеет разрешение 48x48 пикселей.

Результаты экспериментов. База данных «The ORL Database of Faces». С принципом устройства работы CNN можно ознакомиться в .

В ходе работы также были использованы и другие структуры для работы с базой данных «The ORL Database of Faces». Однако они оказались неэффективны. С одной стороны, более сложные и ресурсоемкие для вычислений конфигурации не показывали лучший результат. А более простые структуры - не могли быть обучены вообще. Таким образом, наилучшим образом обученная структура достигает эффективности классификации 97,5 %.

База данных «The Facial Expression Recognition 2013». Поскольку размерность данной задачи сравнительно велика, принято решение уменьшить размерность (до 28x28). В данном случае на вход нейронной сети будет подано изображение меньшей размерности. Практика показала, что время обучения CNN при входных изображениях 48x48 пикселя в 4 раза дольше, чем при входных изображениях 28x28 пикселя. Более того, динамика обучения сети остается почти неизменной.

Следующий этап - проверка гипотезы о том, что значения гиперпараметров CNN влияют на скорость

обучения. Для решения задачи использовались две структуры: Структура 1 - идентична той, что была использована для работы с БД «The ORL Database of Faces».

Структура 2 - это Структура 1 с увеличенными значениями гиперпараметров (теперь количество ядер первого сверточного слоя = 50, второго сверточного слоя = 125) (рис. 3).

На рис. 3: ось абсцисс - итерации обучения сети, ось ординат - точность обучения. Видно, что на 125 итерации Структура 1 достигает своего уровня стагнации, в то время как Структура 2 продолжает увеличивать точность распознования.

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

Данное направление и будет являться объектом дальнейших исследований.

PewemHeecKye umeHUH. 2017

1. Face recognition: a convolutional neural-network approach / S. Lawrence, C. L. Giles, Ah Chung Tsoi, and A. D. Back // IEEE Trans. Neural Networks. 1997. Vol. 8, № 1. P. 98-113.

2. Krizhevsky A., Sutskever I., Hinton G. E. ImageNet Classification with Deep Convolutional Neural Networks, Adv. Neural Inf. Process. Syst. 2012. P. 1-9.

3. LeCun Y., Boser B., Denker J. S. et al. Backpropa-gation Applied to Handwritten Zip Code Recognition. Neural Comput. 1989. № 1 (4). P. 541-551.

4. Lin M., Chen Q., Yan S. Network In Network. arXiv Prepr. 2013:10.

5. Sopov E., Ivanov I. Design efficient technologies for context image analysis in dialog HCI using self-configuring novelty search genetic algorithm. Informatics Control Autom Robot (ICINCO), 2014. 11th Int Conf. 2014. № 2. P. 832-839.

© nn0THHK0B fl. B., ConoB E. A., 2017

Российские ученые предложили новый метод распознавания людей на видео с помощью глубокой нейронной сети. Подход не требует большого числа фотографий, он позволяет значительно повысить точность распознавания по сравнению с ранее известными аналогами, даже если доступна всего одна фронтальная фотография человека. Результаты работы опубликованы в журналах Expert Systems with Applications () и Optical Memory and Neural Networks ().

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

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

В качестве тестовой базы исследователи использовали несколько традиционных наборов данных для оценки методов распознавания лиц на видео – IJB-A (IARPA Janus Benchmark A) и YTF (YouTube Faces). Эти наборы включают в себя находящиеся в свободном доступе изображения известных людей (актеров, политиков, общественных деятелей), которые собирались из открытых источников в неконтролируемых условиях в разное время. Алгоритм должен был распознать лица на видео с YouTube, используя в качестве образцов несколько фотографий тех же людей из другого набора данных – LFW (Labeled Faces in the Wild). В LFW использовалось более высокое разрешение, а сами фотографии были сделаны в разное время, начиная с 1970-х до 2010-х годов.

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

«Алгоритм оценивает, насколько один кадр ближе к одному человеку, другой - к другому. Затем сравнивает, насколько похожи эти два человека между собой. После чего добавляет третьего человека и оценивает, с кем он ближе - с первым или вторым. Исходя из этой близости, еще раз корректирует ошибки распознавания», - говорит профессор Савченко.

Исследователи ВШЭ предложили новый метод распознавания людей на видео с помощью глубокой нейронной сети. Подход не требует большого числа фотографий, он позволяет значительно повысить точность распознавания по сравнению с ранее известными аналогами, даже если доступна всего одна фронтальная фотография человека. Результаты работы опубликованы в статьях «Fuzzy Analysis and Deep Convolution Neural Networks in Still-to-video Recognition » и «Unconstrained Face Identification Using Maximum Likelihood of Distances Between Deep Off-the-shelf Features ».

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

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

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

«Сеть может со 100% точностью распознать, например, известного актера (число изображений которого в сети исчисляются миллионами). Но это совсем не значит, что при переносе знаний, накопленных в нейронной сети, она адаптируется и распознает человека, для которого в качестве образца доступна только одна фотография», - поясняет профессор кафедры информационных систем и технологий НИУ ВШЭ в Нижнем Новгороде Андрей Савченко.

Для того, чтобы решить эту задачу, исследователи ВШЭ использовали теорию нечетких множеств и теорию вероятности. Они разработали алгоритм, который позволяет существенно повысить точность (на 2-6% по сравнению с ранее проведенными экспериментами) идентификации лиц по видео в режиме реального времени при наличии ограниченного числа изображений. Это решение работает с нейросетевыми архитектурами VGGFace, VGGFace2, ResFace и LightCNN.

В качестве тестовой базы исследователи использовали несколько традиционных наборов данных для оценки методов распознавания лиц на видео – IJB-A (IARPA Janus Benchmark A) и YTF (YouTube Faces). Эти наборы включали находящиеся в свободном доступе изображения известных людей (актеры, политики, общественные деятели), которые собирались из открытых источников в неконтролируемых условиях в разное время. Алгоритм должен был распознать лица на видео с YouTube, используя в качестве образцов несколько фотографий тех же людей из другого набора данных – LFW (Labeled Faces in the Wild). В LFW использовалось более высокое разрешение, а сами фотографии были сделаны в разное время, начиная с 1970-х до 2010-х годов.

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

«Алгоритм оценивает насколько один кадр ближе к одному человеку, другой - к другому. Затем сравнивает, насколько похожи эти два человека между собой. После чего добавляет третьего человека и оценивает, с кем он ближе - с первым или вторым. Исходя из этой близости, еще раз корректирует ошибки распознавания», - говорит профессор Савченко.

Сейчас этот алгоритм уже реализован для стационарных компьютеров на Python, что позволяет в фотоальбомах находить и группировать лица разных людей, оценивать год рождения, пол и другие параметры. Разработан прототип приложения для Android, которое определяет возраст и пол людей на фотографиях и видео. Анализ фото-галереи дает возможность автоматически оценить степень социальной активности пользователя, выделить его близких друзей и родственников. Для современных смартфонов прототип приложения обрабатывает 15 кадров в секунду. Исследователи утверждают, что благодаря разработанному алгоритму распознание лиц может происходить точнее.

Поиск одежды по фото с телефона - это для девочек, скажете вы. Это не для серьёзных айтишников, скажете вы. И вообще, где высоконаучные технологии, а где ммм… мир ванильной моды и гламура?

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

Но какое-то время спустя, изучая мировую статистику по визуальному поиску, онлайн- и мобильной коммерции, общим тенденциям на мировом рынке ритейла, мы поняли, что интерес бизнеса к мобильному распознаванию одежды, обуви и аксессуаров (внутри команды мы называем это общим словом fashion) быстро растёт.

Проиллюстрируем.

Немного цифр

Индустрии одежды, моды и предметов роскоши – рынок очень перспективный. Маркетологи и финансисты McKinsey в своём исследовании утверждают, что в период между 2014 и 2020 годами темпы роста мировой индустрии одежды будут выражаться двузначными числами. Причём рост будет происходить за счёт развивающихся рынков (Россия, конечно, тоже сюда относится) и в значительной степени за счёт азиатских покупателей (урбанизация Китая по темпам сейчас в 10 раз превосходит аналогичный процесс в Великобритании в 19 веке).

Если говорить только о рынке женской одежды, то в ближайшие 12 лет его рост составит свыше 50% про всему миру (согласно исследованию McKinsey – Unleashing Fashion Growth City by City).

С одеждой разобрались. Поняли, что рынок растёт – значит, тут есть возможности для развития технологий. Хорошо.

Дальше мы стали изучать тенденции онлайн-шоппинга. Заглянули в Америку. В 2015 году 205 миллионов американцев (при населении 325 миллионов – то есть это больше 60%) хоть раз искали товары в интернете, сравнивали цены или покупали что-то онлайн. Ожидается, что к 2019 году что эта цифра достигнет 224 миллионов.

Похожая тенденция наблюдается и глобально: в исследовании к конференции ООН по торговле и развитию (United Nations Conference on Trade and Development) говорится , что к 2018 году около 1,623 миллиардов человек по всему миру будут покупать товары и услуги в интернете (сравнить с 1,039 миллиардов в 2013).

При этом интересно проследить, что сегмент мобильной коммерции (то есть покупок, сделанных с мобильных устройств) тоже растёт. В одной только Америке, по прогнозам eMarketer, доходы мобильного ритейла к 2018 достигнут 130.12 миллиардов долларов (с 56,67 миллиардов долларов в 2014) – это более чем в два раза.

Мировая тенденция к «мобилизации» онлайн-покупок тоже очевидна. Goldman Sachs опубликовали отчёт, согласно которому за 5 лет сегмент м-коммерции с точки зрения числа пользователей вырастет в 5 раз: с 379 миллионов пользователей в 2013 до более 1 миллиарда покупателей в 2018 (надо заметить, что в отчёте не учитываются онлайн-покупки в сегменте «Путешествия»).

Одежда, надо сказать, согласно исследованиям Nielsen, – наиболее часто покупаемая в онлайне категория. С ней соревнуются только книги, канцелярия и музыка.

По сути, происходит вот что: к нашему времени рынок интернет-доступа достиг своей точки насыщения, прирост пользователей значительно замедлился (прогнозируется на уровне 5-10% в последующие годы). Рост рынка смартфонов тоже стремится к нулю.

Посмотрите, например, презентацию выступления Марка Цукерберга на конференции Facebook F8.

Это значит, что интернет и рынок смартфонов стали тем, что называется commodity, товарами массового спроса, частью повседневности. А вот покупки через мобильные устройства – это новые паттерны поведения, которые дают пространство для развития новых технологий.

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

Как и зачем учить систему распознавать платья?

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

Иными словами, пользовательские ожидания от работы сервиса можно свести к трём шагам: увидел – сфотографировал – купил.

Чтобы разработать и построить такую систему, нам пришлось обработать более 30 000 000 изображений, понять разницу между пуловером и джемпером (есть ещё свитера и кофты, и это всё разные вещи), ботинками дерби и монки, сумками дафл и тоут, открыть свою «кунсткамеру», арендовать манекены, почувствовать себя юными (ну не совсем юными, ладно) модельерами – и много чего ещё. Но обо всём по порядку.

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

Нейрон – это отдельный вычислительный элемент сети; каждый нейрон связан с нейронами предыдущего и следующего слоёв сети. Когда на вход поступает изображение, видео- или аудиофайл, оно последовательно проходит обработку всеми слоями сети. В зависимости от результатов, сеть может изменить свою конфигурацию (параметры каждого нейрона).

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

Шаг 1: Узнать о моде всё

Итак, с технологической точки зрения система должна работать в такой последовательности: анализ загруженного фото системой – выделение областей, потенциально содержащих товар – определение категории товара – отделение объекта от фона – создание цифрового отпечатка (digital fingerprint) изображения товара – поиск похожих товаров в заданной категории.

Первым пунктом в R&D-плане стало создание правильной, полной и точной классификации моды.

Начать мы решили с классификации обуви. Причём женской – нам показалось, что это проще (стоило сразу перекреститься, наивные глупцы). Поняли: чтобы система могла правильно распознавать категории, нам нужна подробная классификация видов women shoes. В ход пошли Википедия, толковые словари, сайты обувных онлайн-магазинов и картинки из Google типа такой:

Параллельно с поиском изображений по категориям и разметкой мы завели внутреннюю папку «Кунсткамера», которую стали пополнять примеры необычной (а то и откровенно странной) обуви, часть из которой хотелось сразу «развидеть». К примеру, у нас есть такие экспонаты:

Такие изображения для обучения сети мы, понятно, не брали. Это для себя – «чисто, чтобы поржать» (с).

А мы поняли, что существует обувь «унисекс». Например, такие категории обуви, как эспадрильи, мокасины или тимберленды внешне могут быть очень похожи – как у мужчин, так и у женщин.

Всего в унисекс мы отнесли 10 категорий.

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

Первое – это сама по себе классификация. Какие именно категории выделять? Не будут ли они слишком мелкими? Или, наоборот, излишне укрупнёнными?

Тут нам помогала структура каталогов наших конечных клиентов – интернет-магазинов. Мы брали за основу их категоризацию, приводя её к тому виду, что могла удовлетворить нашим требованиям (быть универсальной для российских и американских магазинов, не слишком общей и не слишком подробной).

Второе – спорность в отнесении некоторых товаров к определённой категории. Например, что это? Ботильоны или кроссовки?

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

Третье – детальность классификатора. Иногда приходилось «занудничать» и для более точного поиска выделять дополнительные категории, не всегда коррелирующие с категориями магазинов (не путать с фильтрами поиска!), чтобы добиться лучших результатов распознавания.

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

Четвёртое – сложность с подбором картинок в некоторые категории. Было время, когда, например, изображения топсайдеров можно было найти только на зарубежных ресурсах – в наших магазинах эта обувь ещё не была широко представлена.

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

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

Для пробы сделали 2 категории: «Замшевые сапоги» и «Кожаные сапоги» (они, разумеется, пересекаются с другими категориями – высокие сапоги, сапоги на танкетке и прочими). Сеть распознаёт их правильно. Но разделять все типы обуви по материалу на непересекающиеся категории мы в итоге не стали – было бы излишне. А эти две «исторически сложившиеся» категории оставили. Правильной работе они не мешают.

В общем, после того, как мы подготовили классификатор обуви, мы стали считать себя чем-то вроде микса из Александра Васильева, Вячеслава Зайцева и Валентина Юдашкина.

Наша внутренняя переписка

Затем по такому же принципу мы стали выделять женские и мужские сумки, а после – женскую и мужскую одежду.

Шаг 2: Обучить нейронные сети отличать монки от лоферов, а пуловер от джемпера

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

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

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

Скачивание картинок для обучения ведётся наполовину автоматически нашими внутренними алгоритмами, наполовину вручную. После массив фотографий проверяется, чтобы не было дублей и случайных неподходящих картинок. Далее все файлы приводятся к единообразным названиям и одному формату (расширению).

А потом начинается самое сложное: ручная разметка товаров на картинке. Наши сотрудники на фотографии обводят рамкой товар и определяют его категорию.

Например:

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

С чем тут бодались

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

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

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

Вот как выглядит наш fashion-классификатор на примере женской обуви (одна из страниц):

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

Вообще надо сказать, что сетями занимаются очень многие. Это акулы интернет-рынка: «Яндекс» (например, их недавняя фича для Auto.ru -распознавание марки и модели авто по изображению), Microsoft (сервис What-Dog.net , определяющий породы собак по фото), Mail.ru и Facebook (подразделение Facebook AI Research), и, понятно, Google. Но также это и молодые стартапы (только те, у которых достаточно средств на вычислительные мощности).

Усердно сети изучают в технических вузах по всему миру, в частности, в МФТИ Возможно, вы сейчас тоже захотели заниматься сетями. Круто!

Тогда сразу озвучим два момента, к которым нужно быть готовыми.

Ещё раз проговорим, что немаловажная часть технологии – это обучающие данные. Это первое «но». Чтобы сеть умела успешно различать один вид объекта, необходимо собрать несколько тысяч примеров этого объекта, на которых провелось бы обучение. Зачастую количество объектов исчисляется сотнями. Итоговые обучающие базы данных могут насчитывать сотни тысяч, миллионы объектов.

Поэтому подготовка базы – это очень трудоёмкий процесс. К нам приходят иногда стартапы, говорят, вот, хотим сделать распознавание, как у Pinterest, со ссылками на товары из Amazon. «Классно, – говорим мы, –можно устроить. Но надо много картинок на каждый товар, чтобы сеть работала. Сможем собрать?». После этого заказчики почему-то растворяются в пространстве.

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

По аппаратной части тоже виден прогресс – существуют высокопроизводительные видеокарты, позволяющие обучать и использовать сети в несколько сотен раз быстрее.

И второе – хранение и обработка больших массивов данных требует значительных вычислительных мощностей и средств на инфраструктуру. Для обучения и работы сетей нужны карты минимум с 3-4 Гб памяти, а для некоторых архитектур требуются и все 11 гигов. Карточки недешёвые: на один небольшой проект уходит карта стоимостью примерно 100 000 рублей. Плюс требуется много дискового пространства под сами данные.

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

Так, с нашей бумагой по мобильному распознаванию в сфере fashion мы прошли в финал KDD , крупнейшей конференции в мире в области Knowledge Discovery and Data Mining. Текст доклада доступен по ссылке .

Мы продолжаем пахать развивать технологию.

Вконтакте