Обработка временных рядов и байесовские модели для распознавания рукописного текста
Всем привет! Недавно я закончил курс «Machine Learning. Advanced» по продвинутым техникам машинного обучения.
Я работал над проектом по обработке временных рядов. Тема проекта: «Применение алгоритмов обработки временных рядов и байесовских моделей для задачи извлечения символов из темпоральной информации с цифровой ручки». Я надеюсь применить методы, которые опробовал, в моей основной области — обычно я занимаюсь задачами компьютерного зрения, где использую нейронные сети для обработки изображений.
Сейчас я работаю в компании, которая занимается автоматическим анализом документов. Одно время я разрабатывал генератор рукописных текстов. Приходилось глубоко погружаться в наборы данных и модели, которые собрали и построили до меня.
Нужны были оцифрованные рукописные тексты. Они делятся на 2 вида: offline и online. Первый тип — offline — это скан или фотография рукописи, растровое изображение. Online же рукописи состоят из точек — пути цифрового пера во время письма; это векторное изображение. Такие наборы создают вручную при помощи стилусов и графических планшетов. В то же время можно измерить ускорение и угол наклона пера относительно, например, планшета или другой поверхности.
Однако есть и исключение — набор «Stabilo-OnHW» не относится ни к первому, ни ко второму типу. Авторы проекта использовали специальную ручку. Хотя, она пишет на обычной бумаге, на ней также есть специальные датчики: 2 акселерометра, магнитометр, гироскоп и измеритель силы нажатия.
Так собрали параметры поведения ручки в то время, когда человек выводит различные символы. Создай много таких наборов с рукописями — и это уже основа для синхронного перевода бумажных конспектов в цифровой формат безо всякого распознавания и сканирования.
119 писателям было предложено вывести разработанной ручкой по латинской букве: строчной и прописной. Всего было собрано 31275 символов. С частотой 200 Гц датчики фиксировали показания. Акселерометры, гироскоп и магнитометр производили измерения по 3 координатам (x, y, z), измерялась сила нажатия. Таким образом каждому символу соответствует 13 временных рядов.
Как можно видеть из рисунка выше, с течением времени показания датчиков меняются. Выдвину гипотезу: для одинаковых букв поведение измерений будет сходным, для разных букв — различным. Однако это затруднительно проверить вручную, анализируя каждую букву и весь набор данных целиком. Попробуем построить распознаватель букв по замерам датчиков.
Авторы набора данных предлагают делать его для разных разбиений: writer dependent (WD), writer independent (WI). В первом случае предлагается строить отдельные классификаторы для каждого писателя. WI является более сложным. Распознавание требуется производить по общей совокупности собранных данных, не учитывая информацию о писателе. Поэтому построение модели будет производиться для второго варианта разбиения.
Строчные и заглавные буквы выделяются в отдельные выборки. Также есть вариант со смешанными буквами. В данной работе будем рассматривать все эти варианты. Построим графики измерений для некоторых букв от нескольких авторов.
Показания датчиков для разных букв и для разных писателей. Выбранные буквы 'a', 'R' и 'C'
На рисунке выше показаны показания датчиков для букв «a», «R» и «C» для 2 писателей, выбранных случайно. Видно, что поведение силы нажатия похоже для одних и тех же букв. Также стоит обратить внимание на схожесть поведения измерений гироскопа.
Предположительно, используя предложенные данные, можно построить распознаватель.
Как говорилось ранее, датчики производят измерения с некоторой частотой, т.е. через заданные заранее промежутки времени. Разные люди по-разному пишут разные буквы — с разной скоростью ведут ручкой по бумаге. По этой причине количество измерений для всех написаний различается. Данный факт усложняет построение модели распознавания, так как алгоритмам машинного обучения требуются последовательности фиксированной длины на вход.
На графиках выше представлены распределения длин последовательностей в зависимости от буквы. Размеры этих рядов варьируются от буквы к букве, от писателя к писателю. Максимальная длина последовательности превышает 3400 измерений. По-моему мнению, исходя из левого графика, в качестве оптимальной длины последовательности можно взять 60 измерений. Приведение измерений к этой длине производится при помощи алгоритма ресэмплирования из scipy — resample. Производится «сжатие»-«растяжение» исходных временных рядов до указанной длины.
Произведя приведение рядов к одной общей длине можно построить усредненные графики измерений датчиков для каждой буквы. На рисунке приведены графики для букв «a», «C» и «R». Можно заметить, что графики получились не сильно зашумленными — их поведение не сильно варьируется на коротких временных промежутках. Усредненные показания отличаются от буквы к букве. Следовательно эти данные можно использовать для дальнейшего построения модели распознавания. Для этого будут использованы несколько алгоритмов машинного обучения и методов обработки временных рядов.
Авторы набора данных сами проводили эксперименты с распознаванием. Они обучили модели «классического» машинного обучения и нейронные сети. При этом для первого вида моделей данные использовались как без предварительной обработки, так и с использованием специальной мини-модели, преобразующей ряды в специальное представление.
Авторские результаты для «классических» моделей представлены в таблице выше. Использованная метрика — accuracy для мультиклассовой классификации.
Для получения baseline-решения было решено попробовать LogisticRegression и LinearSVM из Scikit-Learn, аналогично тому, как делали разработчики «Stabilo-OnHW».
В качестве новых алгоритмов были взяты:
- XGBoost с макс. глубиной 10 и количеством деревьев 500
- LightGBM с макс. глубиной 10 и количеством деревьев 500
- Простая байесовская линейная модель: Реализация выполнена при помощи pymc3.
Дополнительно были опробованы библиотеки автоматической генерации признаков из временных рядов: TSFresh и TSFEL.
Извлечение новых признаков из показаний магнитометра и датчика силы нажатия проводилось с использованием библиотеки TSFresh. Графический анализ данных выявил стационарность измерений магнитометра. Поэтому для них был выбран набор MinimalFCParameters. Сила же нажатий варьируется сильнее. Для нее используются параметры EfficientFCParameters.
Показания гироскопа для разных букв выглядят как набор периодических функций. Из показаний акселерометров теоретически можно извлечь частотно-временную информацию. Для этих измерений используется TSFEL. Она предоставляет большую вариативность в видах признаков для генерации, например, могут быть извлечены статистические и спектральные признаки.
Полученные признаки фильтруются — удаляются скоррелированные и константные признаки. Затем происходит обработка функцией select_features из TSFresh. В итоге из 60 значений временных рядов получается 1467 признаков.
Выбранные мной модели были обучены на следующих наборах: рэсэмплированных рядах и автоматически сгенерированных признаках.
На таблице выше приведены значения метрики accuracy на тестовой выборке. Результаты полученного мной baseline совпали с авторскими. Отмечу, что модели градиентного бустинга достигают лучшего качества по сравнению с простыми моделями. При этом LightGBM показывает лучшее качество чем XGBoost.
Из таблицы видно, что синтез новых признаков улучшает линейные модели, но плохо влияет на работу моделей градиентного бустинга. Байесовская модель работает лучше чем линейные модели, но хуже чем градиентный бустинг. Использованная для реализации байесовской модели библиотека PyMC3 не смогла обработать данные с новыми признаками. По этой причине в сравнении для признаков байесовская модель отсутствует.
Авторы в своей статье приводят результаты распознавания с использованием рекуррентных нейронных сетей. Использованный мной градиентный бустинг работает на 5% хуже, чем более сложные сети. Это говорит о том, что были достигнуты приемлемые результаты распознавания.
Для анализа ошибок рассмотрим confusion matrix для результатов работы LightGBM на строчных, прописных и смешанных буквах.
На confusion matrix видно, что буквы типа «c/C», «o/O», «s/S», «z/Z» являются проблемными для модели-распознавателя. Гипотетически, это связано с тем, что строчное и прописное написание таких букв схоже. А учитывая то, что разные авторы пишут разным почерком и с разным размером штрихов, то такие буквы могут быть неотличимы друг от друга по показаниям датчиков.
Для строчных и прописных букв модель путает буквы, у которых могут быть одинаковые элементы. Например, у букв «P» и «D есть выпуклая вправо дуга. Это создает возможность при плохом почерке одинаково выводить эти буквы. Модель может не улавливать мельчайшие изменения в поведении ручки и ошибаться в предсказании буквы.
Почти 1,5 тысячи признаков на наборе Stabilo-OnHW я сгенерировал благодаря новым для меня библиотекам: TSFresh и TSFEL. Опираясь на них, я построил модели распознавания рукописных символов. Новые признаки даже улучшили качество линейных моделей на 8–10%.
Градиентный бустинг показал достойные результаты без сложной предобработки, которая даже ухудшает модели такого рода. Я не менял гиперпараметры — максимальную глубину дерева и количество деревьев — чтобы сохранить корректность сравнений. Но чтобы достичь лучшего качества, нужны ещё и эксперименты с их изменением.
Также можно построить более качественную модель, если улучшить распознавание регистров букв. Думаю, здесь будет полезен ансамбль из нескольких моделей. Одна из моделей распознает регистр буквы: строчная или прописная. Остальные — нужны, чтобы предсказывать конкретный символ.
Дополнительно стоит провести эксперименты с различными архитектурами нейронных сетей. К сожалению, это уже выходит за рамки проекта. Тем не менее, было бы интересно сравнить работу таких моделей с результатами, которые получили авторы «Stabilo-OnHW», и построить наилучшую модель распознавания.
Кстати, прямо сейчас в OTUS открыт набор на специализацию Machine Learning, в рамках которой можно пройти полный цикл обучения. Подробнее о специализации можно узнать тут.