В предыдущих статьях мы уже писали о том, как работают наши технологии распознавания текста: Навигатор по сериям постов
- Распознавание текста в ABBYY FineReader (1/2)
- Распознавание текста в ABBYY FineReader (2/2)
Но распознавание иероглифов имеет свои трудности:
- Огромное количество классов, которые необходимо различать.
- Более сложная структура символа в целом.
Однозначно сказать, сколько иероглифов в китайской письменности, так же сложно, как точно подсчитать, сколько слов в русском языке.
Но наиболее часто используемые иероглифы в китайской письменности составляют около 10 000 иероглифов.
Мы ограничили количество классов, используемых при распознавании их.
Обе описанные выше проблемы также приводят к тому, что для достижения высокого качества необходимо использовать большое количество признаков, а сами эти признаки требуют больше времени для расчета на изображениях персонажей.
Чтобы эти проблемы не привели к сильным замедлениям всей системы распознавания, пришлось использовать множество эвристик, направленных в первую очередь на быстрое отсечение значительного количества иероглифов, на которые эта картинка точно не похожа.
Это еще не полностью помогло, но мы хотели вывести наши технологии на качественно новый уровень.
Мы начали изучать возможность применения сверточных нейронных сетей для улучшения качества и скорости распознавания символов.
Я хотел заменить весь блок распознавания отдельных символов для этих языков с помощью нейронных сетей.
В этой статье мы расскажем вам, как нам в конечном итоге это удалось.
Простой подход: одна сверточная сеть для распознавания всех иероглифов
В целом, использование сверточных сетей для распознавания символов — совсем не новая идея.Исторически они впервые были использованы именно для этой задачи еще в 1998 году.
Правда, тогда это были не печатные иероглифы, а рукописные английские буквы и цифры.
За последние 20 лет технологии в области глубокого обучения, конечно, сильно шагнули вперед. Это включает в себя появление более совершенных архитектур и новых подходов к обучению.
Архитектура, представленная на схеме выше (LeNet), на самом деле сегодня очень хорошо подходит для таких простых задач, как распознавание печатного текста.
Я называю это «простым» по сравнению с другими задачами компьютерного зрения, такими как поиск и распознавание лиц.
Казалось бы, решение не может быть проще.
Берем нейронную сеть, образец помеченных иероглифов, и обучаем ее задаче классификации.
К сожалению, оказалось, что все не так просто.
Все возможные модификации LeNet для задачи классификации 10 000 иероглифов не обеспечивали достаточного качества (по крайней мере, сравнимого с уже имеющейся у нас системой распознавания).
Для достижения необходимого качества пришлось рассмотреть более глубокие и сложные архитектуры: WideResNet, SqueezeNet и т. д. С их помощью удалось добиться необходимого уровня качества, но они показали существенную просадку по скорости работы — в 3-5 раз.
по сравнению с базовым алгоритмом на ЦП.
Некоторые могут задаться вопросом: «Какой смысл измерять скорость сети на ЦП, если на графическом процессоре (GPU) она намного быстрееЭ» Здесь стоит сделать ремарку, что для нас в первую очередь важна скорость работы алгоритма на CPU. В ABBYY мы разрабатываем технологии для большой линейки продуктов распознавания.
В большинстве сценариев распознавание осуществляется на стороне клиента, и мы не можем сознательно предполагать, что у него есть графический процессор.
Итак, в итоге мы пришли к следующей проблеме: одна нейросеть для распознавания всех символов в зависимости от выбора архитектуры работает либо слишком плохо, либо слишком медленно.
Двухуровневая нейросетевая модель распознавания иероглифов
Мне пришлось искать другой путь.При этом отказываться от нейронных сетей мне не хотелось.
Казалось, самой большой проблемой было огромное количество классов, из-за чего приходилось строить сети со сложной архитектурой.
Поэтому мы решили, что не будем обучать сеть для большого количества классов, то есть для всего алфавита, а вместо этого будем обучать множество сетей для небольшого количества классов (подмножеств алфавита).
В общих чертах идеальная система представлялась следующим образом: алфавит разделен на группы одинаковых символов.
Сеть первого уровня классифицирует, к какой группе символов принадлежит данное изображение.
Для каждой группы, в свою очередь, обучается сеть второго уровня, которая производит итоговую классификацию внутри каждой группы.
Картинка кликабельна
Таким образом, мы выполняем итоговую классификацию, запуская две сети: первая определяет, какую сеть второго уровня запускать, а вторая уже производит итоговую классификацию.
Собственно, принципиальным моментом здесь является то, как разделить символы на группы таким образом, чтобы сеть первого уровня можно было сделать точной и быстрой.
Построение классификатора первого уровня
Чтобы понять, какие символы сети отличить легче, а какие сложнее, проще всего посмотреть, какие особенности выделяются у тех или иных символов.Для этого мы взяли сеть-классификатор, обученную качественно различать все символы алфавита, и посмотрели статистику активации предпоследнего слоя этой сети — мы начали смотреть конечные представления признаков, которые сеть получает для всех символов.
.
При этом мы знали, что картинка там должна выглядеть примерно так:
Это простой пример для случая классификации выборки рукописных цифр (MNIST) на 10 классов.
Предпоследний скрытый слой, который идет перед классификацией, содержит всего 2 нейрона, что позволяет легко отображать статистику их активаций на плоскости.
Каждая точка на графике соответствует какому-либо примеру из тестовой выборки.
Цвет точки соответствует определенному классу.
В нашем случае размерность пространства признаков была больше, чем в примере — 128. Мы прогнали группу изображений из тестового набора и получили вектор признаков для каждого изображения.
После этого они были нормализованы (разделены по длине).
Из картинки выше понятно, почему это стоит сделать.
Мы кластеризовали нормализованные векторы с помощью метода KMeans. Мы получили разделение выборки на группы схожих (с точки зрения сети) изображений.
Но нам в конечном итоге нужно было получить разбиение алфавита на группы, а не разбиение тестового набора.
Но получить первое из второго несложно: достаточно каждой метке класса присвоить тот кластер, который содержит наибольшее количество изображений этого класса.
Конечно, в большинстве ситуаций весь класс окажется внутри одного кластера.
Ну вот и все, мы получили разбивку всего алфавита на группы схожих символов.
Остается только выбрать простую архитектуру и обучить классификатор различать эти группы.
Вот пример случайных 6 групп, которые получаются путем разделения всего исходного алфавита на 500 кластеров:
Построение классификаторов второго уровня
Далее вам нужно решить, на каких целевых наборах символов будут учиться классификаторы второго уровня.Кажется, ответ очевиден – это должны быть группы символов, полученные на предыдущем шаге.
Это будет работать, но не всегда с хорошим качеством.
Дело в том, что классификатор первого уровня в любом случае допускает ошибки и частично их можно смягчить, построив множества второго уровня следующим образом:
- Фиксируем какой-то отдельный образец изображений символов (не участвующий ни в обучении, ни в тестировании);
- Мы пропускаем этот образец через обученный классификатор первого уровня, помечая каждое изображение меткой этого классификатора (групповой меткой);
- Для каждого символа рассматриваются все возможные группы, к которым изображения этого символа были отнесены классификатором первого уровня;
- Добавляем этот символ во все группы до тех пор, пока не будет достигнута необходимая степень покрытия T_acc;
- Полученные группы признаков мы считаем целевыми множествами второго уровня, для которых будут обучаться классификаторы.
Всего у нас есть 1000 изображений этого символа.
Тогда мы сможем добавить символ «А» в 5-ю группу и получить 98% покрытие этого символа.
Мы можем отнести его к 5-й и 2-й группам и получить охват 99,9%.
Или мы можем сразу распределить их по группам (5, 2, 6) и получить 100% покрытие.
По сути, T_acc устанавливает некоторый баланс между скоростью и качеством.
Чем он выше, тем выше будет итоговое качество классификации, но тем больше будут целевые наборы второго уровня и тем потенциально сложнее будет классификация на втором уровне.
Практика показывает, что даже при T_acc=1 увеличение размера наборов в результате описанной выше процедуры пополнения не столь существенно – в среднем примерно в 2 раза.
Очевидно, это будет напрямую зависеть от качества обученного классификатора первого уровня.
Вот пример того, как это дополнение работает для одного из наборов из того же разделения на 500 групп, приведенного выше:
Результаты внедрения модели
Обученные двухуровневые модели наконец оказались быстрее и лучше, чем использовавшиеся ранее классификаторы.На самом деле «подружиться» с одним и тем же графом линейного деления (ЛДГ) оказалось не так-то просто.
Для этого нам пришлось отдельно обучать модель отличать символы от априорного мусора и ошибок сегментации строк (в таких ситуациях возвращать низкую достоверность).
Конечный результат встраивания в полный алгоритм распознавания документов представлен ниже (получен на коллекции китайских и японских документов), скорость указана для полного алгоритма:
Мы повысили качество и ускорили как обычный, так и быстрый режимы, а все распознавание символов перенесли на нейронные сети.
Немного о сквозном распознавании
Сегодня большинство общеизвестных систем OCR (тот же Tesseract от Google) используют архитектуры End-to-End нейронных сетей для распознавания целых строк или их фрагментов.Здесь мы использовали нейронные сети именно как замену отдельному модулю распознавания символов.
Это не случайно.
Дело в том, что разбиение строки на символы в печатном китайском и японском языках не является большой проблемой из-за моноширинный Распечатать.
В связи с этим использование End-to-End распознавания для этих языков не сильно улучшает качество, но значительно медленнее (по крайней мере, на CPU).
И вообще непонятно, как использовать предложенный двухуровневый подход в контексте End-to-End. Напротив, есть языки, для которых линейное деление на символы является ключевой проблемой.
Очевидными примерами являются арабский язык, хинди.
Для арабского языка, например, нами уже активно исследуются сквозные решения.
Но это совсем другая история.
Алексей Журавлёв, руководитель группы OCR «Новые технологии» Теги: #Машинное обучение #gpu #искусственный интеллект #нейронные сети #машинное обучение #CPU #сквозной #алфавит #сверточные нейронные сети #lenet #abbyy #иероглифы #kmeans #MNIST #WideResNet #squeezenet
-
Монгольские Языки
19 Oct, 24 -
Подвергаем Модель Gpt-3 Тесту Тьюринга
19 Oct, 24 -
Поддержка Протокола Spdy В Node.js
19 Oct, 24 -
Директор Vcloud
19 Oct, 24 -
Создание Собственного Веб-Файла
19 Oct, 24