Tesseract-OCR在第3版以前用的是傳統的辨識引擎(legacy engine),從第4版開始,Tesseract-OCR引入LSTM這種以深度學習為基礎的辨識引擎(LSTM engine),使得辨識的準確度能進一步獲得提升,因此本指南將針對LSTM訓練相關的知識與技巧進行說明。
中文屬於表意文字,因此中文系統中有著數以萬計的中文字用以表意,從模型訓練的角度來看這意味著一件事,若要建構「全中文字通用的OCR辨識模型」,將會有數萬個類別(label值),從手寫數字數據集-MNIST類別與訓練資料的比例為10:60000來看,這表示訓練通用模型至少需要上千萬筆的訓練資料,因此不可能也不需要訓練這樣一個全中文字通用的模型,即便有這樣一個模型,辨識速度也可能因為模型過於龐大而變慢。
從實務上來講,官方已有提供相對較通用且準確的辨識模型,只要以該辨識模型做為基礎,接著對模型進行微調(Fine tune)的動作,就能針對特定辨識錯誤的字詞加強訓練,切記,只需對關鍵字進行訓練,訓練過多的冗餘字,只會造成模型肥大效能下降,官方目前已經針對不同應用情境訓練對應的模型,如下表所示:
模型名稱 | 類型 | 應用情境 | 準確度 | 速度 | 專案連結 |
---|---|---|---|---|---|
tessdata | Both legacy & LSTM engine | 訴求辨識準確率註1 | 較佳 | 慢 | 點此 |
tessdata_best | Only LSTM engine | 用於模型的微調 | 佳 | 中 | 點此 |
tessdata_fast | Only LSTM engine | 訴求辨識速度快 | 中 | 快 | 點此 |
官方其實已經提供了很好的辨識模型,所以如果辨識關鍵字的辨識效果還堪用,那就就直接用就好,因為訓練的成本偏高,但如果關鍵字的辨識能力不足,那麼再繼續往下參閱說明。
我們選用的是上表所呈現的tessdata專案,該專案能啟動雙引擎辨識模式,較耗時但較準確。
下載完後將模型傳到下列路徑的目錄中。
C:\Program Files\Tesseract-OCR\tessdata
tesseract [pic to be tested] [output file name] -l [lang] --psm [num] --oem [num]
--psm [num]
表示Page segmentation modes(分頁模式)註2,實務上設6為佳。--oem [num]
表示OCR Engine modes(OCR 引擎)模式註3。tesseract test.png result -l chi_tra --psm 6 --oem 2
代碼 | 意義 |
---|---|
0 | Orientation and script detection (OSD) only. |
1 | Automatic page segmentation with OSD. |
2 | Automatic page segmentation, but no OSD, or OCR. (not implemented) |
3 | Fully automatic page segmentation, but no OSD. (Default) |
4 | Assume a single column of text of variable sizes. |
5 | Assume a single uniform block of vertically aligned text. |
6 | Assume a single uniform block of text. |
7 | Treat the image as a single text line. |
8 | Treat the image as a single word. |
9 | Treat the image as a single word in a circle. |
10 | Treat the image as a single character. |
11 | Sparse text. Find as much text as possible in no particular order. |
12 | Sparse text with OSD. |
13 | Raw line. Treat the image as a single text line, bypassing hacks that are Tesseract-specific. |
代碼 | 意義 |
---|---|
0 | Legacy engine only. |
1 | Neural nets LSTM engine only. |
2 | Legacy + LSTM engines.(雙引擎辨識模式) |
3 | Default, based on what is available. |
目的: 將字型套用在給定的字集生成圖檔
產出:
[lang].[fontname].exp[num].tif
文件[lang].[fontname].exp[num].box
文件指令格式:
text2image --text="[text file path]" --outputbase="[lang].[fontname].exp[num]" --fontconfig_tmpdir="[temp directory]" --font="[fontname]" --fonts_dir="[fontname directory]"
指令說明:
以下針對text2image
的常用參數選項功能進行說明:
--text="all_chi_new.txt"
是要進行訓練的樣本文件路徑。--outputbase="chi_tra.MicrosoftJhengHei.exp0"
欲生成.tif
和.box
文件的路徑與名稱。--fontconfig_tmpdir="%temp%"
字型組態檔的暫存位置(填環境變數即可),不填會報錯。--font="Microsoft JhengHei"
字型名稱(不見得是檔名,通常要特別去查)註5註6。--fonts_dir="C:\Windows\Fonts"
原則上是填系統字型文件的路徑,也可以自訂路徑。若想進一步瞭解各種參數選項的功能與用法,可直接在terminal輸入text2image
參閱。
指令範例:
text2image --text="all_chi_new.txt" --outputbase="chi_tra.MicrosoftJhengHei.exp0" --fontconfig_tmpdir="%temp%" --font="Microsoft JhengHei" --fonts_dir="C:\Windows\Fonts"
中文名稱 | 樣式 | 對應英文名稱 |
---|---|---|
微軟正黑體 | Regular | Microsoft JhengHei |
微軟正黑體 | Bold | Microsoft JhengHei Bold |
微軟正黑體 | Light | Microsoft JhengHei weight=290 |
新細明體 | Regular | mingliub |
標楷體 | Regular | DFKai-SB |
蘋方體 | Ultralight | PingFang TC Ultralight |
蘋方體 | Light | PingFang TC Light |
蘋方體 | Thin | PingFang TC Thin |
蘋方體 | Regular | PingFang TC Regular |
蘋方體 | Medium | PingFang TC Medium |
蘋方體 | Semibold | PingFang TC Semibold |
填入字型名稱時,--font
須填入正確的fontname,該空格就要空格,但是--outputbase
出現空格則會報錯,正確範例如下:
--font="Microsoft JhengHei weight=290"
--outputbase="chi_tra.MicrosoftJhengHeiLight.exp0"
.box
文件重建目的: 由於LSTM訓練一次只接受一整排框,而不是一格格的文字框,而在行末還需要一行\t
表示該行結束,因此需透過tesseract
指令中的wordstrbox
參數重建.box
文件,在訓練的資料量較大時,此步驟相當耗時,若不做可能會報錯,但即便沒報錯,訓練時的錯誤率(loss)也會極高。
格式:
# .box file with wordstrbox format
1 148 127 268 151 0
2 148 127 268 151 0
3 148 127 268 151 0
4 148 127 268 151 0
5 148 127 268 151 0
6 148 127 268 151 0
7 148 127 268 151 0
8 148 127 268 151 0
148 127 268 151 0
產出:
[lang].[fontname].exp[num].box
文件指令格式:
tesseract [lang].[fontname].exp[num].tif [lang].[fontname].exp[num] -l [lang] --psm [num] wordstrbox
指令說明:
以下針對tesseract
用於「構建wordstrbox格式的.box文件」的參數選項功能進行說明:
-l [lang]
指定欲使用的辨識語言e.g. chi_tra。wordstrbox
表示欲構建wordstrbox格式的.box文件。若想進一步瞭解各參數選項的功能與用法,可在terminal輸入tesseract --help-extra
參閱。
指令範例:
tesseract chi_tra.MicrosoftJhengHei.exp0.tif chi_tra.MicrosoftJhengHei.exp0 -l chi_tra --psm 6 wordstrbox
目的: 透過.box
與.tif
檔產生.lstmf
檔,用於模型訓練。
產出:
[lang].[fontname].exp[num].lstmf
文件指令格式:
tesseract [lang].[fontname].exp[num].tif -l [lang] --psm [lang] lstm.train
指令說明:
以下針對tesseract
用於「構建.lstmf文件」的參數選項功能進行說明:
lstm.train
表示欲構建.lstmf文件。指令範例:
tesseract chi_tra.MicrosoftJhengHei.exp0.tif chi_tra.MicrosoftJhengHei.exp0 -l chi_tra --psm 6 lstm.train
目的: 將tessedata_best
所下載的chi_tra.traineddata
中擷取chi_tra.lstm
文件註7。
產出:
[lang].lstm
文件指令格式:
combine_tessdata -e [target .traineddata file] [target file to extract]
指令說明:
以下針對combine_tessdata
的常用參數選項功能進行說明:
-e
可從.traineddata
中擷取出特定的文件-u
可從.traineddata
中擷取出所有文件至特定資料夾。-o
可將某文件覆寫進.traineddata
的文件。指令範例:
combine_tessdata -e chi_tra.traineddata chi_tra.lstm
若想進一步瞭解各參數選項的功能與用法,可直接在terminal輸入combine_tessdata
參閱。
tessedata_best
的.lstm
文件為基礎,而是要確定.traineddata
需為基於LSTM模型所訓練,但由於tessedata_best
是官方所提供訓練較全面且準確的模型,因此通常以tessedata_best
為基礎。目的: 建立一個文件檔,提供訓練檔的路徑。
產出:
[lang].training_files.txt
文件文件內容註8:
chi_tra.MicrosoftJhengHei.exp0.lstmf
.lstmf
檔的路徑,超過會報錯,請務必留意。目的: 將所有前置作業所準備好的文件用來進行訓練。
產出:
[name]_checkpoint
文件[name]_[error_rate]_[iterations].checkpoint
文件指令格式:
lstmtraining --model_output="[directory of output]" --continue_from="[path to lstm]" --traineddata="[path to .traineddata file]" --train_listfile="[path to train_listfile]" --target_error_rate=[float]
指令說明:
以下針對lstmtraining
用以「訓練模型」的參數選項功能進行說明:
--model_output
指定模型訓練完所輸出的路徑。--continue_from
指定LSTM模型的路徑,以該模型繼續訓練。--train_listfile
指定存放欲被訓練之.lstmf
檔的文件路徑。--traineddata
指定.traineddata
文件路徑。--target_error_rate
指定模型準確度收斂的標準(停止標準)。--debug_interval
(optional)預設為0,每100個迭代輸出進度報告,若為-1則改為每次迭代輸出進度。若想進一步瞭解各參數選項的功能與用法,可直接在terminal輸入lstmtraining
參閱。
指令範例:
lstmtraining --model_output="dist" --continue_from="chi_tra.lstm" --traineddata="chi_tra.traineddata" --train_listfile="chi_tra.training_files.txt" --target_error_rate=0.01
目的: 模型訓練完產生的[name]_checkpoint
文件表示模型參數,將其寫入模型。
產出:
[lang].traineddata
文件指令格式:
lstmtraining --stop_training --continue_from="[path to [name]_checkpoint file]" --traineddata="[path to .traineddata file]" --model_output="[directory of output]"
指令說明:
以下針對lstmtraining
用以「模型輸出」的參數選項功能進行說明:
--stop_training
表示將training model轉換為runtime model。--continue_from
指定[name]_checkpoint
文件的路徑,以轉換為runtime model。--traineddata
指定將被更新model的.traineddata
文件路徑。--model_output
指定模型訓練完所輸出的路徑。若想進一步瞭解各參數選項的功能與用法,可直接在terminal輸入lstmtraining
參閱。
指令範例:
lstmtraining --stop_training --continue_from="dist_checkpoint" --traineddata="chi_tra.traineddata" --model_output="dist"
將[lang].traineddata
放入系統的~\Tesseract-OCR\tessdata
後,接著將terminal的目錄切換到要測試的圖片目錄底下,即可開始進行測試。
指令範例:
tesseract test.png result -l chi_tra --psm 6
Tesseract OCR發現.box
文件格式錯誤,通常發生在訓練LSTM模型時,因為LSTM訓練一次只接受一整排框,而不是一格格的文字框,而在行末需要一行\t表示該行結束。
確保有Step2與Step3有確實完成,並直接跳到Step.6。
在[lang].traineddata
文件中有包含許多模型相關的文件,其中一個是unicharset
文件,裡面記錄著該辨識模型所能辨識的字,相當於LSTM模型能夠分類圖像的類別數量,因此當訓練資料中出現unicharset
文件沒紀錄的字元時,就相當於模型輸入未知的類別(label),所以就會報出這個錯誤。
針對unicharset
文件中「沒有被紀錄的字」新建一個unicharset
文件,並包裝成一個新的[lang].traineddata
文件對於舊的(欲訓練的)[lang].traineddata
文件進行訓練,使得原有LSTM模型能夠「支援新類別」也能夠「正確辨識新類別」,因此,也需要針對「欲新增的類別(字)」準備一份訓練文本讓模型訓練。
此步驟相當費工,要擴充的新字除非很關鍵,否則千萬不要貪心的認為反正都要做了,那就連同一些罕用字或特殊符號都一起擴充,這可能會造成樣本蒐集不足,導致模型無法收斂,也可能造成模型訓練成本(時間、精力)過高,甚至使模型過於龐大而造成效能不足。
Step1. unicharset
文件中「沒有被紀錄的字」獲取
[lang].traineddata
文件,並從中找到unicharset
文件,接著可以透過自行撰寫程式,進而過濾訓練文本中有哪些未被unicharset
文件所記錄到的文字而保留下來。unicharset
文件所記錄到的文字。combine_tessdata -u [path of target file]
combine_tessdata -u dist/chi_tra.traineddata
Step.2 .box
文件獲取
text2image
指令能將文字轉為.tif
與.box
。.box
文件。text2image --text="[path to text file]" --outputbase="[lang].[fontname].exp[num]" --fontconfig_tmpdir="[directory of temp]" --font="[fontname]" --fonts_dir="[directory of fontname]"
text2image --text="all_chi_new.txt" --outputbase="chi_tra.MicrosoftJhengHei.exp0" --fontconfig_tmpdir="%temp%" --font="Microsoft JhengHei" --fonts_dir="C:\Windows\Fonts"
Step.3 unicharset
文件構建
unicharset_extractor
指令能將.box
文件轉為unicharset
文件。unicharset
文件。unicharset_extractor --output_unicharset [path to unicharset] --norm_mode 1 [path to .box file]
unicharset_extractor --output_unicharset chi_tra.unicharset --norm_mode 1 chi_tra.MicrosoftJhengHei.exp0.box
Step.4 unicharset
文件的字元屬性設定
set_unicharset_properties
指令,將讀取官方所提供langdata註9內的資訊,寫入unicharset
文件的字元屬性中。unicharset
文件。set_unicharset_properties -U [path to unicharset] -O chi_tra.unicharset --script_dir [directory of langdata]
set_unicharset_properties -U chi_tra.unicharset -O chi_tra.unicharset --script_dir dist\langdata-master
Step.5 新建.traineddata
文件打包
unicharset
文件重新打包成.traineddata
文件,以備後續訓練進行使用。.traineddata
文件combine_lang_model --input_unicharset [path to unicharset] --lang [lang] --script_dir [directory of langdata] --output_dir [directory of output]
combine_lang_model --input_unicharset chi_tra.unicharset --lang chi_tra --script_dir dist\langdata-master --output_dir dist
Step.6 訓練資料準備
unicharset
文件所記錄的文字用於建構訓練的語料,可用不同的字型、角度、雜訊等等方式產出圖片,並接續產出所有訓練所需的檔案。[lang].[fontname].exp[num].box
文件[lang].[fontname].exp[num].tif
文件[lang].[fontname].exp[num].lstmf
文件[lang].training_files.txt
文件# 文字轉圖像
text2image --text="training_text.txt" --outputbase="chi_tra.MicrosoftJhengHei.exp0" --fontconfig_tmpdir="%temp%" --font="Microsoft JhengHei" --fonts_dir="C:\Windows\Fonts" --xsize=2000 --ysize=3000
# .box文件重建
tesseract chi_tra.MicrosoftJhengHei.exp0.tif chi_tra.MicrosoftJhengHei.exp0 -l chi_tra --psm 6 wordstrbox
# 模型訓練檔構建
tesseract chi_tra.MicrosoftJhengHei.exp0.tif chi_tra.MicrosoftJhengHei.exp0 -l chi_tra --psm 6 lstm.train
Step.7 寫入新unicharset
文件並訓練模型
unicharset
文件打包成的新traineddata
文件traineddata
文件擷取出來的lstm
模型traineddata
文件.lstmf
檔的training_files
文件。.traineddata
文件lstmtraining --model_output="dist" --continue_from="chi_tra.lstm" --traineddata="dist\chi_tra\chi_tra.traineddata" --old_traineddata="chi_tra.traineddata" --train_listfile="chi_tra.training_files.txt" --target_error_rate=0.05
--traineddata
指定新traineddata
文件的路徑--old_traineddata
指定原traineddata
文件的路徑Step.8 將訓練結果寫入新模型
[name]_[error_rate]_[iterations].checkpoint
文件寫入模型,更新版的模型就會支援新字元並且具備辨識能力,後續就能以該模型為基礎,針對其它辨識效果不佳的字元加強訓練。.traineddata
文件lstmtraining --stop_training --continue_from="dist_0.012_360000_360000.checkpoint" --traineddata="dist\chi_tra\chi_tra.traineddata" --old_traineddata="chi_tra.traineddata" --model_output="dist\chi_tra.traineddata"
日月光