Как я дообучал Tesseract и что из этого получилось

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Вместо предисловия

Решал я как-то задачку по поиску сущностей в отсканированных документах. Чтобы работать с текстом, надо его сначала получить из картинки, поэтому приходилось использовать OCR. Выбор пал на одну из самых популярных и доступных библиотек Tesseract. С ее помощью задача решается очень неплохо и процент распознавания текста достаточно высокий, особенно на хороших сканах. Но нет предела совершенству, а так же ввиду наличия большого количества документов сомнительного качества, поулучшав пайплайн разными методами, было принято решение попробовать улучшить и сам тессеракт.

Инструкция от разработчиков https://tesseract-ocr.github.io/tessdoc/Home.html не всегда сразу понятна и очевидна, поэтому и появилась мысль записать свой опыт в эту статью.

У меня на компьютере стоит Linux Mint 20.2 Cinnamon, поэтому все действия происходят в этой системе и я не могу гарантировать, что все получится точно так же в Windows или Mac.

Для начала необходимо установить бибилиотеку tesseract на компьютер. Делается это достаточно просто. Сначала проверю версию, которая уже установлена (как правило в комплекте с Linux уже есть пакет tesseract). В терминале набираем

$ tesseract -v

У меня изначально был такой ответ:

tesseract 4.1.1
 leptonica-1.79.0
  libgif 5.1.9 : libjpeg 6b (libjpeg-turbo 2.0.6) : libpng 1.6.37 : libtiff 4.2.0 : zlib 1.2.11 : libwebp 0.6.1 : libopenjp2 2.4.0
  Found AVX
  Found SSE
  Found libarchive 3.4.3 zlib/1.2.11 liblzma/5.2.5 bz2lib/1.0.8 liblz4/1.9.3
 libzstd/1.4.8

Перед установкой новой версии, необходимо удалить текущую:

$ sudo apt-get remove tesseract-ocr

Теперь для начала делаем клон из репозитория Git:

$ git clone https://github.com/tesseract-ocr/tesseract.git

А затем необходимо выполнить по порядку несколько команд:

$ cd tesseract
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
$ make training
$ sudo make training-install

Перезапускаем терминал и проверяем версию:

$ tesseract -v
> tesseract 5.1.0-32-gf36c0
> leptonica-1.79.0 
>  libgif 5.1.9 : libjpeg 6b (libjpeg-turbo 2.0.6) : libpng 1.6.37 : libtiff 4.2.0 : zlib 1.2.11 : libwebp 0.6.1 : libopenjp2 2.4.0 
> Found AVX
> Found SSE4.1 
> Found OpenMP 201511

Осталось скачать языковые пакеты. Все не нужны, поэтому переходим по ссылке https://github.com/tesseract-ocr/tessdata и скачать только необходимые. Я скачивал eng.traineddata и rus.traineddata. В дальнейшем, при запуске тессеракт указывается флаг с каким языком необходимо работать, например: -l rus или -l eng , а можно комбинировать -l rus+eng. Скаченные данные необходимо поместить в папку: /usr/local/share/tessdata/

Теперь можно использовать библиотеку тессеракт с помощью командной строки в терминале, например:

$ tesseract image outputfile -l rus+eng

А теперь начнем файн-тюнить полученную модель. Этот процесс состоит из нескольких этапов:

  1. Разметка тренировочных данных

  2. Слепок текущей модели для начала дообучения

  3. Непосредственно дообучение модели

  4. Фиксация результатов

Для демонстрации я выбрал случайный документ, немного закрасил фамилии, чтоб не было разглашения личных данных.

1. Разметка тренировочных данных

Для создания разметки в тессеракте используются файлы с расширением .box и создаются они специальной командой:

$ tesseract testfile.png testfile --psm 6 -l rus+eng lstmbox

где lstmbox - как раз указывает на необходимость создания файла разметки, а --psm 6 указывает на способ создания боксов. Это построчный вариант, как правило самый часто используемый при обработке обычных текстов, про другие варианты можно почитать здесь запустив команду: $ tesseract --help-psm

На выходе получается файл testfile.box. На моем документе он выглядит так:

В файле с разметкой шесть столбцов. Разделитель пробел. Первый элемент - это непосредственно распознанный символ (или тоже пробел) затем через пробел указываются координаты бокса, в котором находится данный символ в виде x_min, y_min, x_max, y_max. Это если считать началом для ординаты левый нижний край картинки. Это немного отличается от привычных координат, когда ось ординат начинается с левого верхнего угла и опускается вниз, поэтому учитывайте этот момент. Что находится в шестом столбце я толком не нашел в документации, везде стоит 0, так и оставлял. Между боксами находится строка с теми же координатами, но у нее вместо символа и пробела в начале стоит символ табуляции /t

Самое сложное и долгое - это проверка файла разметки на правильность. Необходимо проверить все символы, правильно ли они распознались. А так же сверить верно ли модель определила боксы, не пропустила ли какие-то части текста. Я написал небольшой скрипт, который рисовал боксы из файла разметки на документе, чтобы увидеть "глазами" как это получается. Получилось вот так:

Видно, что тессеракт не совсем верно распознал где именно находится текст из-за плохого качества изображения. Так же отдельно собирается текст и проверяется правильность распознавания символов, удаляя мусорные знаки.

После того, как все файлы box будут готовы, необходимо сделать следующий шаг - преобразовать их в файлы lstmf. Именно их модель будет принимать на вход для обучения. Делается это с помощью следующей команды:

$ tesseract testfile.png testfile --psm 6 -l rus+eng lstm.train

где testfile.png - это наш исходный документ и должен он быть именно в png или tiff формате, testfile - имя файла .box указывается без расширения, подготовленный ранее, затем --psm 6 - способ формирования боксов, -l rus - какую модель использовать и lstm.train - непосредственно метод преобразования данных. Это необходимо сделать с каждым документом и результат сложить в отдельную папку.

2. Слепок текущей модели для начала дообучения

Сначала извлекаем данные из текущей модели, которые будем использовать как предобученную модель. Запускаем:

$ combine_tessdata 
		-e /usr/local/share/tessdata/rus.traineddata 
  	/home/andrey/Downloads/tesseract_train/rus.lstm

Здесь первым параметром я указывал полный путь к существующей модели, которую скачивал выше при установке тессеракта, а вторым параметром указан полный путь к слепку с расширением lstm, который будет использоваться в дальнейшем.

По тем инструкциям, что я нашел, данного шага должно быть достаточно, чтобы переходить к третьему этапу, но мне пришлось выполнить еще несколько команд, прежде, чем получилось идти дальше.

Итак, еще необходимо подготовить справочник символов, которые используются в файлах обучения. Команда собирает эти данные в файл, указанный флагом --output_unicharset из файлов указанных в конце, в моем случае это все *.box файлы из размеченных документов:

$ unicharset_extractor 
		--output_unicharset train/my.unicharset 
  	--norm_mode 2 docs/*.box

Теперь генерируется начальная модель на основе всех имеющихся моих данных, символов, которые встречаются в моих документах, а так же дополнительных справочниках по словам и цифрам.

$ combine_lang_model 
		--input_unicharset train/my.unicharset 
  	--script_dir /home/andrey/langdata_lstm/ 
  	--words /home/andrey/langdata_lstm/rus/rus.wordlist 
  	--numbers /home/andrey/langdata_lstm/rus/rus.numbers 
  	--puncs /home/andrey/langdata_lstm/rus/rus.punc  
  	--output_dir train/ --lang rus

Файлы, указанные в папке langdata_lstm я скачал с https://github.com/tesseract-ocr/langdata_lstm/tree/main/rus

3. Непосредственно дообучение модели

Осталось совсем немного и можно начинать тренировку. Команда для этого выглядит следующим образом:

$ lstmtraining 
  	--model_output output/ 
  	--continue_from model/rus.lstm 
  	--old_traineddata /usr/local/share/tessdata/rus.traineddata 
  	--traineddata train/rus/rus.traineddata 
  	--train_listfile train/rus.training_files.txt 
  	--eval_listfile eval/rus.training_files.txt 
  	--U train/my.unicharset 
  	--max_iterations 140000

--model_output output/ - папка куда сохраняется обученная модель (и чекпоинты)
--continue_from model/rus.lstm - подготовленная модель с помощью combine_tessdata
--old_traineddata /usr/local/share/tessdata/rus.traineddata - указание на родоночальную модель
--traineddata train/rus/rus.traineddata - здесь указывается модель, собранная командой combine_lang_model
--train_listfile train/rus.training_files.txt - файл со списком файлом lstm для тренировки модели
--eval_listfile eval/rus.training_files.txt - файл со списком файлов lstm для валидации модели
--U train/my.unicharset - указатель на приготовленный файл с используемыми символами
--max_iterations 500 - количество итераций

Я делал отдельный баш скрипт с перечнем всех указанных параметров и запускал его с сохраниением логов в обычный текстовый файл, чтобы можно было затем посмотреть результаты. На самом деле там не очень все интересно и я сам не до конца разобрался во всех сообщениях в процессе обучения, кроме явных параметров, как здесь:

2 Percent improvement time=82, best error was 100 @ 0
At iteration 82/100/105, Mean rms=1.658%, delta=9.201%,
char train=27.571%, word train=35.266%, skip ratio=5%,  
New best char error = 27.571 wrote best model:output/27.571_82.checkpoint wrote checkpoint.

В папке output в результате обучения у меня появилось некоторое количество файлов:

4. Фиксация результатов

Каждый указанный выше чекпоинт - это по существу дообученная модель, показывающая указанную в наименовании ошибку. Теперь надо зафиксировать результат, чтобы эту модель можно было использовать. Делается это достаточно легко:

$ lstmtraining 
		--stop_training 
  	--continue_from output/24.791_426.checkpoint 
  	--traineddata train/rus/rus.traineddata 
  	--model_output output/rus_ftuned.traineddata

--stop_training - флаг указывает на завершение обучения
--continue_from output/24.791_426.checkpoint - указываю файл чекпоинта, который хочу использовать
--traineddata train/rus/rus.traineddata - ранее подгттовленная модель
--model_output output/rus_ftuned.traineddata - куда сохранить результат

Я назвал свою дообученную модель rus_ftuned.traineddata. Теперь этот файл необходимо поместить к остальным языковым моделям тессеракта в папку /usr/local/share/tessdata/ , после чего ее можно использовать точно так же, как и любые другие, а так же в комбинации в другими языками. Например вот так:

$ tesseract image outputfile -l rus_ftuned+eng

Заключение

Для обучения модели у меня было 40 размеченных страниц документов - картинок. Всего ставил 140 тыс. итераций тренировки. Ошбика при этом опустилась с 27.571 до 3.832. На тестовых документах стало меньше мусорных символов. Качество распознавания улучшилось, но незначительно. При подсчете расстояния Левинштейна между референсным текстом и распознанным тессерактом, значение уменьшилось в среднем на 3% относительно длины текста. Цифра вроде небольшая, но чем больше текст, тем больше правильно распознанных букв и цифр. Так, например, на тексте из 3363 символов, начальная модель ошибалась в 296, а дообученная всего в 203.

В заключении хочу сказать, что дообучение тессеракта под определенные типы документов имеета право на жизнь. Самое главное и в то же время самое сложное - это ответственно подходить к разметке. Я этим не занимался, я получил файлы уже размеченные, но при беглом осмотре я находил небольшие ошибки и в размерах боксов и в символах. Возможно, если их исправить, то качество могло быть еще лучше.

Возможно, мой опыт кому-то пригодится. А если кто-то тоже уже занимался тренировкой тессеракта и заметил неточности, то буду благодарен если укажете.

Источник: https://habr.com/ru/post/669020/


Интересные статьи

Интересные статьи

А также с чего началась земная геология, и почему мы такие особенные в Солнечной системе. Момент рождения Луны можно для определённости представить как на этом фотоснимке, сделанном 4,5 миллиарда л...
В ноябре 2021 года Яндекс.Практикум запустил курс «Go-разработчик» для программистов, которые хотят добавить Go в свой стек. На курсе не рассказывают о базовых вещах, а сразу объясняют студенту, к...
В августе бизнес-аналитики из Санкт-Петербурга стартовали новый проект, который получил рабочее название «Проект Z». Они расширили возможности входа в бизнес-анализ для тех, у кого нет опыта работы, и...
Когда в вашем распоряжении одновременно оказывается мощное облако с инфраструктурой в США, Евросоюзе, СНГ, Азии и Австралии и CDN со 100 точками присутствия в 70+ городах на пяти континен...
Один из ключевых сценариев работы в CRM это общение с клиентом в удобном для него канале. По почте, по телефону, по SMS или в мессенджере. Особенно выделяется WhatsApp — интеграцию с ...