Всем привет.
Мне тут вздумалось погрузиться в дебри нейросетей и запилить быстренько приложение, которое позволяет распозновать рукописные (нарисованные на сенсорном экране пальцем или еще чем-то) цифры. Самая простая идея: игра – обучение/тренировка арифметике. Игроку предлагается некий простенький пример, он решает его и пишет ответ, система распознает и говорит "верно"/"неверно". Можно еще добавить очки или ограничить время. Тут недавно была похожая тема, но у меня акцент именно на рукописном способе ввода.
Название: Study Maths (рабочее, возможно, сменится)
Жанр: обучающая головоломка
Начало разработки: 19 февраля 2013 года
Текущий статус: есть демка с базовым функционалом
Язык, API: Obj-C, Cocos2D-iPhone
Пока поддерживаются операции сложения (от 0 до 19), вычитания (без отрицательных), умножения (до 10 * 10), деления (на ноль нельзя!).
На алгоритм распознавания потратил очень много времени: почти неделю. Но пока он далек от совершенства. Я использую 5 слойную сверточную нейросеть, наученную на базе рукописных цифр (MNIST, 600000 цифр). Отсюда вытекает главная проблема: в базе цифры написаны ручкой на бумаге, потом отсканированы. У меня же они пишутся пальцем на экране, рендерятся в текстуру и идут на нейросеть. После нейросети есть еще пара хаков: например, моя рукописная 6 всегда почти распознается, как 5. Пришлось использовать некоторые свойства кривых, чтобы различать их. И то, не всегда успешно. Также алгоритм разделения кривых на цифры, который я придумал сегодня утром, иногда сбоит и нуждается в явной доработке. Хочу добавить еще знаки "+" и "-", позже ".".
Еще есть концептуальная идея прикрутить к этому делу CMU Sphinx и какой-нить text-to-speech, получим, таким образом, и чисто голосовой вариант. Игра читает игроку пример, игрок отвечает голосом, получает одобрение или наоборот. Обязательно попробую в скором времени, если пойдет гладко (справлюсь менее, чем за неделю), то 100% включу в проект.
Сейчас также думаю над графикой и оформлением. Тут пока неоднозначно: либо найду кого из друзей, либо сам нарисую, либо тут поспрашиваю. Если художник будет, то свое время посвящу сбору рукописных начертаний для дополнительного обучения сети.
Опубликую обязательно, по сути уже сейчас можно публиковать. Если с оформлением заладится, то буду искать издателя. Если издатели откажут, выложу бесплатно с отключаемой рекламой. В любом случае пойдет юзверям на радость, а мне в портфолио.
В общем, планов много, не знаю сейчас, что и когда будет реализовано. Времени не хватает. Еще параллельно тащу 2 проекта и кандидатскую диссертацию :)
Ожидаемый фидбек:
удивленные возгласы, слова одобрения, идеи для улучшения игрового/обучающего процесса. Если вдруг очень захочется помочь, велком в скайп linrand
Скриншоты:
Обязательно посмотрите видео.
Сорри за качество: штатив сперли, а стабилизатор в редакторе замылил почему-то...
Дневник разработки:
19.02.2013 Начало
26.02.2013 Добавлена озвука примеров и результата на аглийском Flite text-to-speech
27.02.2013 Добавлена поддержка распознования голоса (см. видео со звуком):
К сожалению, результат меня сильно не устраивает. Слишком мала точность, требуется тишина, трудно сделать русский язык, приложение очень сильно разбухает в объеме. Так что в первом релизе скорее всего распознования голоса не будет. Я пока не знаю, как улучшить распознования голоса, т.к. использую сторонний API.
01.03.2013
Добавил распознование знака "минус".
Добавил главное меню.
Добавил меню конфигурирования задачки: набор операций, максимальные числа, разрешение на нуль и на отрицательные числа.
Об игровых режимах:
Не прошло и трех часов (два из которых ушли на Майнкрафт), как прикрутил голосовую озвучку. Пока на английском языке. Завтра обновлю ролик.
какова скорость распознавания?
> (MNIST, 600000 цифр).
разве нельзя сделать проще? когда-то давно решал олимпиадную задачку на распознавание ряда символов, символы рисовались по сетке - "монохромное" поле MxM, буква могла занимать любое количество клеток, распознавалось кажется через конечные автоматы
Прикольно.
leonardo98
> какова скорость распознавания?
На iPhone 5 где-то 100 мс на цифру в отладочном режиме (3 прогона сети). Если собрать в релизе, убртать вывод в лог, думаю будет существенно быстрее. Ну и в отдельный поток, конечно, вывести, чтоб не смущать подтормаживаниями.
> разве нельзя сделать проще?
Думаю, нет. Я перебрал несколько вариантов: анализ кривой (длина, скорость, повороты), простая двуслойная нейросеть Кохонена, супер-пупер крутую библиотеку для OCR – Tesseract . Они все дают плохие результаты.
Задачка была в духе: "на электронном табло сломались какие-то пиксели, попробуйте угадать, какое число отображается?" Если да, то это совсем не то. Начертаний от руки может быть очень много, одна и таже цифра может выглядеть совершенно по-разному. Сеть Кохонена при длительном обучении превращается в однородный супчик и перестает вообще что-либо распозновать.
tirinox
> Задачка была в духе: "на электронном табло сломались какие-то пиксели,
> попробуйте угадать, какое число отображается?"
нет, просто буквы были "нарисованы" с хвостиками и замкнутыми областями разных размеров
Добавил дневник разработки в начальный пост.
Добавил в приложение озвучку (Flite TTS) и поддержку распознования голоса (PocketSphinx). Можно решать примеры чисто на слух. К сожалению, результат меня сильно не устраивает. Слишком мала точность, требуется тишина, трудно сделать русский язык, приложение очень сильно разбухает в объеме. Так что в первом релизе скорее всего распознования голоса не будет. Я пока не знаю, как улучшить распознования голоса, т.к. использую сторонний API.
(См. видео со звуком)
Добавил распознование знака "минус".
Добавил главное меню.
Добавил меню конфигурирования задачки: набор операций, максимальные числа, разрешение на нуль и на отрицательные числа.
Пока не заливаю видео и скриншоты. В ближайшее время добавлю игровые режимы, доску рекордов и еше что-нить. Тогда залью.
Режим "Тренировка"
Неограниченное количество примеров, без игровых очков и досок рекордов.
Режим "Тест"
Время неограничено. Дается, скажем, 10 примеров. Нужно стараться решить их безошибонко. По окончанию теста ставится оценка.
Режим "На время"
Игроку дается определенное фиксированное время, думаю, 1:30 будет оптимально, потому что за минуту мало примеров можно решить, а через две может уже надоесть. Игрок решает примеры так быстро, как может. Задача решить как можно больше примеров.
В последних двух режимах ведется подсчет очков. За каждый верно решенный пример прибавляют N очков
N = a * b * exp(-alpha * t^2), распределение нормальное по сути,
где a – коэффициент сложности операции в примере. Пусть для сложения a = 1, вычитания a = 2, умножения и деления a = 3.
b – коэффициент, зависящий от величины операндов и результата. Если мы решаем примеры с числами до 10, то b = 100, если до 20 – b = 150, и т. д. Здесь рост более медленный, приоритет отдается скорости решения. Иначе можно считать на калькуляторе большие числа и вырываться в топы. Некоторая защита от читерства.
alpha – отвечает за скорость убыли очков со временем, t – время решения.
Таким образом, игрок получит больше очков, если будет решать более сложные примеры за более короткое время.
Не знаю, пока стоит ли делать эти коэффициенты изменяемыми от примера к примеру или нет. Если будут меняться, то появится элемент случайности от серии к серии. Т.е. можно будет набрать мало очков только потому, что попадались простые примеры.
Аргумент "ПРОТИВ". Программа о математике, науке точной, не должно быть случайности. В школе стараются поставить учеников в равные условия.
Аргумент "ЗА". Не повезло со сложностью – ты решишь быстро и примешься за следующую серию – игрок будет проводить больше времени в игре.
И еще деталь, которую хочу реализовать.
Если ответ, распознанный игрой неверен, то единожды предлагается ввести его еще раз. Право на ошибку позволит скомпенсировать неидеальность разпознования. Двойная ошибка – незачет примера, показывается анимация правильного начертания ответа. Позволит игроку лучше привыкнуть к системе. Для самых юных – заодно обучение начертанию цифр.
Тема в архиве.