Могут ли игральные кости быть нечестными? Чтобы ответить на этот вопрос, недостаточно просто бросить кости пару раз. Нужны тысячи, а лучше сотни тысяч бросков. Делать это вручную — путь в никуда. Поэтому мы решили научить компьютер делать это за нас. В этой статье — история о том, как мы создали систему, способную распознавать игральные кости в реальном времени, и с какими трудностями столкнулись.
Первая задача состояла в самом распознавании игральных костей, значении грани и цвета кости в реальном времени из любого источника. Существует два основных подхода к решению этой задачи: линейные алгоритмы компьютерного зрения(OpenCV) и нейронные сети (ИИ).
Преимущество ИИ заключается в том, что готовое решение хорошо себя показывает при изменении условий:
цвета костей,
количества костей,
фокуса,
ракурса,
разрешения камеры,
освещенности и т.д.
Вдобавок, обученная модель легко расширяема: если вместо точек на гранях будут цифры, то её можно дообучить на новых данных.
Начали мы с простого — OpenCV. Как и ожидалось, такое решение оказалось не устойчиво ко всем выше перечисленным изменениям условий, поэтому приступили к поиску фреймворка для обнаружения объектов с помощью ИИ. Выбор пал на Ultralytics YOLO — знаменитая модель для обнаружения и классификации объектов в реальном времени:
основан на передовом прогрессе в области глубокого обучения и компьютерного зрения
предлагает непревзойденную производительность в отношении скорости и «точности»
предоставляет удобный API на питоне
предоставляет CLI для обучения, предсказания и прочих действий.
Этап первый: подготовка к обучению
Обучение модели требует большой датасет из наборов пар - внутри каждой содержится из изображения и файла разметки. Разметка представляет из себя обычный текстовый файл с информацией: где на изображении располагаются кубики и значения граней.

Структура файла разметки представляет из себя строки, содержащие название класса, нормализованные координаты центра и нормализованную высоту с шириной:
название класса |
нормализо- |
нормализо- |
нормализо- |
нормализо- |
|
Кость #1 |
6 |
0.425 |
0.597 |
0.03 |
0.053 |
Кость #2 |
6 |
0.442 |
0.319 |
0.03 |
0.041 |
Кость #3 |
5 |
0.206 |
0.502 |
0.032 |
0.05 |
Кость #4 |
4 |
0.268 |
0.725 |
0.034 |
0.057 |

Есть много инструментов для упрощения создания датасетов, так как их требуется несколько тысяч. Выбор пал на open source программу «LabelImg»: примитивно, просто и бесплатно. Для первоначального датасета этого вполне достаточно. С её помощью создание датасета свелось к простейшим манипуляциям: выделение мышкой костей на изображении и выбор значения грани.

Чувствуем вашу мысль: «Даже с подобными инструментами, создание нескольких тысяч наборов потребует месяцы работы!», согласны с мыслью! Посему скачали уже готовые наборы с игральными костями(из открытых источников): kaggle и Roboflow. Поскольку наборы находятся в различных источниках,каждый пользователь размечал и сохранял данные по-своему,
Нам потребовалось время, чтобы привести их к одному виду и формату YOLO, но оно того стоило!
Этап второй: обучение
Для обучения модели требовались большие вычислительные мощности: в основном CUDA и тензорные ядра видеокарты. Но для начального этапа нам было достаточно офисного ПК:
Материнская плата - Gigabyte B460M
Процессор - Intel i7-10700F
Видеокарта - GT1030
ОЗУ - 16GB
SSD - 256GB
Такой конфигурации достаточно для определения вектора разработки, но даже с ней обучение на скачанном датасете в размере 2 000 заняло всего 20 часов. Обученная модель имела неплохие результаты «точности», но работала только с тестовыми наборами данных. Вот тут и появилась первая проблема: профессиональные игральные кости - прозрачные, и нижняя грань просвечивается. В этой связи наша модель не может распознать значения граней правильно, да и в готовых датасетах отсутствовали такие кейсы.

Для решения этой проблемы пришлось прибегнуть к ручной разметке в LabelImg: добавили в стартовый датасет около 200-300 наборов с ручной разметкой и запустили следующую итерацию обучения.
Новая модель научилась распознавать профессиональные кости в реальном времени, но со средней «точностью». С увеличением датасета время обучения линейно увеличивается - потребовалось примерно 23 часа.

Эта модель открыла бОльшие возможности для дальнейшего обучения и применения. На её основе мы уже можем разработать некоторые инструменты, которые будут помогать в дальнейшем обучении:
Проверка датасета на наличие ошибок с помощью модели, обученной на этом же датасете:
прогнав датасет через модель и отсортировав результаты наборов по «точности» распознавания, можно взять часть, примерно 10%, наихудших результатов и проверить их вручную через LabelImg. С большой вероятностью, найдутся наборы, содержащие ошибки при ручной разметке - они очень портят итоговый результат модели.Полуавтоматическое дополнение датасета:
теперь необязательно размечать наборы вручную с помощью LabelImg. Достаточно показать кости с любого видеопотока и они определяются моделью Далее нужно только вручную подтвердить валидность, т.к. модель может ошибиться и набор сохранится в датасет.
Имея модель с приемлемой «точностью» и инструментами, можно определить цикл обучения для дальнейшего улучшения качества распознавания:
Проводим проверку датасета инструментом №1
Добавляем в датасет новые данные инструментом №2
Начинаем процесс обучения

После 5-7 таких циклов размер датасета увеличился до 5 000 наборов, «точность» вышла на приемлемый уровень но уперлась в «потолок» из-за ограниченной мощности ПК.


В данный момент обучение модели происходит в низком разрешении изображений 640. Для повышения «точности» распознавания нужны наборы данных в высоком разрешении 1920, но это невозможно с данной конфигурацией ПК. Поэтому собираем новый:
Было |
Стало |
|
Материнская плата |
Gigabyte B460M |
Gigabyte Z790 AORUS ELITE |
Процессор |
Intel i7-10700F |
Intel i7-12700K |
Видеокарта |
GT1030 |
RTX 4080 |
ОЗУ |
16GB |
64GB |
SSD |
256GB SATA |
1TB M2 |
CUDA / TENSOR ядра |
384 / 0 |
9728 / 76 |
Время обучения на одинаковом датасете |
28 минут |
15 секунд |
Запускаем обучение на текущем датасете в высоком разрешении 1920 и параллельно - обучение другой модели для распознавание цвета кости. В результате «точность» значительно выросла.

Продолжим увеличивать датасет, но в этот раз сделаем это быстрее! Где же можно найти столь много материала? Ответ прост - записи чемпионатов игры в нарды. Для получения видеопотока из интернета, в частности Ютуб, будем использовать OBS studio, через которую эмулируем веб камеру, которая транслирует видеоролик. Такой подход позволяет нам не менять программную часть и быстро менять ссылки на источник видео.

Таким способом мы быстро собираем около тысячи наборов для датасета, проверяем и снова запускаем обучение. Новая модель даёт ещё больше возможностей - например обрабатывать изображения 4к со сложным фоном.


Так как «точность» поднялась на высокий уровень, мы запустили автоматическое дополнение датасета: разработали инструмент, куда передается список ссылок на ютуб видео, которые далее скачиваются, и в нём модель находит наборы данных, которые добавляет в датасет. Для примера: выбрано 5 видео с играми в нарды общей продолжительностью около 20 часов. Разработанному инструменту потребовалось 3-4 минуты для обработки всех кадров, обнаружения 2 000 наборов данных и добавления их в общий датасет для дальнейшего обучения.
В итоге получилась обученная на датасете размером 10 000 модель для распознавания игральных костей любого типа. Скорость распознавания, вне зависимости от количества костей в кадре, составляет около 80 кадров в секунду (разрешение 1920рх). Ниже - таблица улучшения распознавания модели при увеличении датасета.Обозначим, что все модели обучались при стандартных гиперпараметрах, кроме разрешения:
итерация обучения |
размер датасета |
mAP50 |
mAP50-95 |
комментарий |
время обучения |
1 |
2 000 |
0.88 |
0.77 |
скачанные датасет |
20 часа |
2 |
2 300 |
0.92 |
0.81 |
добавление 300 собственных наборов |
23 часа |
2-9 |
5 000 |
0.95 |
0.86 |
50 часов |
|
10 |
5 200 |
0.96 |
0.89 |
Новый ПК и добавление наборов высокого разрешении |
5 часов |
10-20 |
7 000 |
0.97 |
0.92 |
7 часов |
|
21 |
10 000 |
0.98 |
0.94 |
добавление наборов в автоматическом режиме |
10 часов |
22 |
11 000 |
0.994 |
0.96 |
последняя проверка датасета на ошибки |
11 часов |
Последний этап: оценка точности модели
Сейчас мы разберёмся почему «точность» всю статью была в кавычках и опустим их. На рисунках 5, 7, 10, 11, помимо значения грани кости, присутствует дробная величина, которая варьируется от 0 до 1. Это значение не является точностью или вероятностью распознавания, как многие это считают - значение называется уверенностью. Модель YOLO при обнаружении объектов выдает так называемую оценку уверенности для каждого найденного объекта. Эта величина не является точностью или вероятностью в привычном смысле. Скорее, это комбинированный показатель, который отражает:
насколько модель уверена, что в данной области изображения действительно есть какой-то объект.
насколько хорошо модель подобрала границы этого объекта по сравнению с реальными (эталонными) границами.
Иными словами, если уверенность высокая — это значит, что модель считает, что объект точно есть, и она довольно точно определила его положение. Но это не «чистая» вероятность, и напрямую сравнивать её с метриками вроде точности или вероятности нельзя — она рассчитывается по внутренним правилам модели и используется в основном для фильтрации слабых или сомнительных предсказаний.
Значение уверенности в итоговой модели варьируется в пределах 0,85-0,95. А устраивает ли нас данная уверенность модели для ее дальнейшего применения? По многочисленным результатам исследований был выявлен условный порог уверенности, равный 0,8. Исследование заключалось в отслеживании значения уверенности с каждым кадром при постепенном ухудшении условий распознавания: изменение фокуса, освещённости, дальности, а затем снова улучшения, чтобы оценить стабильность.

На графике наглядно видны провалы функции уверенности до 0 - модель неверно распознала грань. Тут мы делаем вывод, что при значении уверенности ниже 0,8 начинают появляться разного рода осцилляции и срывы функции, что недопустимо. Это доказывает экспериментальным путём стабильную работу модели при уверенности больше 0,8.
Заключение
Для итоговой модели мы использовали датасет из более чем 10 000 наборов реальных фотографий, а не синтетических, которых можно сгенерировать огромное количество за пару часов. Именно это нам дало сильную устойчивость к разному фону, разрешению камеры, углу, фокусу, типа кубика, освещению и т.д. как можно заметить на рисунках 7, 8 и 11. Такая модель идеально подходит для следующего масштабного этапа — математическому анализу частоты выпадения граней и автоматическому устройству, которое бросает кости сотни тысяч раз подряд.
LeshaRB
Какое-то дежавю... Вчера же статья была с комментариями