跳至內容。

如何訓練 LSTM/神經網路 Tesseract

關於訓練過程有疑問嗎? 如果您在訓練過程中遇到問題需要協助,請使用 tesseract-ocr 論壇提出您的問題。請勿將您的問題和訓練相關的疑問回報為 issues

Tesseract 5 不支援/已棄用使用 tesstrain.sh bash 腳本進行訓練。請使用 tesstrain repo 中的 python 腳本進行訓練。

目錄

簡介

Tesseract 4.00 引入了基於神經網路的新識別引擎,與先前的版本相比,在文件影像上的準確性顯著提高,但所需的運算能力也大幅增加。然而,在複雜的語言上,它實際上可能比基本的 Tesseract 更快

神經網路需要明顯更多的訓練資料,並且訓練速度比基本 Tesseract 慢很多。對於拉丁語系,現有的模型資料已經使用約 400000 行文字,涵蓋約 4500 種字型進行訓練。對於其他文字,可用的字型沒有那麼多,但它們仍然使用了類似數量的文字行進行訓練。Tesseract 4.00 不是花費幾分鐘到幾個小時來訓練,而是需要花費幾到幾的時間。即使有了所有這些新的訓練資料,您可能會發現它對於您的特定問題來說仍然不足,因此您才會在這裡想要重新訓練它。

訓練有多種選擇:

雖然上述選項聽起來可能不同,但訓練步驟實際上幾乎相同,除了命令列之外,因此在有時間或硬體可以平行運行的情況下,嘗試所有方法相對容易。

舊的識別引擎仍然存在,也可以進行訓練,但已棄用,除非有充分的理由保留它,否則可能會在未來的版本中刪除。

開始之前

您不需要任何神經網路的背景知識即可訓練 Tesseract,但它可能有助於理解訓練選項之間的差異。在深入研究訓練過程之前,請先閱讀實作簡介

重要提示:請務必注意,除非您使用的是非常不尋常的字型或新的語言,否則重新訓練 Tesseract 可能不會有幫助。在您投入時間和精力訓練 Tesseract 之前,強烈建議您閱讀ImproveQuality頁面。許多時候,只需預處理輸入影像即可提高識別率。

硬體軟體需求

在撰寫本文時,訓練僅適用於 Linux。(macOS 幾乎可以運作;它需要對 shell 腳本進行微小的修改,以適應其提供的較舊版本的 bash 以及 mktemp 的差異。)Windows 的情況不明,但需要 msys 或 Cygwin。

至於執行 Tesseract,擁有多核心(4 個核心是好的)機器、支援 OpenMP 和 Intel Intrinsics 的 SSE/AVX 擴充功能很有用,但並非必要。基本上,它仍然可以在任何具有足夠記憶體的電腦上執行,但您的處理器越高階,執行速度就越快。不需要 GPU。(不支援。)記憶體使用量可以透過 –max_image_MB 命令列選項進行控制,但您可能需要至少 1GB 的記憶體,超出作業系統所佔用的記憶體。

額外需要的程式庫

從 3.03 版開始,需要額外的程式庫來建置訓練工具。

sudo apt-get install libicu-dev libpango1.0-dev libcairo2-dev

建置訓練工具

從 3.03 版開始,如果您是從原始碼編譯 Tesseract,則需要使用單獨的 make 命令來建立和安裝訓練工具。

為了進行訓練,您必須確保安裝了所有這些選用的相依性,並且 Tesseract 的建置環境可以找到它們。在 ./configure 的輸出中尋找這些行:

checking for pkg-config... [some valid path]
checking for lept >= 1.74... yes
checking for libarchive... yes
checking for icu-uc >= 52.1... yes
checking for icu-i18n >= 52.1... yes
checking for pango >= 1.22.0... yes
checking for cairo... yes
[...]
Training tools can be built and installed with:

(當然,版本號碼可能會隨時間變化。我們尋找的是「yes」,所有選用的相依性都可用。)

設定完成後,您可以嘗試建置訓練工具:

make
make training
sudo make training-install

建立ScrollView.jar 也很有用,但並非必要。

make ScrollView.jar
export SCROLLVIEW_PATH=$PWD/java

訓練文字需求

對於拉丁語系,現有的模型資料已經使用約 400000 行文字,涵蓋約 4500 種字型進行訓練。對於其他文字,可用的字型沒有那麼多,但它們仍然使用了類似數量的文字行進行訓練。

請注意,擁有更多的訓練文字和製作更多的頁面是有益的,因為神經網路的泛化能力不佳,需要訓練類似於它們將要執行的內容。如果目標領域受到嚴重限制,那麼所有關於需要大量訓練資料的嚴重警告可能不適用,但可能需要更改網路規範。

訓練過程概述

訓練的主要步驟是:

  1. 準備訓練文字。
  2. 將文字渲染為影像 + 方塊檔案。(或為現有的影像資料建立手動方塊檔案。)
  3. 建立 unicharset 檔案。(可以部分指定,即手動建立)。
  4. 從 unicharset 和選用的字典資料建立入門/原型 traineddata。
  5. 執行 tesseract 以處理影像 + 方塊檔案,以建立訓練資料集(lstmf 檔案)。
  6. 在訓練資料集上執行訓練。
  7. 合併資料檔案。

與訓練基本 Tesseract(傳統 Tesseract 3.04)的主要差異在於:

由於以下幾個原因,訓練不能像 3.04 的訓練那樣完全自動化:

了解訓練期間使用的各種檔案

與基本/傳統 Tesseract 一樣,完成的 LSTM 模型及其所需的所有內容都收集在 traineddata 檔案中。與基本/傳統 Tesseract 不同,在訓練期間會提供一個 starter/proto traineddata 檔案,並且必須預先設定。它可以包含:

必須提供粗體元素。其他元素是可選的,但如果提供了任何 dawg,則還必須提供標點符號 dawg

提供了一個新的工具 combine_lang_model,可以從 unicharset 和選用的字詞列表建立 starter traineddata,並且是訓練所必需的。

在訓練期間,訓練器會寫入檢查點檔案,這是神經網路訓練器的標準行為。這允許訓練在需要時停止並稍後再次繼續。任何檢查點都可以透過使用 --stop_training 命令列標記轉換為完整的 traineddata 以進行識別。

訓練器還會定期在訓練期間達到的新最佳情況下寫入檢查點檔案。

可以修改網路並僅重新訓練其中一部分,或針對特定訓練資料進行微調(即使使用修改後的 unicharset!),方法是告知訓練器 --continue_from 現有的檢查點檔案,或從使用 combine_tessdata 從現有的 traineddata 檔案中提取的裸 LSTM 模型檔案,前提是它尚未轉換為整數。

如果在 --traineddata 標記中,與透過 --continue_from 提供的模型中使用的 unicharset 相比, unicharset 有所更改,則必須使用相應的 traineddata 檔案提供 --old_traineddata 標記,該檔案包含 unicharsetrecoder。這使訓練器能夠計算字元集之間的對應關係。

訓練資料透過 .lstmf 檔案提供,這些檔案是序列化的 DocumentData。它們包含影像和對應的 UTF8 文字轉錄,並且可以使用 Tesseract 以類似於為舊引擎建立 .tr 檔案的方式,從 tif/box 檔案對產生。

LSTMTraining 命令列

lstmtraining 程式是一個用於訓練神經網路的多功能工具。下表描述了它的命令列選項

旗標 類型 預設值 說明
traineddata 字串 啟動器 traineddata 檔案的路徑,其中包含 unicharset、recoder 和可選的語言模型。
net_spec 字串 指定網路的拓撲結構。
model_output 字串 輸出模型檔案/檢查點的基本路徑。
max_image_MB 整數 6000 用於快取影像的最大記憶體容量。
learning_rate 雙精度浮點數 10e-4 SGD 演算法的初始學習率。
sequential_training 布林值 false 設定為 true 以進行循序訓練。預設是以循環方式處理所有訓練資料。
net_mode 整數 192 network.h 中的 NetworkFlags 的旗標。可能的值:128 表示使用 Adam 優化而非動量;64 表示允許不同的層級擁有自動發現的各自的學習率。
perfect_sample_delay 整數 0 當網路變好時,只有在自上次允許通過完美樣本以來已看到這麼多不完美樣本後,才反向傳播一個完美樣本。
debug_interval 整數 0 如果非零,則每隔這麼多次迭代顯示視覺除錯。
weight_range 雙精度浮點數 0.1 初始化權重的隨機值範圍。
momentum 雙精度浮點數 0.5 用於平滑梯度動量。
adam_beta 雙精度浮點數 0.999 ADAM 演算法中平方梯度的平滑因子。
max_iterations 整數 0 在此多次迭代後停止訓練。
target_error_rate 雙精度浮點數 0.01 如果平均百分比錯誤率低於此值,則停止訓練。
continue_from 字串 要繼續訓練或微調的先前檢查點的路徑。
stop_training 布林值 false --continue_from 中的訓練檢查點轉換為辨識模型。
convert_to_int 布林值 false 使用 stop_training,轉換為 8 位元整數以提高速度,但準確性略有下降。
append_index 整數 -1 在給定的索引處切斷網路的頭部,並將 --net_spec 網路附加到被切斷的部分。
train_listfile 字串 列出訓練資料檔案的檔案名稱。
eval_listfile 字串 列出評估資料檔案的檔案名稱,這些檔案將用於獨立於訓練資料評估模型。

大多數旗標都使用預設值,並且有幾個旗標僅對於下面列出的特定操作是必需的,但首先對更複雜的旗標進行一些詳細的評論

Unicharset 壓縮-重新編碼

LSTM 在學習序列方面非常出色,但是當狀態數量太大時,速度會大幅減慢。有一些經驗結果表明,要求 LSTM 學習一個長序列比學習一個具有許多類別的短序列更好,因此對於複雜的文字 (漢字、韓文和印度文字),最好將每個符號重新編碼為少量類別中程式碼的短序列,而不是擁有大量的類別集合。

combine_lang_model 命令預設啟用此功能。它將每個漢字編碼為 1-5 個程式碼的可變長度序列,使用 Jamo 編碼將韓文編碼為 3 個程式碼的序列,並將其他文字編碼為其 Unicode 組件的序列。對於使用梵語輔音結合符號字元產生連體輔音的文字 (所有印度文字加上緬甸語和高棉語),函式 NormalizeCleanAndSegmentUTF8 會將梵語輔音結合符號與適當的相鄰字元配對,以在 unicharset 中產生更面向字形的編碼。為了充分利用此改進,應該為這些文字的 combine_lang_model 設定 --pass_through_recoder 旗標。

隨機化訓練資料和 sequential_training

為了使隨機梯度下降正常運作,應該在所有樣本檔案中隨機洗牌訓練資料,因此訓練器可以依次讀取每個檔案,並在到達結尾時返回第一個檔案。

如果使用渲染程式碼 (透過 tesstrain.py),則它會在每個檔案中洗牌樣本文字行,但是您將獲得一組檔案,每個檔案都包含來自單一字型的訓練樣本。為了加入更均勻的混合,預設會依序處理每個檔案中的一個樣本,又稱為「循環」樣式。如果您以其他方式產生訓練資料,或者它們全部來自同一樣式 (例如手寫的手稿書),則可以對 lstmtraining 使用 --sequential_training 旗標。這更節省記憶體,因為它一次僅會從兩個檔案載入資料,並按順序處理它們。(第二個檔案是預先讀取的,因此在需要時可以使用。)

模型輸出

訓練器會使用 --model_output 作為基本名稱定期儲存檢查點。因此,可以在任何時候停止訓練,並使用相同的命令列重新啟動它,並且它將繼續。若要強制重新啟動,請使用不同的 --model_output 或刪除所有檔案。

網路模式與最佳化

128 旗標會開啟 Adam 優化,這似乎比普通動量好得多。

64 旗標啟用自動層級特定學習率。當進度停滯時,訓練器會調查應獨立降低其學習率的層級,並且可能會降低一個或多個學習率以繼續學習。

net_mode 的預設值 192 同時啟用 Adam 和層級特定學習率。

完美樣本延遲

訓練「簡單」樣本不一定是個好主意,因為這是在浪費時間,但是不應允許網路忘記如何處理它們,因此,如果它們出現的頻率過高,則可以捨棄一些簡單的樣本。如果自上次看到完美樣本以來,還沒有看到那麼多不完美樣本,則 --perfect_sample_delay 引數會捨棄完美樣本。

目前的預設值零會使用所有樣本。實際上,該值似乎沒有產生巨大的影響,並且如果允許訓練持續足夠長的時間,則零會產生最佳結果。

偵錯間隔與視覺化偵錯

使用零 (預設值) --debug_interval,訓練器每 100 次迭代輸出進度報告,類似於以下範例。

At iteration 717/10500/10500, Mean rms=0.113000%, delta=0.009000%, BCER train=0.029000%, BWER train=0.083000%, skip ratio=0.000000%,  New worst BCER = 0.029000 wrote checkpoint.

At iteration 718/10600/10600, Mean rms=0.112000%, delta=0.007000%, BCER train=0.023000%, BWER train=0.085000%, skip ratio=0.000000%,  New worst BCER = 0.023000 wrote checkpoint.

2 Percent improvement time=509, best error was 2.033 @ 209
At iteration 718/10700/10700, Mean rms=0.111000%, delta=0.006000%, BCER train=0.019000%, BWER train=0.069000%, skip ratio=0.000000%,  New best BCER = 0.019000 wrote best model:data/engRupee/checkpoints/engRupee_0.019000_718_10700.checkpoint wrote checkpoint.

2 Percent improvement time=509, best error was 2.033 @ 209
At iteration 718/10800/10800, Mean rms=0.108000%, delta=0.002000%, BCER train=0.007000%, BWER train=0.052000%, skip ratio=0.000000%,  New best BCER = 0.007000 wrote best model:data/engRupee/checkpoints/engRupee_0.007000_718_10800.checkpoint wrote checkpoint.

Finished! Selected model with minimal training error rate (BCER) = 0.007

使用 --debug_interval -1,訓練器會為每次訓練迭代輸出詳細的除錯文字。文字除錯資訊包括真值文字、辨識的文字、迭代次數、訓練樣本 ID (lstmf 檔案和行) 以及數個錯誤指標的平均值。在所有情況下都會顯示該行的 GROUND TRUTHALIGNED TRUTHBEST OCR TEXT 僅在與 GROUND TRUTH 不同時才會顯示。

Iteration 455038: GROUND  TRUTH : उप॑ त्वाग्ने दि॒वेदि॑वे॒ दोषा॑वस्तर्धि॒या व॒यम् ।
File /tmp/san-2019-03-28.jsY/san.Mangal.exp0.lstmf line 451 (Perfect):
Mean rms=1.267%, delta=4.155%, train=11.308%(32.421%), skip ratio=0%
Iteration 455039: GROUND  TRUTH : मे अपराध और बैठे दुकानों नाम सकते अधिवक्ता, दोबारा साधन विषैले लगाने पर प्रयोगकर्ताओं भागे
File /tmp/san-2019-04-04.H4m/san.FreeSerif.exp0.lstmf line 28 (Perfect):
Mean rms=1.267%, delta=4.153%, train=11.3%(32.396%), skip ratio=0%
Iteration 1526: GROUND  TRUTH : 𒃻 𒀸 𒆳𒆳 𒅘𒊏𒀀𒋾
Iteration 1526: ALIGNED TRUTH : 𒃻 𒀸 𒆳𒆳 𒅘𒊏𒊏𒀀𒋾
Iteration 1526: BEST OCR TEXT :    𒀀𒋾
File /tmp/eng-2019-04-06.Ieb/eng.CuneiformComposite.exp0.lstmf line 19587 :
Mean rms=0.941%, delta=12.319%, train=56.134%(99.965%), skip ratio=0.6%
Iteration 1527: GROUND  TRUTH : 𒀭𒌋𒐊
Iteration 1527: BEST OCR TEXT : 𒀭𒌋
File /tmp/eng-2019-04-06.Ieb/eng.CuneiformOB.exp0.lstmf line 7771 :
Mean rms=0.941%, delta=12.329%, train=56.116%(99.965%), skip ratio=0.6%

使用 --debug_interval > 0,訓練器會在網路的層級上顯示數個除錯資訊視窗。

--debug_interval 1 的特殊情況下,它會在繼續下一次迭代之前等待 LSTMForward 視窗中的點擊,但是對於所有其他情況,它只會繼續並按要求頻率繪製資訊。

請注意,若要使用 --debug_interval > 0,您必須同時建置 ScrollView.jar 以及其他訓練工具。 請參閱建置訓練工具

視覺除錯資訊包括

每個網路層級的前向和後向視窗。大多數只是隨機雜訊,但是 Output/Output-backConvNL 視窗值得檢視。Output 顯示最終 Softmax 的輸出,它首先是空字元的黃線,並逐漸在它認為有字元的每個點產生黃色標記。(x 軸是影像的 x 座標,y 軸是字元類別。) Output-back 視窗使用相同的佈局顯示實際輸出與目標之間的差異,但是黃色表示「給我更多這個」,藍色表示「給我更少這個」。隨著網路的學習,ConvNL 視窗會發展出您期望從底層獲得的典型邊緣偵測器結果。

LSTMForward 顯示整個網路在訓練影像上的輸出。LSTMTraining 顯示訓練影像上的訓練目標。在這兩個視窗中,都會繪製綠線以顯示每個字元的峰值輸出,並且字元本身會繪製在該行的右側。

其他兩個值得關注的視窗是 CTC OutputsCTC Targets。這些視窗將網路的目前輸出和目標顯示為輸出強度與影像 x 座標的線形圖。與 Output 視窗中的熱圖不同,會為每個字元類別繪製一條不同的彩色線,並且 y 軸是輸出強度。

迭代次數和檢查點

在訓練期間,我們會看到以下種類的資訊

2 Percent improvement time=100, best error was 100 @ 0
At iteration 100/100/100, Mean rms=6.042000%, delta=63.801000%, BCER train=98.577000%, BWER train=100.000000%, skip ratio=0.000000%,  New best BCER = 98.577000 wrote checkpoint.

2 Percent improvement time=200, best error was 100 @ 0
At iteration 200/200/200, Mean rms=5.709000%, delta=58.372000%, BCER train=98.399000%, BWER train=99.986000%, skip ratio=0.000000%,  New best BCER = 98.399000 wrote checkpoint.
...
At iteration 14615/695400/698614, Mean rms=0.131000%, delta=0.038000%, BCER train=0.207000%, BWER train=0.579000%, skip ratio=0.4%,  wrote checkpoint.

在以上範例中,

14615 : learning_iteration
695400 : training_iteration
698614 : sample_iteration

sample_iteration : 「訓練樣本集合的索引。(sample_iteration >= training_iteration)。」這表示一個訓練檔案被傳遞到學習程序的次數。

training_iteration : 「所使用的實際反向訓練步驟的次數。」這表示訓練檔案已成功傳遞到學習程序的次數。因此,每次您收到錯誤:「影像太大,無法學習!!」- 「字串編碼失敗!」- 「反序列化標頭失敗!」,sample_iteration 會遞增,但 training_iteration 不會。實際上,您有 1 - (695400 / 698614) = 0.4%,這是由於錯誤而略過的檔案的跳過率:比例

learning_iteration : 「產生非零增量錯誤,從而提供顯著學習的迭代次數。(learning_iteration <= training_iteration)。learning_iteration_ 用於測量學習進度速率。」因此,它使用增量值來評估迭代是否有效。

重要的是要知道,當您為訓練程序指定最大迭代次數時,它會使用中間迭代次數 (training_iteration) 來知道何時停止。但是,當它寫入檢查點時,檢查點名稱也會使用最佳迭代次數 (learning_iteration) 以及字元訓練率。因此,檢查點名稱是 model_name & char_train & learning_iteration & training_iteration 的串連,例如 sanLayer_1.754_347705_659600.checkpoint。

lstmtraining 程式輸出兩種檢查點檔案

這兩種檢查點檔案都可以使用 lstmtraining 的 stop_trainingconvert_to_int 標誌,轉換為標準 (最佳/浮點) traineddata 檔案或稍微不準確 (快速/整數) traineddata 檔案。

來自訓練的錯誤訊息

在執行訓練時可能會出現各種錯誤訊息,其中一些可能很重要,而另一些則不那麼重要。

當訓練影像的文字字串無法使用給定的 unicharset 進行編碼時,會出現 Encoding of string failed! 的錯誤訊息。可能的原因有:

  1. 文字中存在未表示的字元,例如您的 unicharset 中沒有的英鎊符號。
  2. 文字中存在未打印的亂碼字元(例如 Tab 或控制字元)。
  3. 文字中存在未表示的印度語字形/字母 (aksara)。

您可以使用 sed 指令碼輕鬆移除 pct. 2 中的違規字元 (CHARACTER TABULATION、CARRIAGE RETURN、NO-BREAK SPACE、LEFT-TO-RIGHT MARK、RIGHT-TO-LEFT MARK、ZERO WIDTH NO-BREAK SPACE、POP DIRECTIONAL FORMATTING、ZERO WIDTH NON-JOINER)。

remove_control_chars.sed

s/\x09//g
s/\x0d//g
s/\x00\xa0/ /g
s/\x20\x0e//g
s/\x20\x0f//g
s/\xfe\xff//g
s/\x20\x2c//g
s/\x20\x0c//g

sed -i -f remove_control_chars.sed data/lang-ground-truth*.gt.txt

在任何情況下,這都會導致訓練程式忽略該訓練影像。如果錯誤不常發生,則無害,但這可能表示您的 unicharset 不足以表示您正在訓練的語言。

Unichar xxx is too long to encode!! (最有可能僅限於印度語)。可以在 recoder 中使用的 unicode 字元長度上限,這簡化了 LSTM 引擎的 unicharset。它只會繼續並將該字母 (Aksara) 排除在可辨識的集合之外,但如果有很多,那就麻煩了。

Bad box coordinates in boxfile string! LSTM 訓練器只需要完整文字行的邊界框資訊,而不是字元層級的資訊,但如果您在框字串中加入空格,例如這樣:

<text for line including spaces> <left> <bottom> <right> <top> <page>

解析器會感到困惑並給您錯誤訊息。

當訓練輸入不是 LSTM 格式或檔案無法讀取時,會發生 Deserialize header failed。檢查您的檔案清單檔案,查看它是否包含有效的檔案名稱。

當版面配置分析無法正確分割作為訓練資料提供的影像時,會發生 No block overlapping textline:。文字行會被捨棄。如果沒有太多問題,但如果有很多,則訓練文字或渲染過程可能存在問題。

<Undecodable> 可能在訓練初期出現在 ALIGNED_TRUTH 或 OCR TEXT 輸出中。這是 unicharset 壓縮和 CTC 訓練的結果。(請參閱上面的 Unicharset 壓縮和 train_mode)。這應該是無害的,可以安全地忽略。隨著訓練的進行,其頻率應該會下降。

合併輸出檔案

lstmtraining 程式輸出兩種檢查點檔案

這些檔案都可以轉換為標準的 traineddata 檔案。這將從訓練傾印檔案中提取辨識模型,並將其插入到 –traineddata 參數中,以及在訓練期間提供的 unicharset、recoder 和任何 dawgs。

注意 Tesseract 現在可以愉快地使用 traineddata 檔案運行,該檔案包含 lang.lstmlang.lstm-unicharsetlang.lstm-recoderlstm-*-dawgs 是可選的,並且在將 OCR 引擎模式設為 OEM_LSTM_ONLY 時,其他元件都不是必需的或使用的。 無需雙連字、unichar 歧義或任何其他元件,即使存在也不會產生任何影響。唯一有作用的其他元件是 lang.config,它可以影響版面配置分析和子語言。

如果將其新增至現有的 Tesseract traineddata 檔案,則 lstm-unicharset 不必與 Tesseract unicharset 相符,但必須使用相同的 unicharset 來訓練 LSTM 並建構 lstm-*-dawgs 檔案。

幻覺效應

如果您注意到您的模型行為不當,例如:

然後閱讀幻覺主題。