Хабрахабр

Как мы заменили спортивного скаута нейронной сетью


Да, действительно, мы смогли заменить нейронной сетью спортивного скаута и стали автоматически собирать данные об игре. И теперь знаем о спортивном состязании больше присутствующего на нем зрителя, а иногда и судьи.
Мы (Constanta) специализируемся на разработке букмекерских IT-продуктов: мобильных приложений, сайтов и в последнее время развиваем проекты в области компьютерного зрения и машинного обучения. Об одном из них и пойдет речь.

Для этого спортивные скауты непосредственно на игровых площадках собирают и передают с помощью специального приложения на смартфоне большой объем данных. Пока спортсмены сражаются за большие и маленькие победы, букмекеру нужно в режиме реального времени знать ход событий, чтобы пересчитывать коэффициенты, по которым, собственно, и принимаются ставки. Наша цель – свести их к минимуму, попутно увеличив объем и оперативность сбора и передачи данных, плюс — снизить себестоимость всей этой работы. Скаут – такой же человек, как все мы, поэтому естественным образом возникают связанные с человеческим фактором риски. Мы решили, что интереснее сразу строить систему для игры с большим количеством взаимодействующих шаров, как в бильярде. Летает маленький шарик над теннисным столом или мяч по футбольному полю — техническая сторона реализации системы компьютерного зрения для сбора данных не имеет концептуальных отличий.


Мне нужны координаты и скорости всех твоих шаров и твоего кия.

Отсюда вытекают высокие требования к надежности работы компонентов, отвечающих за определение этих событий. Заметим, что при анализе многих спортивных игр для правильного определения результата необходимо безошибочно отследить цепочку событий. Матч продолжается до пяти побед одного из игроков, то есть всего происходит от 5 до 9 розыгрышей, в среднем 7. Поясним на простом примере: если в бильярде в среднем игроки закатывают все шары в лузы за 20 ударов, то при надежности определения исхода удара 99% вероятность определить победителя в розыгрыше составляет всего около 82% (0,9920≈0,817). А ведь изначально вероятность ошибки составляла лишь 1%! Таким образом, в среднем при такой надежности определения событий правильный результат матча получается с вероятностью всего лишь около 24% (0,8177≈0,24).

Пул “девятка”

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

Компьютерное зрение

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


Пример кадра видеопотока, обрабатываемого системой.

Это классическая задача компьютерного зрения, состоящая в том, что алгоритм должен отнести пиксели изображения к одному или нескольким классам. Ключевой этап обработки видеопотока нейронной сетью — семантическая сегментация. Нейронная сеть выдает “маски”, выделяя пиксели, относящиеся, например, к шару или игроку. Проще говоря, на видеокадрах необходимо определить, что есть что. По ним после сглаживания фильтром для каждого шара определяются скорость и траектория движения. Пройдя через серию постпроцессинговых алгоритмов “маски” шаров превращаются в координаты. Полученные данные отправляются в модуль обработки правил, который реализует всю логику игры. На этом этапе отслеживаются низкоуровневые, или промежуточные, события, такие как столкновения шаров между собой и с бортами стола. букмекеру, высокоуровневые события: забивание шаров в лузы, фолы, переходы ходов и, собственно, результат игры. Он в итоге и выдает конечному потребителю, т.е.


Общая схема системы.

Еще один важный участник действия — кий, именно он определяет направление удара и, соответственно, траекторию движения битка. Для решения задачи в первую очередь необходимо найти местоположение стола на кадре и всех шаров на нем. С точки зрения анализа игры они представляют собой “посторонние предметы”, как и подставка для шаров, а также мобильные телефоны, перчатки, салфетки и прочие вещи, которые по воле игроков появляются на бортах стола. Над столом наклоняются игроки, частично закрывая его от камеры. При этом каждый шар представлен отдельным классом в зависимости от его цвета. Таким образом, получается несколько целевых классов для семантической сегментации изображений: стол, его борта, лузы, кий, посторонние предметы и, разумеется, шары.

Она относительно быстро работает и хорошо зарекомендовала себя в различных “боевых” задачах конкурсов по компьютерному зрению. Для семантической сегментации используется полностью сверточная нейронная сеть с архитектурой LinkNet-34. Для определения перечисленного выше множества классов используется всего одна нейронная сеть, решающая все задачи компьютерного зрения.

arXiv).
Архитектура сети LinkNet-34 (см.

“Маски-предсказания” представляют собой двумерные массивы чисел со значениями от 0 до 1. На вход подаются изображения, а на выходе получается стопка “масок” всех требуемых классов. Для итоговой классификации пикселей полученные предсказания бинаризируются пороговым фильтром. Величина каждого элемента “маски” соответствует уверенности сети в том, что соответствующий пиксель относится к классу данной “маски”.

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

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

Быстро, быстрее, еще быстрее…

Конечному потребителю данных информация нужна в реальном времени (а еще лучше — быстрее риал-тайм). Для ускорения работы нейронной сети применено несколько техник, таких как объединение пакетной нормализации с 2D-сверткой (BatchNorm Fusion), что позволяет получить эквивалентную сеть без нескольких слоев. Хороший результат дает также подготовка и загрузка нового кадра параллельно с обработкой предыдущего на видеокарте. Помимо этого, на gpu выполняется часть подготовительных операций с кадрами и постобработки “масок”. Сократить суммарное время на обработку каждого кадра помогла даже простая идея — переносить результат работы сети с видеокарты в оперативную память после бинаризации в виде uint8 вместо получаемого из сети float32.

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

А было ли столкновение?

Координаты шаров мы определяем по “маскам”, но предварительно нужно исключить то, что лишь напоминает шар, например круглые нашивки на футболках игроков. Тут в дело вступают эвристики: проверяется форма и размер шаров, их положение относительно прошлого, хорошо известного. Далее, если с “маской” все в порядке, для обработки берется ее центроид.


Игрок в бильярд в страшных снах разработчиков.

Объяснение простое — “зашумленность” реального видео, артефакты сжатия видеопотока, что вместе с погрешностью в определении положения смазанных изображений движущихся шаров приводит к необходимости сглаживать полученные результаты. На первый взгляд странно, но факт — результат определения положения шаров может отличаться между кадрами даже при неподвижных шарах.

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

Синим цветом изображены результаты измерений, красным — результат фильтрации.
Демонстрация сглаживания определения положения и скорости шаров фильтром Калмана.
Слева: Raw: результат прямого измерения, векторы у шаров соответствуют скорости, цифры — обозначают оценку величины скорости; UKF: результат работы фильтра.
Справа: пример сглаживания направления скорости шара фильтром Калмана. Резкие скачки направления соответствуют столкновениям шара.

Данные о состоянии и траектории шаров позволяют определить наступление так называемого низкоуровневого события, даже когда оно попало “между кадрами”.

Поэтому для всех типов взаимодействий (столкновение шаров между собой, с бортом или попадание в лузу) вначале строится список возможных событий. Шары во время удара перемещаются так быстро, что зачастую нет кадра, на котором видно непосредственно событие, например, столкновение шаров. Во-первых, критически близкое взаимное расположение шаров. Критериев здесь два. Во-вторых, при большой скорости движения шаров возможные события определяются по пересечению траекторий, полученных из динамической модели. При медленном перемещении возникает большая относительная погрешность в определении скорости и траектории, поэтому важно расстояние между взаимодействующими объектами. Такой подход дает весьма приятный бонус: возможность немного заранее предсказать вероятное попадание шара в лузу.

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

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

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

Так мы играем или нет?

Шары катятся, сталкиваются, попадают в лузы… А идет ли на самом деле в этот момент игра? Или, напротив, все на столе кажется незыблемо… Значит игра остановилась? Правильный ответ на эти вопросы, вероятно, так же важен, как и определение столкновений. Когда игрок готовится к удару, обдумывает его, целится, движения нет. Но бывает и наоборот, в неигровые моменты жизнь на столе может идти весьма динамично: забитые шары перемещают из одной лузы в другую, биток могут катать по столу при его установке после фола, причем делают это в том числе кончиком кия (очень похоже на удар!). Если окончание текущего удара легко можно определить — после корректного удара все шары перестают двигаться, то с началом все не так однозначно. Конечно, можно обучить нейронную сеть обнаруживать события в видео, в том числе и настоящие удары кия по битку. А можно составить набор эвристик, которые анализируют положение и угол кия, траекторию и скорость его концов и траекторию битка после предполагаемого удара. Мы пошли вторым путем, и в результате получился очень быстрый и надежный алгоритм, определяющий текущее состояние игры.


Система пытается понять, началась игра или нет.

И кто в итоге выиграл?

Все данные о низкоуровневых событиях (удар по битку, положения и столкновения шаров, попадания в лузы) отправляются в модуль, который по их последовательности определяет, что произошел фол или корректное падение шара в лузу, переход хода или окончание игры. Беспристрастный модуль ведет счет и объявляет победителя. Особенность его в том, что он работает без всяких автокоррекций и эвристик, просто формально применяя правила игры. Блок с правилами можно целиком заменить, что позволяет без существенного вмешательства в систему адаптировать ее к локальным правилам турнира или использовать для обработки других видов бильярдных игр.
Как беспилотные автомобили до сих пор полностью не избавились от инженера-испытателя в салоне, который следит за безопасностью, так и наш модуль правил позволяет осуществлять внешнее ручное управление через web-интерфейс. Вмешательство может потребоваться, если автоматическая система ошибется. Кроме того, необходим ручной ввод отсутствующих в видеопотоке данных: о начинающем игроке, специальных ударах, которые объявляются по ходу игры голосом и т.п. Один человек потенциально может следить за несколькими играми одновременно.

Как это работает

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

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

Техническая визуализация того, как работает система. Шар около «Cue ball» обозначает с каким первым шаром столкнулся биток; «State» — состояние системы: может быть «wait» — пока игрок не совершил удар и «play» — пока шары находятся в движении; «Player» — текущий игрок; цифры около шаров обозначают оценку скорости в см/с.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть