Наверняка многие, кто пытался сделать свою первую нейросеть, проходили на Kaggle челленж Cat vs Dog, в котором нужно научить компьютер отличать картинку с кошкой или собакой на дата-сете из 25 тысяч заранее размеченных изображений.



Примерно с таким «Kaggle-опытом» я взялся за свою первую боевую модель машинного обучения с нуля. И опыт получился интересным. Но обо всем по порядку.

Пролог. «Система, чем-то похожая на Тиндер»


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

В частности, в один момент мы поняли, что освещенность картинки с камеры преподавателя влияет на конверсию в следующую оплату.


Это не очень большие цифры, но тем не менее, тоже влияют на LTV. В образовании неспроста существуют нормы освещенности: это помогает в концентрации внимания. Есть вторая, менее научная, но не менее важная причина — эмоции. Когда ты разговариваешь с человеком, важно видеть его реакцию.

image

Поэтому вас не должны слушать с таким лицом (за картинку спасибо Malik Earnest)

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

  • свайп влево — с картинкой что-то не то,
  • свайп вправо — на уроке хорошее изображение.

Но школа росла. В 2019-м число одновременно проходящих уроков стало исчисляться сотнями. Ручной отсмотр покрывал примерно 5% занятий, а оценка «плохо» не давала знания, что именно не так. Нам важно было быстро понимать, не отвлекается ли преподаватель на гаджеты, общение с посторонними, прибрана ли комната, в которой он/она сидит, видно ли лицо целиком и учитывать еще с десяток факторов, которые влияют на восприятие и впечатления от занятий.

Мы решили автоматизировать процесс, обучив машину сразу «говорить», что именно плохо или хорошо в кадре. И, среди прочих параметров, определять тип освещения лица преподавателя.

Есть два типа людей 3 типа лиц


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

Качество картинки в частности зависит от того, сколько света попадает в объектив. А встроенные камеры во многих ноутбуках смотрят на общую экспозицию кадра. Пытаясь привести экспозицию к норме, камера не всегда обращает «внимание» на человека.

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



Мы называем это underexposed.
Кто на фото?
Мы не стали использовать фото преподавателей из выборки: на примерах фигурируют наши пиарщики или модели с фотостоков.

У этого явления есть антипод: вы сидите в темноте и все, что освещает ваше лицо — это монитор. Думаю, вы догадались: камера посчитает картинку слишком темной и высветлит целиком, превратив лицо в белое пятно.



Знакомьтесь — overexposed.
Кто на фото?
Мы не стали использовать фото преподавателей из реальной выборки: на примерах фигурируют наши пиарщики или модели с фотостоков. За это фото спасибо Alex Sheldon.

Есть еще и «нормальный тип лица» — то есть, с освещенностью все хорошо.

Мне нужно было научить машину находить среди общей массы скриншотов с уроков проблемные.

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

Сами обеспечить всех камерами мы не можем. В случае Skyeng многие преподаватели — подрядчики, а не сотрудники. Они могут в любой момент прервать или прекратить сотрудничество с нами. То есть, при всем желании, непонятно, как оформлять передачу техники, как обеспечивать ее возврат, ремонт и другие случаи. Плюс, банально, при кратном росте числа учеников (а следом — и преподавателей), как это уже бывало, это добавит заметную нагрузку на бюджеты и вызовет огромные сложности в логистике.

Как мы искали иголку в стоге скриншотов


На момент старта проекта у нас было довольно много материала — скриншоты, которые отправлялись асессорам отдела качества. Но их еще надо было разметить.

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



Так появился алгоритм компьютерного зрения на базе OpenСV.

Наш алгоритм выделял лицо человека на снимке и превращал снимок в черно-белый. Получая среднюю яркость лица и среднюю яркость остального снимка, можно определить проблему: если яркость лица больше, это overexposed — и наоборот.

Но у этого метода были свои проблемы.


Одной из проблем стали… стены. Например, если человек со светлым лицом сидел на фоне темной стены, то алгоритм автоматически считал лицо пересвеченным. И наоборот — сидеть на фоне белой стены мог только очень бледный человек. Иначе изображение считалось проблемным. У преподавателей со смуглой кожей алгоритм тоже регулярно обнаруживал несуществующие проблемы с яркостью.

В общем, OpenСV — не наш путь. Да и будучи классическим алгоритмом, он не всегда определял лицо на снимке. Но мы хотя бы сузили радиус поиска с миллионов скриншотов до нескольких десятков тысяч. Из них уже можно было формировать обучающую выборку, и для завершения проекта было решено:

  • провести ручную валидацию материала для разметки,
  • попробовать классические сверточные нейросети — кажется, они будут вести себя стабильнее в плане детекции лиц.

Нельзя просто так взять и получить 5К размеченных скриншотов


До этого я всегда работал с готовыми дата-сетами, поэтому процесс разметки представлял себе примерно. Казалось, все будет просто: сформулируем задачу, отдадим изображения асессорам, получим результат, натренируем модель — и готово.

Я взял где-то 50 тысяч скриншотов, описал задачу — и… за несколько дней мы получили всего 300 скриншотов в каждой категории, а также много обратной связи в духе «я не понимаю, что значит ваш overexposed». Плюс много, очень много полярных оценок для одних и тех же скринов.

Но материала уже хватало, чтобы сделать подобие MVP. Модель, несмотря на такую себе точность, схватывала нужные фичи. Чтобы повысить точность, нужно было больше материала. За первый раунд я понял, что: люди субъективны при оценке изображений, задачи разметки надо тоже формулировать по SMART, а мне стоит быть проще в формулировках).

Для второго подхода:

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

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

Материала для нейросети было уже достаточно — и я сделал модель на Resnet.


Обучил, подтянул параметры, поэкспериментировал с loss-ом, использовал разные штрафы, — модель хорошо себя показывала.

Все очень радовались, и помимо валидационного датасета, игрались с собственными фотками — загружали портреты себя за ноутами, чтобы убедиться, что модель работает как надо.

Как прогонять скриншоты через модель


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

Мы пользуемся инфраструктурой АWS, и одним из «очевидных» решений, которые советует и Amazon, и коллективный разум в интернете, стал SageMaker.


Быть или не быть...

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

У нас есть материал и нужно его как-то обрабатывать. Не должно быть ничего сложного.


Тратить дополнительное время, деньги и другие ресурсы не хотелось, поэтому мы арендовали ЕС2-виртуалку и написали простой пайплайн:

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

Сделали все простым и легким в поддержке.

Что в результате?


  • Я создал свою первую боевую модель, которая работает с 90% точности и покрывает все наши уроки.
  • Несколько моделей полностью заместили ручной труд, позволяют отслеживать массу важных с визуальной точки зрения вещей — присутствие человека в кадре, отсутствие гаджетов и посторонних людей, другие критерии. Среди прочего, мы получили инструмент работы с обратной связью от учеников.
  • А еще я понял, что правило 80 на 20 и правда существует: большую часть времени пришлось потратить на коммуникацию, подготовку и организационные вопросы, а не на саму модель. Но главное, что результат порадовал.