Мы в Smart Engines много пишем про распознавание документов. И, конечно, для распознавания документов нам требуется обучать нейросети, в частности, сети, распознающие текст на картинке. А им, как известно, нужно больше золота данных. И сегодня мы бы хотели поговорить о влиянии обучающих данных на итоговую сеть и о том, как такие данные синтезировать.
Для начала поговорим о создании обучающих данных в целом и сразу постулируем, что синтез и аугментации - это разные этапы работы с данными. Аугментация - это процесс увеличения уже существующей (собранной или синтезированной) выборки изображений (про нее мы писали несколько постов, например, этот). Синтез - это процесс создания исходной выборки. И в данном посте мы будем говорить именно о синтезе. В задаче оптического распознавания текста синтез, опять-таки, делится на два этапа: создание текста и создание картинок с этим текстом. В большинстве существующих работ внимание уделяют только второй части, говорят о важности разнообразия шрифтов и кегля, иногда о фонах (что уже лежит на стыке с аугментацией), однако очень редко говорят непосредственно о создании текста и его влиянии на итоговую распознающую сеть. Именно о важности непосредственно текста, а не его изображения, мы бы хотели рассказать. Как правило, можно встретить два варианта создания текста:
Чистый рандом. Если нам нужно распознавать поля с русским алфавитом, цифрами и пробелами, то просто будем случайно выбирать следующий символ и его печатать. Такой текст на взгляд постороннего человек выглядит как случайная последовательность (коей и является), в нем нет никакой связи между рядом стоящими символами и возможны любые диграммы.
Тексты из книг и интернета. Берем тексты с нужным алфавитом и печатаем. Текст абсолютно человекочитаем. И человек и машина могут вывести закономерности, например, большинство текстов на русском покажут, что нет слов, начинающихся с “Ы” и не встречаются диграммы “чя-щя” или “жы-шы”.
Мы не зря делаем упор на возможность вывода закономерностей. Дело в том, что еще в посте мы показывали на примере Tesseract OCR, что распознающие сети, обученные на данных, в которых есть много сильных закономерностей, начинают проигрывать сетям, обученным на рандомных (или около рандомных, об этом чуть позже) данных, на изображениях, содержащих текст, не соответствующий выведенным закономерностям. Примером таких изображений в системах распознавания ID документов является МЧЗ, она MRZ, она же машиночитаемая зона (показана на картинке в красной рамке).
Как можно заметить, МЧЗ (про ее распознавание мы писали отдельный пост), с одной стороны, абсолютно не рандомна, она описана в международном стандарте ICAO, с другой - не соответствует нормальной модели языка, то есть не содержит закономерностей, типичных для английского. В уже упомянутом мы для обучения наших распознающих моделей генерировали текст, введя несколько эвристик, в частности запретили “заборчики” - строки вида “ПфрАЕНПАЛсва”, указали, что слова могут начинаться с заглавных букв, увеличили вероятность пробела относительно букв. Однако такой подход будет существенно усложнять систему с каждой новой эвристикой, к тому же, часть свойств мы можем замечать, но не можем их нормально формализовать, в особенности для непривычных языков. Соответственно, мы решили, что нужен способ задавать закономерности для генерируемого текста, легко расширяемый на новые языки и новые специфические поля (по типу МЧЗ) и не требующий глубоких знаний об искомых закономерностях.
Нейронные сети в синтезе тексте
Нейросети, в частности, всем известная ChatGPT, хорошо научились синтезировать данные для полностью человекочитаемых текстов при должной сложности модели. Нам нужны не человекочитаемые тексты, а тексты, отражающие какие-то простые закономерности. Однако в целом идея использовать нейронные сети для генерации текста хороша, а главное, предполагает универсальность и расширяемость метода. По сути, для нашей задачи нужно создать легкую языковую модель, перед которой не стоит задача создавать нормальный текст. Наша сеть должна извлекать какие-то предполагаемые свойства из строк и помогать создавать новые последовательности.
Частота символов
Одной из интересных закономерностей является частота встречаемости различных кластеров символов в целевых текстах. Под кластерами мы подразумеваем каким-то образом заранее заданные группы, на которые можно разделить все символы. Например, можно сказать, что каждая буква, независимо от регистра, принадлежит отдельному кластеру и тогда число кластеров будет равно размеру алфавита (для русского языка 33 кластера), можно поделить с учетом регистра и тогда для русского алфавита кластеров будет уже 66, а можно наоборот сказать, что независимо от регистра мы все гласные собираем в один кластер, а все согласные - в другой, и тогда кластеров будет всего 2. Тут важно отметить, что для обучения моделей такого типа необходимо иметь текстовые данные (не картинки!), задающие целевые поля, ведь статистика распределения кластеров (как бы мы их не задали) сильно меняется, например, от поля к полю документа (скажем, в датах буквы бывают сильно реже, чем в именах).
В качестве легкой модели для генерации текста мы предлагаем использовать нейросеть, которая берет на вход последовательность из N кластеров, а на выход выдает следующий кластер. В качестве архитектуры сети мы взяли полносверточную сеть с ~6к параметров (представлена в таблице ниже, rf - наша оригинальная функция [1]). Конечное число параметров сети зависит от размера последнего слоя, где число выходов Х равно числу заранее заданных кластеров. Интересно, что так как и архитектура и входные данные очень легкие сеть учится практически моментально.
# | Тип | Функция активации | Параметры |
1 | Conv | ReLU | 32 фильтра 4х1, шаг 1х1, без отступов |
2 | Conv | ReLU | 32 фильтра 1х1, шаг 1х1, без отступов |
3 | Conv | ReLU | 64 фильтра 4х1, шаг 1х1, без отступов |
4 | Conv | rf[1,1] | 32 фильтра 1х1, шаг 1х1, без отступов |
5 | Conv | rf[1,1] | 16 фильтров 1х1, шаг 1х1, без отступов |
6 | Softmax | Х выходов |
Применение, оно же инференс
Для начала работы нам необходим первый входной вектор. Мы решили, что стоит брать случайный вектор нужного размера N, чтобы увеличить итоговое разнообразие полученных данных. Мы последовательно запускаем сеть, подавая ей на вход последние N элементов текущей сгенерированной строки, получаем (N+1)ый элемент, а точнее вектор псевдоверятностей для каждого кластера. Далее, на основе вероятностей из полученного вектора мы выбираем (N+1)ый кластер. Мы не всегда берем элемент с наибольшим конфиденсом, чтобы увеличить разнообразие данных. Далее, определив кластер, мы случайным образом выбираем элемент этого кластера, добавляем его в строку и продолжаем по кругу. Подробнее этот процесс можно увидеть на рисунке. После создания строки необходимой (заранее заданной) длины процесс прекращается. После создания необходимого числа строк они печатаются на фон. Для печати на фон у нас есть заранее определенное множество шрифтов в TrueType или OpenType формате и заданный набор фонов, например, стандартные фоны с бланков, фотографии стен и тд. Печать производится с помощью открытых библиотек работы со шрифтами, например, cairo.
И снова про МЧЗ
Итак, вернемся к МЧЗ. МЧЗ состоят из заглавных английских букв, цифр и “лычек”, то есть знаков меньше “<”. Мы решили разделить все символы на следующие группы: согласные буквы, гласные, цифры, знаки препинания (в нашем случае “<”) и пробелы. Пробелы тут нужны для эффективного использования итоговой распознающей сетки, по сути, пробелы для нее - признака начала и конца строки. Если не добавить пробелов, то после окончания строки МЧЗ, сеть радостно распознает фон как символы (и мы даже писали отдельно про распознавание пробелов).
Для обучения сети генерации текста для МЧЗ мы взяли разметку из открытого датасета, в котором чуть больше 11к МЧЗ, в каждой из которых по 2-3 строки. Каждый символ в строке кодируется соответствующим кластером, то есть гласным/согласным/цифрой/лычкой. Далее все строки склеиваются в одну ооочень длинную строку, в начало которой добавляется N пробелов, в наших экспериментах N = 4. Последовательность символов была разделена на отдельные слова длиной N+1, образуя последовательность символов w = (s1, s2, s3, s4, s5), где s1−4 представляют входные данные для обучения нейронной сети, а s5 - прогнозируемый класс. Для получения большего числа обучающих данных слова вырезаются с шагом 1 по строке. Всего мы получили порядка 1 млн слов, то есть обучающих примеров.
В рамках постановки данного эксперимента нужно отдельно отметить, что в случае 5 кластеров и N = 4 сеть может показаться излишней, ведь можно было бы просто посчитать зависимости выходов от входов “вручную”. Однако, как говорилось выше, сеть позволит нам разработать универсальный подход с понятным методом обучения, включая создание данных, в то время как инженерный подход может начать буксовать при увеличении числа кластеров или N. Например, чуть дальше будет описана сеть, где каждый символ алфавита - отдельный кластер и для нее уже нужно предподсчитывать более 2 млн вариантов. В случае же более широкого алфавита поля это число станет еще больше.
Эксперименты
Для начала, возможно, вас заинтересовало, почему мы взяли 5 кластеров, а не сказали, что каждый символ алфавита - это отдельный кластера. Мы тоже задумались, так ли верна наша интуитивная догадка, и поэтому обучили две сети: с 5 кластерами и с 38. На картинках ниже можно посмотреть на результаты синтеза в трех вариантах: чистый рандом, 5 кластеров и 38 кластеров.
А на гистограмме можно посмотреть на распределение числа символов в каждом случае.
Использование сети для генерации данных с 5 кластерами сократило количество пробелов на 60% по сравнению со случайным выбором символов. Напротив, количество символов-заполнителей “<“ увеличилось почти в 13 раз. Каждая гласная встречается в строках почти в два раза чаще, чем согласная.
Далее мы приступили к задаче распознавания МЧЗ. Мы взяли картинки строк МЧЗ из открытого датасета MIDV-500, содержащего 5к строк МЧЗ. Мы обучили три распознающие сетки в соответствии с тремя способами генерациями, приведенными выше, и сравнили их качество с Tesseract OCR 5. Результаты приведены в таблице, где PCRRC - это сеть, для обучения которой текст создавался рандомно, PCRFA - сеть, где в синтезе текста было 38 кластеров, PCRNN - сеть, где в синтезе текста 5 кластеров. Качество распознавания мы оценивали по формуле
Датасет | Кол-во полей | Tesseract 5 | PCRRC | PCRFA | PCRNN |
MIDV-500 | 5096 | 58.01 | 93.16 | 92.45 | 93.85 |
По таблице видно, что использование предсказывающей сети с 5 кластерами при обучении положительно влияет на результаты распознавания. Сеть, обученная на рандомных данных, проигрывает, так как у нее нет никакого выученного контекста. При этом, по результатам Тессеракта видно, что полное отсутствие контекста лучше, чем присутствие неправильного контекста.
Заключения
В этом посте мы описали очень простую сеть, позволяющую усовершенствовать систему синтеза обучающих данных и добавить ей много интересных возможностей, и показали положительное влияние такой сети на распознавание. Вообще, мы считаем, что важной частью успеха является умение грамотно пользоваться доступными средствами. Так, не нужно пытаться синтезировать человекочитаемый текст, если он вам не нужен. При этом помните, что качество обучающих данных оказывает гигантское влияние на итоговую сеть. Зачастую для улучшения распознавания нужно не переподбирать архитектуру, а посмотреть на данные и понять, чего в них не хватает, как делаем мы, создавая новые для сети для наших OCR продуктов.
[1] Gayer A. V., Sheshkus A. V., Nikolaev D. P., Arlazarov V. V. Improvement of U-Net Architecture for Image Binarization with Activation Functions Replacement // ICMV 2020 / Bellingham, Washington 98227-0010 USA: Society of Photo-Optical Instrumentation Engineers (SPIE). — янв. 2021. — Т. 11605. — ISSN 0277-786X. — ISBN 978-15-10640-40-5. — 2021. — Т. 11605. — С. 116050Y1-116050Y9. — DOI: 10.1117/12.2587027.