Tesseract4の再学習・追加学習手順まとめ

2019年9月25日

当サイトはアフィリエイト広告を利用しています。

tesseractの学習方法であるScratch TrainingとFine Trainingの手順をまとめました。

以下の公式ページを参考にして書いてます。英語が得意な方はこちらにもお目通しを。
https://tesseract-ocr.github.io/tessdoc/tess4/TrainingTesseract-4.00.html

そもそも学習させる必要あるの?

Tesseractはバージョン4から新たなニューラルネットワークを用いた文字認識技術を使うようになりました。
これにより文字認識精度は格段に高まっています。

Tesseractバージョン4にデフォルトで準備されているモデル「tessdata_best」は大量のデータを学習して作られていますが、それでもまだうまく文字認識できないことがあります。またデフォルトで提供されているモデルでは学習されていない文字も存在します。例えば"±"(プラスマイナス)。学習されていない文字は認識することができません。("±"を追加学習により認識できるようにする手順もこの記事に載せています)

満足できる文字認識結果を出すためには、公式が提供しているモデルを再学習させ認識精度をあげる必要があります。

学習方法3種

3つの学習方法を紹介しますが、学習させるための手順はどれもほとんど同じです。

それぞれの学習方法に良い点、悪い点があるので、どの学習方法が自分の目的にあっているのか把握してから選びましょう。
大体の場合は最初に紹介する「Fine Tune」で問題ないです。

Fine Tune

「Fine Tune」はすでに存在するモデルに対し、自前で準備したデータを利用して再学習させる方法です。

この方法なら少数の学習データでも機能します。

一般的なフォントの文字でうまく認識できないことがある場合には、この方法が最適な可能性が高いです。

しかし一般的なフォントからはかけ離れた文字を対象とした認識をさせたい時には、うまくいかないこともあります。
これは元のモデルの影響が大きく残ってしまうためです。

Cut off and Retrain top layer of network

この学習はニューラルネットワークの上層(出力に近い層)を削除し、新たな学習データを用いて、新たな上層を再学習させる方です。

「Fine Tune」をした結果うまく認識できなかったら、このやり方を試してみましょう。

完全に新しい言語を学習させる時にうまく機能する可能性が高いです。

Retrain from scratch

1から自分の持つデータで学習させる方法です。

この方法はかなり大量かつ上質な学習データがないと、良い結果が出ません。

大抵の場合過学習に陥ってしまい、学習に使ったデータ以外ではうまく行かない可能性が高いでしょう。

学習を始める前に

これから学習の手順について説明しますが、学習を始める前に見ておくべきページを紹介しておきます。
Improving the quality of the output
このページには文字認識させる対象画像に対してやっておくべき前処理が書かれており、モデルを再学習させなくてもここに記載されている前処理をするだけでうまく認識出来るようになったりします。モデルの学習をさせる前に一度このページに従って前処理をして結果を確認することをお勧めします。

学習の手順

それでは本題のtesseractの学習方法の手順について。

この記事の一番上で紹介した公式ページにtesseractの学習チュートリアル(TessTutorial)というものがあったので、それに沿って説明します。

日本文字ではなくて英文字の追加学習の流れであることに注意してください。日本文字の学習も手順は変わらないです。

TessTutorialのための準備

使いたいフォントがすでに学習実行する予定のマシンにインストールされていることが前提条件です。
フォントのインストール方法は以下のページを参考にしてください。
Fonts for Tesseract training

使いたいフォントがマシンにインストールされていることを確認出来たら以下を順次実行していきます。

# 必要なパッケージのインストール
sudo apt update
sudo apt install ttf-mscorefonts-installer
sudo apt install fonts-dejavu

# 追加したフォントの有効化(フォントのキャッシュファイルの更新)
fc-cache -vf

# TessTutorial用のフォルダ作成&移動
mkdir ~/tesstutorial
cd ~/tesstutorial

# 言語データを取得
mkdir langdata
cd langdata
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/radical-stroke.txt
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/common.punc
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/font_properties
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/Latin.unicharset
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/Latin.xheights

# 英語の学習に必要なファイルをダウンロード
mkdir eng
cd eng
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.training_text
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.punc
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.numbers
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.wordlist

# tesseract本体のダウンロード
cd ~/tesstutorial
git clone --depth 1 https://github.com/tesseract-ocr/tesseract.git
cd tesseract/tessdata
wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata
wget https://github.com/tesseract-ocr/tessdata/raw/master/osd.traineddata
mkdir best
cd best
wget https://github.com/tesseract-ocr/tessdata_best/raw/master/eng.traineddata
wget https://github.com/tesseract-ocr/tessdata_best/raw/master/heb.traineddata
wget https://github.com/tesseract-ocr/tessdata_best/raw/master/chi_sim.trained

学習用データ作成

tesseractの学習用ファイルはlstmfファイルと呼ばれ、このファイルを使ってLSTMトレーニングというtesseractの学習を行います。

tesstrain.shというシェルスクリプトを使うことでlstmfファイルを作成することができます。

tesstrain.sh実行の準備

tesstrain.shを使うためにはクローンしてきたtesseractをインストールする必要があります。
インストール手順は以下の記事にまとめているのでご確認ください。

また特にtesseractのインストール手順で何をしているのかは特に知らなくても良いという方のために、実行するコマンドだけを抜粋して以下に載せておきます。

sudo apt-get install g++ # or clang++ (presumably)
sudo apt-get install autoconf automake libtool
sudo apt-get install pkg-config
sudo apt-get install libpng-dev
sudo apt-get install libjpeg8-dev
sudo apt-get install libtiff5-dev
sudo apt-get install zlib1g-dev
sudo apt-get install libicu-dev
sudo apt-get install libpango1.0-dev
sudo apt-get install libcairo2-dev
git clone https://github.com/DanBloomberg/leptonica.git
cd leptonica
./autogen.sh
./configure
make
sudo make install
cd ~/tesstutorial/tesseract
./autogen.sh
./configure
make
sudo make install
sudo ldconfig
make training
sudo make training-install

tesstrain.shの実行

LSTMトレーニング用のファイルを作成するのは以下のコマンドを実行します。

~/tesstutorial/tesseract$ src/training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \
  --noextract_font_properties --langdata_dir ../langdata \
  --tessdata_dir ./tessdata --output_dir ~/tesstutorial/engtrain

オプションの説明は以下です。

  • –font_dir: フォントのデータが格納されているディレクトリを指定
  • –linedata_only: lstmtraining用の学習データしか作らないようにする
  • –lang: 対象の言語を指定
  • –noextract_font_properties: フォントのプロパティを抽出しないようにする
  • –langdata_dir: 言語情報が格納されているディレクトリを指定
  • –tessdata_dir: 学習用データを作る際に利用する学習済みのデータのありかを指定
  • –output_dir: 学習用データの出力先を指定

追加学習にどれだけの効果があったのか確認するために、評価用のデータも作成しておきます。

先ほどのコマンドとの違いは–fontlistオプションがついて、"Impact Condensed"というフォントのみを対象としてLSTM training用のファイルを作成していることです。

~/tesstutorial/tesseract$ src/training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \
  --noextract_font_properties --langdata_dir ../langdata \
  --tessdata_dir ./tessdata \
  --fontlist "Impact Condensed" --output_dir ~/tesstutorial/engeval

lstmtraining

まずはスクラッチ学習(Training from Scratch)のやり方について紹介します。

「Fine Tune」の説明はその後で行います。「Fine Tune」のチュートリアルの際にはスクラッチ学習の結果も利用するので、スクラッチ学習も行ってください。

Training From Scratch

上記のtesstrain.shの出力結果を使ってスクラッチ学習を実行します。
lstmtrainingにはかなり時間がかかります。これは5000回繰り返し学習しているためです。

mkdir -p ~/tesstutorial/engoutput
training/lstmtraining --debug_interval 100 \
  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
  --net_spec '[1,36,0,1 Ct3,3,16 Mp3,3 Lfys48 Lfx96 Lrx96 Lfx256 O1c111]' \
  --model_output ~/tesstutorial/engoutput/base --learning_rate 20e-4 \
  --train_listfile ~/tesstutorial/engtrain/eng.training_files.txt \
  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt \
  --max_iterations 5000 &>~/tesstutorial/engoutput/basetrain.log

別のターミナルを開いて以下のコマンドを実行すれば、ログを確認できます。

tail -f ~/tesstutorial/engoutput/basetrain.log

lstmtrainingが完了したら出来上がったモデルを精度を調査します。

試しに"Impact"というフォントで今作ったモデルの精度を検証してみましょう。

training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \
  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

~/tesstutorial/engoutput/base_checkpointがスクラッチ学習で得られたモデルです。

一文字の誤認識率(Char error rate)は70~85%、
単語あたりの誤認識率(Word error rate)は90%以上になったりします。

つまりかなり精度が悪いです。上記のlstmtrainingでは4系より前のtesseractと同じ量の学習データを使って学習させているにもかかわらず散々な結果です。

そこで今度はデフォルトで準備されているtessdata_bestのeng.traineddataを使って精度を測ってみます。

training/lstmeval --model ~/tesstutorial/tesseract/tessdata/best/eng.traineddata \
  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

一文字の誤認識率(Char error rate)は約2.5%
単語あたりの誤認識率(Word error rate)は約8%

デフォルトのモデルを使用した方が圧倒的に良い精度が得られています。

スクラッチ学習を行う際には非常に大量で良質な学習データを準備しないと、精度の出るモデルは作成されないことが分かりました。

ちなみにscratch学習のmax_iterationsの値をさらに増やして行うと、全体的な誤認識率は下がりますが、学習セットで利用されていないフォントに対しては誤認識率が上がってしまいます。これは過学習の結果です。

Fine Tuning

それでは今度は先ほどスクラッチ学習で作成したモデルに対して、Fine Tuningを行って認識精度を上げていきます。

以下のコマンドを実行します。

mkdir -p ~/tesstutorial/impact_from_small
training/lstmtraining --model_output ~/tesstutorial/impact_from_small/impact \
  --continue_from ~/tesstutorial/engoutput/base_checkpoint \
  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
  --train_listfile ~/tesstutorial/engeval/eng.training_files.txt \
  --max_iterations 1200

上記のコマンドの中でも特に重要なコマンドが"–continue_from"。これはどのモデルから追加で学習するかを指定するオプションで、これが指定されることによってFine Tuningが行われます。

–continue_fromで指定するのは学習のチェックポイントファイルか文字認識用モデルです。
文字認識用モデルは"combine_tessdata"コマンドでtraineddataから作成することが出来ます。

training/combine_tessdata -e tessdata/best/eng.traineddata \
  ~/tesstutorial/impact_from_full/eng.lstm

また–train_listfileで指定されているファイルがスクラッチ学習の時とは異なり、engevalディレクトリ内のファイルに指定されていることにも注目しましょう。
engevalは"Impact"フォントを基に作られた学習用のファイルが格納されています。

このlstmtrainingの結果作成されたモデルで精度検証してみましょう。

training/lstmeval --model ~/tesstutorial/impact_from_small/impact_checkpoint \
  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

限りなくゼロに近いエラー率になったはずです。
私が実施した結果、Char error rateもWord error rateも0になりました。

これはFine tuningでモデルが改善された結果です。

ちなみに注意点があります。
tessdata_bestから持ってきたあらかじめ学習がされているモデルの場合にはイテレーション数を増やしすぎると誤認識率が上がってしまう恐れがあること。これは過学習が行われた結果であると考えられます。

誤認識率に注目しながら、過学習を起こさないよう注意しましょう。

新たな文字を追加するFine Tuning

Fine Tuningならモデルに無い新たな文字を追加学習することも出来ます。

ここでは例として"±"(プラスマイナス)という文字を追加する手順を説明します。

“±"を学習させるために、学習用のテキストである"langdata/eng/eng.training_text"を編集して、複数箇所(10箇所以上あると良い)に"±"を追記します。
数字の前に付けると文章としての意味が通るようになるので、文字の前後関係が学習対象となるLSTM学習をする上でおすすめです。

編集し終わったら、tesstrain.shでlstmtraining用のデータと評価用のデータを作成しましょう。

~/tesstutorial/tesseract$ src/training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \
  --noextract_font_properties --langdata_dir ../langdata \
  --tessdata_dir ./tessdata --output_dir ~/tesstutorial/trainplusminus
~/tesstutorial/tesseract$ src/training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \
  --noextract_font_properties --langdata_dir ../langdata \
  --tessdata_dir ./tessdata \
  --fontlist "Impact Condensed" --output_dir ~/tesstutorial/evalplusminus

作成したlstmtraining用のデータでlstmtrainingを実行します。

~/tesstutorial/tesseract/src$ training/combine_tessdata -e ../tessdata/best/eng.traineddata \
  ~/tesstutorial/trainplusminus/eng.lstm
~/tesstutorial/tesseract/src$ training/lstmtraining --model_output ~/tesstutorial/trainplusminus/plusminus \
  --continue_from ~/tesstutorial/trainplusminus/eng.lstm \
  --traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \
  --old_traineddata ../tessdata/best/eng.traineddata \
  --train_listfile ~/tesstutorial/trainplusminus/eng.training_files.txt \
  --max_iterations 3600

実行が完了したら以下のコマンドを入力して、
“±"の学習が正常に行われているか確認してみましょう。

~/tesstutorial/tesseract/src$ training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \
  --traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \
  --eval_listfile ~/tesstutorial/evalplusminus/eng.training_files.txt 2>&1 |
  grep ±

Truthの行が実際文字列で、OCRの行がtesseractによる認識結果です。
“±"がきちんと認識できていることを確認できるはず。

今度は比較のために"±"を学習させていないモデルで、結果を確認してみましょう。

~/tesstutorial/tesseract/src$ training/lstmeval --model ~/tesstutorial/tesseract/tessdata/best/eng.traineddata \
  --eval_listfile ~/tesstutorial/evalplusminus/eng.training_files.txt 2>&1 | \
  grep ±

“Can’t encode transcription: ~"という出力があり、"±"が認識できていないようです。

つまり学習の結果、±"が認識出来るようになったことが分かりました。

再学習結果をモデルとして使える形にする

ここまで様々な再学習方法を学んできましたが、実は今までのlstmtrainingではcheckpointファイルを作っているだけで、
tesseractで利用できる形のモデル(~.traineddata)にはなっていません。

tesseractで利用できる形のモデルにするためには以下のようなコマンドの実行が必要です。

~/tesstutorial/tesseract/src$ mkdir -p ~/tesstutorial/new_trainedata
~/tesstutorial/tesseract/src$ training/lstmtraining --stop_training \
  --continue_from ~/tesstutorial/engoutput/base_checkpoint \
  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
  --model_output ~/tesstutorial/new_trainedata/eng.traineddata

ここでのポイントが–stop_training

このオプションを付けることで–continue_fromで指定したcheckpointファイルから新たなtraineddata(モデル)が作成されます。

作成されたら以下のように作成されたtraineddataを使って文字認識が行えるようになります。

# TESSDATA_PREFIX環境変数を設定
$ export TESSDATA_PREFIX=~/tesstutorial/new_trainedata/
# tesseractでの文字認識
$ tesseract -l eng 認識対象の画像ファイル名 stdout

-lで指定するtraineddataは"TESSDATA_PREFIX/~~~.traineddata"の~~~の部分だけで良いです。

以上でtesseractの再学習方法の解説は終わりです。

追加学習・再学習をするためには必要な手順が多いです。混乱するところもたくさんあると思いますが、何回も読み直して学習を成功させてほしいです。

おまけ

最後に私がtesseractのトレーニング方法を学んでいる中でメモしていた内容を載せておきます。

ハードウェア要件

  • マルチコアだと良いが必須では無い。
  • GPUはサポートしていないので使う意味はない。
  • メモリ使用量は–max_image_MBというオプションで指定できる。少なくともOSが使用する分を除いて1GBは欲しい。

学習の流れ概要

基本的にはTesseract 3.04の学習の流れと同じ

  1. 学習用のテキストデータを準備する
  2. テキストを画像ファイルとboxファイル(画像ファイルと対応する座標ファイルらしい。)に変える
  3. 画像ファイルとboxファイルからunicharsetファイルを作成する
  4. unicharsetと自由選択の辞書データから始まりとなるtraineddataを作成する
  5. 画像ファイルとboxファイルでtraining data set を作成する
  6. training data setで学習を行う
  7. 作成されたdata ファイルを結合させる
  8. 完了

参考情報として3系との重要な違いは以下

  • boxファイルが行単位での情報しか必要としていない。
    そのため処理の高速化が実現されている
  • .trファイルはlstmfファイルというファイルに置き換わった
  • フォントは分離するのではなく、自由に混合させることができる
  • 複数あったクラスタリングのステップは
    lstmtrainingという一つの処理に時間のかかるものに置き換わった

その他知っておくと良い点

  • combine_lang_modelというツールはunicharsetと任意の単語リストから
    starter traineddataを作成するためにある。
  • 学習中にはcheckpointファイルが作成される。
    このファイルのおかげで学習を途中で終えたり、続けて学習を行うことが出来るようになったりする。
  • 全てのcheckpointファイルは–stop_trainingというlstmtrainingのオプションで
    完全なtraineddataに変換することが出来る。
  • checkpointファイルは学習中、精度が上がってきたら定期的に作成される。
  • –continue_fromフラグで指定されたモデルで使われるunicharsetと
    –traineddataフラグで与えられたデータ内で使われるunicharsetが異なる際には、
    不足分のunicharsetを持つtraineddataを–old_traineddataとともに記載する必要がある。
  • .lstmfファイルはtifファイルとboxファイルから作られる。
  • .lstmファイルは複数の情報が格納されたデータであり、
    画像とそれに対応するUTF8テキストの情報を保持している。
    このlstmfファイルからtraining dataが作成される。

直近でおすすめの本

直近十数冊読んだ中で一番おすすめの本です。

人が行動をするに至るまでのステップを科学的に分析した上で、その結果を習慣と紐付けて解説してくれている本です。

悪い習慣を断ち、良い習慣を継続する方法を詳細に説明してくれています。習慣が人を作っているので、この本の内容を実践できれば人生を大きく好転させられる気がしました。

この本の最初の方に説明があるのですが、複利という考え方があり毎日1パーセントだけの増加でもそれが続くととてつもない倍率になります。これは投資でよく用いられる概念ですが、良い習慣は未来への投資なので習慣にもあてはまります。良い習慣を身に付けるのは早ければ早いほど良いです。

私はまず長時間YouTubeを見てしまう習慣を断って、直近の業務に役立つITの勉強を習慣として身に付けよう思います。