Как я делал нейросеть для оценки картинки с простеньких веб-камер
Наверняка многие, кто пытался сделать свою первую нейросеть, проходили на Kaggle челленж Cat vs Dog, в котором нужно научить компьютер отличать картинку с кошкой или собакой на дата-сете из 25 тысяч заранее размеченных изображений.
Примерно с таким «Kaggle-опытом» я взялся за свою первую боевую модель машинного обучения с нуля. И опыт получился интересным. Но обо всем по порядку.
Пролог. «Система, чем-то похожая на Тиндер»
Следить за качеством онлайн-уроков в Skyeng стали в 2015 году — так появился отдел контроля качества, в котором я работаю аналитиком. Задача нашего отдела — сделать так, чтобы все уроки проходили комфортно для ученика. Для этого мы выборочно анализируем аудио (это помогает понять, сколько времени говорят ученик и учитель и на каком языке), а также контролируем визуальную сторону занятия — оцениваем, насколько хорошо выглядят преподаватель, его фон и т.д.
В частности, в один момент мы поняли, что освещенность картинки с камеры преподавателя влияет на конверсию в следующую оплату.
Это не очень большие цифры, но тем не менее, тоже влияют на LTV. В образовании неспроста существуют нормы освещенности: это помогает в концентрации внимания. Есть вторая, менее научная, но не менее важная причина — эмоции. Когда ты разговариваешь с человеком, важно видеть его реакцию.
Поэтому вас не должны слушать с таким лицом (за картинку спасибо Malik Earnest)
В первые годы у нас получалось анализировать большую часть занятий вручную. Мы написали систему, которую окрестили «тиндером»: три скриншота урока отправлялись 3 разным асессорам, а они оценивали качество изображения:
- свайп влево — с картинкой что-то не то,
- свайп вправо — на уроке хорошее изображение.
Но школа росла. В 2019-м число одновременно проходящих уроков стало исчисляться сотнями. Ручной отсмотр покрывал примерно 5% занятий, а оценка «плохо» не давала знания, что именно не так. Нам важно было быстро понимать, не отвлекается ли преподаватель на гаджеты, общение с посторонними, прибрана ли комната, в которой он/она сидит, видно ли лицо целиком и учитывать еще с десяток факторов, которые влияют на восприятие и впечатления от занятий.
Мы решили автоматизировать процесс, обучив машину сразу «говорить», что именно плохо или хорошо в кадре. И, среди прочих параметров, определять тип освещения лица преподавателя.
Есть два типа людей 3 типа лиц
Кажется, в век инстаграма все уже привыкли к сочному изображению, но добиться такой же картинки от камер недорогих ноутбуков архисложно. И вот почему.
Качество картинки в частности зависит от того, сколько света попадает в объектив. А встроенные камеры во многих ноутбуках смотрят на общую экспозицию кадра. Пытаясь привести экспозицию к норме, камера не всегда обращает «внимание» на человека.
Так и получается, что если вы сядете спиной к окну, камера посчитает картинку слишком светлой и компенсирует экспозицию, превратив вас в темный силуэт.
Мы называем это underexposed.
Мы не стали использовать фото преподавателей из выборки: на примерах фигурируют наши пиарщики или модели с фотостоков.
У этого явления есть антипод: вы сидите в темноте и все, что освещает ваше лицо — это монитор. Думаю, вы догадались: камера посчитает картинку слишком темной и высветлит целиком, превратив лицо в белое пятно.
Знакомьтесь — overexposed.
Есть еще и «нормальный тип лица» — то есть, с освещенностью все хорошо.
Мне нужно было научить машину находить среди общей массы скриншотов с уроков проблемные.
Сами обеспечить всех камерами мы не можем. В случае 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 и правда существует: большую часть времени пришлось потратить на коммуникацию, подготовку и организационные вопросы, а не на саму модель. Но главное, что результат порадовал.