Проблема в том, что Яли слишком мал, чтобы разобраться в том, как играют в игру, и он изобрёл свою версию игры. Цель игры – разобрать карточки по категориям (покемон, энергия и тренировочная карта).
Он не спрашивал, откуда я знаю, какого типа карта. Он просто взял несколько карт и спросил, какого они типа. Получив несколько ответов, он сумел разделить несколько карт по типу (совершив при этом несколько ошибок). В этот момент я понял, что мой племянник – это, по сути, алгоритм машинного обучения, а моя задача в качестве дяди состоит в маркировке данных для него. Так как я дядя-гик, и энтузиаст машинного обучения, я начал писать программу, которая сможет посоревноваться с Яли.
Так выглядит типичная карта покемона:
Для умеющего читать взрослого человека легко понять, какого типа эта карта — на ней написано. Но Яли 4 года, и читать он не умеет. Простой OCR-модуль быстро решил бы мою задачу, но я не хотел делать лишних предположений. Я просто взял эту карту и предоставил её для изучения MLP-нейросети. Благодаря сайту pkmncards я мог скачивать картинки, уже рассортированные по категориям, поэтому с данными проблем не возникло.
Алгоритму машинного обучения нужны особенности, и моими особенностями были пиксели изображений. Я преобразовывал 3 цвета RGB в одно целое число. Поскольку мне попадались картинки разных размеров, их нужно было нормализовывать. Найдя максимальные высоту и ширину картинок, я добавлял нули к картинкам меньшего размера.
Быстрый прогон QA перед работой самой программы. Я случайным образом брал две карты каждого типа и запускал предсказание. При использовании 100 карт из каждой категории подгонка шла очень быстро, а предсказания были ужасными. Затем я взял по 500 карт из каждой категории (исключая типы энергии, которых было всего 130), и запустил подгонку.
Память закончилась. Можно было запустить код подгонки в облаке, но я хотел придумать способ экономии памяти. Самая крупная картинка была размером 800×635, это было слишком много, и изменение размера картинок решило мою проблему.
Для настоящей проверки в дополнение к обычным картам я добавлял карты, на которых я немного калякал, карты, разрезанные пополам, с нарисованными поверх контурами, фотографировал их с телефоном (с плохой камерой) и т.п. Для тренировки эти карты не использовались.
Я использовал 1533 модели. Разные размеры картинок, несколько скрытых слоёв (до 3), длина слоя (до 100), цвета изображений, методы чтения изображений (всё целиком, верхняя часть, каждый второй пиксель, и т.п.). После многих часов подгонки лучшим результатом стало 2 ошибки из 25 карт (мало у каких моделей был такой результат, и каждая из них ошибалась на разных картах). 9 моделей из 1533 сработали с результатом в 2 ошибки.
Комбинация моделей давала мне результат с 1 ошибкой, если я поднимал порог выше 44%. Для теста я использовал порог в 50%. Я подождал месяц, пока Яли игрался с картами, и провёл тестирование.
Ошибки происходят при распознавании энергетических карт. На pkmncards таких карт было всего 130, в отличие от тысяч карт других типов. Меньше примеров для обучения.
Я поспрашивал Яли по поводу того, как он распознавал карты, и он рассказал, что видел некоторых покемонов в телешоу или книгах. Именно так он распознал уши Райчу или узнал, что Вапореон – это водный Иви. У моей программы таких данных не было, только карты.
Победив Яли в игре с покемонами и получив награду, наш машинный интеллект отправляется навстречу новым приключениям.
Источник