如何訓練 Tesseract 4.00
**使用 tesstrain.sh
進行訓練現在已不受支援/已放棄。請使用 https://github.com/tesseract-ocr/tesstrain 中的 python 腳本進行訓練。**
對訓練過程有疑問嗎? 如果您在訓練過程中遇到問題並且需要協助,請使用 tesseract-ocr 郵件列表提出您的問題。請不要將您的問題和訓練相關的問題回報為 issue!
Ray Smith 的指南和教學內容
- 簡介
- 開始之前
- 所需額外函式庫
- 建置訓練工具
- 硬體和軟體需求
- 訓練文字需求
- 訓練過程概述
- 了解訓練期間使用的各種檔案
- LSTMTraining 命令列
- TessTutorial
- 合併輸出檔案
- 幻覺效應
初步說明
以下指南和教學對於 Tesseract 5 已過時。使用 tesstrain.sh
進行訓練已不受支援/已放棄。請使用 https://github.com/tesseract-ocr/tesstrain 中的腳本進行訓練。
簡介
Tesseract 4.00 包含一個新的基於神經網路的識別引擎,它在文件圖像上的準確度明顯高於之前的版本,但需要更高的運算能力。 然而,在複雜的語言上,它實際上可能比基礎 Tesseract 更快。
神經網路需要顯著更多的訓練資料,並且訓練速度比基礎 Tesseract 慢得多。 對於基於拉丁文的語言,提供的現有模型資料已在約 400000 個文字行,跨越約 4500 種字體上進行訓練。對於其他文字,可用的字體不多,但它們仍然在類似數量的文字行上進行了訓練。 Tesseract 4.00 並非像訓練花費幾分鐘到幾個小時,而是需要幾天到幾週的時間。 即使有了所有這些新的訓練資料,您可能會發現它對於您的特定問題仍然不夠,因此您才會想重新訓練它。
有多種訓練選項
- 微調。 從現有的訓練語言開始,針對您特定的其他資料進行訓練。 這對於與現有訓練資料接近,但以某些微妙方式不同的問題可能有效,例如特別不尋常的字體。 即使使用少量訓練資料也可能有效。
- 從網路中截斷頂層(或任意數量的層),並使用新資料重新訓練一個新的頂層。 如果微調不起作用,這很可能是下一個最佳選擇。 如果您從看起來最相似的文字開始,截斷頂層仍然可以用於訓練全新的語言或文字。
- 從頭開始重新訓練。 這是一項艱鉅的任務,除非您為您的問題準備了一個非常有代表性且足夠大的訓練集。 如果沒有,您很可能會得到一個過度擬合的網路,該網路在訓練資料上表現非常好,但在實際資料上卻不然。
雖然上述選項聽起來可能不同,但訓練步驟實際上幾乎相同,除了命令列,因此很容易嘗試所有方法,只要有時間或硬體可以平行執行它們。
至少對於 4.00,舊的識別引擎仍然存在,也可以進行訓練,但已過時,並且除非有充分的理由保留它,否則可能會在未來的版本中刪除。
開始之前
您不需要任何神經網路的背景知識即可訓練 Tesseract 4.00,但這可能有助於了解訓練選項之間的差異。 在深入研究訓練過程之前,請閱讀 實作簡介,並應用與訓練 Tesseract 3.04 相同的注意事項
重要提示:在您投入時間和精力訓練 Tesseract 之前,強烈建議您閱讀 ImproveQuality 頁面。
所需額外函式庫
從 3.03 開始,需要額外的函式庫來建置訓練工具。
sudo apt-get install libicu-dev libpango1.0-dev libcairo2-dev
建置訓練工具
從 3.03 開始,如果您是從原始碼編譯 Tesseract,則需要使用單獨的 make 命令來建立和安裝訓練工具。 安裝上述額外的函式庫後,從 Tesseract 原始碼目錄執行以下操作
./configure
或者,如果您計劃在 docker 中執行(或不需要圖形)
./configure --disable-graphics
預設情況下,如果缺少僅用於訓練的依賴項,Tesseract 配置將繼續,但對於訓練,您必須確保安裝所有這些可選依賴項,並且 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」,所有可選的依賴項都可用。)
如果配置未表示可以建置訓練工具,您仍然需要新增函式庫或確保 pkg-config
可以找到它們。
配置完成後,您可以嘗試建置訓練工具
make
make training
sudo make training-install
建置 ScrollView.jar 也很有用,但不是必需的
make ScrollView.jar
export SCROLLVIEW_PATH=$PWD/java
在 macOS Mojave 上使用 Homebrew
Homebrew 設定 pkgconfig
的方式不尋常,因此您必須選擇加入某些檔案。 通常執行 brew info package
並確保您將提到的 PKG_CONFIG_PATH 附加到此環境變數。
brew install cairo pango icu4c autoconf libffi libarchive
export PKG_CONFIG_PATH=\
$(brew --prefix)/lib/pkgconfig:\
$(brew --prefix)/opt/libarchive/lib/pkgconfig:\
$(brew --prefix)/opt/icu4c/lib/pkgconfig:\
$(brew --prefix)/opt/libffi/lib/pkgconfig
./configure
硬體和軟體需求
在撰寫本文時,訓練僅在 Linux 上有效。 (macOS 幾乎可以工作;它需要對 shell 腳本進行小的修改,以解決它提供的較舊版本的 bash
以及 mktemp
的差異。)Windows 是未知的,但需要 msys 或 Cygwin。
至於執行 Tesseract 4.0.0,擁有多核心(4 個很好)機器,並支援 OpenMP 和用於 SSE/AVX 擴展的 Intel Intrinsics 是有用的,但不是必要的。基本上,它仍然可以在任何具有足夠記憶體的設備上執行,但是您的處理器越高階,它的速度就越快。 不需要 GPU。(不支援。)記憶體使用量可以透過 –max_image_MB 命令列選項進行控制,但您可能至少需要 1GB 的記憶體,超出您的作業系統所佔用的記憶體。
訓練文字需求
對於基於拉丁文的語言,提供的現有模型資料已在約 400000 個文字行,跨越約 4500 種字體上進行訓練。對於其他文字,可用的字體不多,但它們仍然在類似數量的文字行上進行了訓練。
請注意,擁有更多的訓練文字並製作更多頁面是有益的,因為神經網路不能很好地泛化,並且需要在與它們將要執行的內容相似的內容上進行訓練。 如果目標網域受到嚴重限制,那麼所有關於需要大量訓練資料的可怕警告可能不適用,但可能需要更改網路規格。
訓練過程概述
整體訓練過程與 訓練 3.04 類似。
概念上相同
- 準備訓練文字。
- 將文字渲染為圖像 + box 檔案。(或為現有圖像資料建立手工製作的 box 檔案。)
- 建立 unicharset 檔案。(可以部分指定,即手動建立)。
- 從 unicharset 和可選字典資料建立起始 traineddata。
- 執行 tesseract 以處理圖像 + box 檔案,以建立訓練資料集。
- 對訓練資料集執行訓練。
- 合併資料檔案。
主要差異在於
- box 只需要在文字行層級。因此,從現有圖像資料建立訓練資料要容易得多。
- .tr 檔案被 .lstmf 資料檔案取代。
- 字體可以並且應該自由混合,而不是單獨使用。
- 叢集步驟(mftraining、cntraining、shapeclustering)被單一緩慢的 lstmtraining 步驟取代。
由於以下幾個原因,訓練無法像 3.04 的訓練那樣自動化
- 緩慢的訓練步驟不適合從腳本中間執行,因為它可以在停止時重新開始,並且很難自動判斷它何時完成。
- 有多個如何訓練網路的選項(見上文)。
- 語言模型和 unicharset 允許與基礎 Tesseract 使用的模型不同,但不必如此。
- 基礎 Tesseract 的語言與神經網路 Tesseract 的語言不必相同。
了解訓練期間使用的各種檔案
與基礎 Tesseract 一樣,完成的 LSTM 模型及其所需的一切都收集在 traineddata
檔案中。 與基礎 Tesseract 不同,訓練期間會提供 starter traineddata
檔案,並且必須提前設定。 它可以包含
- 提供控制參數的設定檔。
- Unicharset 定義字元集。
- Unicharcompress,又名重新編碼器,它將 unicharset 進一步對應到神經網路辨識器實際使用的程式碼。
- 標點符號模式 dawg,其中包含允許在單字周圍使用的標點符號模式。
- 單字 dawg。 系統單字表語言模型。
- 數字 dawg,其中包含允許使用的數字模式。
必須提供粗體元素。 其他元素是可選的,但如果提供了任何 dawg,則還必須提供標點符號 dawg。 提供了一個新工具: combine_lang_model
,用於從 unicharset
和可選的單字列表建立 starter traineddata
。
在訓練期間,訓練器會寫入檢查點檔案,這是神經網路訓練器的標準行為。 這允許訓練在需要時停止並稍後繼續。 透過使用 --stop_training
命令列標誌,可以將任何檢查點轉換為完整的 traineddata
以進行識別。
訓練器還會定期在訓練期間達到的新最佳點寫入檢查點檔案。
可以修改網路,並僅重新訓練部分網路,或是針對特定的訓練資料進行微調(即使使用修改過的 unicharset!),方法是告訴訓練器使用 --continue_from
參數,指定現有的檢查點檔案,或是從現有的 traineddata
檔案中提取出的裸 LSTM 模型檔案(使用 combine_tessdata
工具),前提是該模型尚未轉換為整數格式。
如果與透過 --continue_from
參數提供的模型所使用的 unicharset 相比,在 --traineddata
旗標中更改了 unicharset,則必須提供 --old_traineddata
旗標,並指定包含 unicharset
和 recoder
的對應 traineddata
檔案。這可以讓訓練器計算字元集之間的映射。
訓練資料是透過 .lstmf
檔案提供的,這些檔案是序列化的 DocumentData
。它們包含影像和對應的 UTF8 文字轉錄,並且可以使用 Tesseract 從 tif/box 檔案對生成,方式與舊引擎建立 .tr
檔案的方式類似。
LSTMTraining 命令列
lstmtraining 程式是一個用於訓練神經網路的多用途工具。下表描述其命令列選項
旗標 | 類型 | 預設值 | 說明 |
---|---|---|---|
traineddata |
字串 |
無 | 包含 unicharset、recoder 和可選語言模型的起始 traineddata 檔案的路徑。 |
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 組件的序列。對於使用 virama 字元產生結合輔音的腳本(所有印度腳本以及緬甸語和高棉語),函數 NormalizeCleanAndSegmentUTF8
將 virama 與適當的鄰居配對,以便在 unicharset 中產生更面向字形的編碼。為了充分利用此改進,應為這些腳本的 combine_lang_model
設定 --pass_through_recoder
旗標。
隨機化訓練資料和 sequential_training
為了使隨機梯度下降正常工作,訓練資料應該在所有樣本檔案中隨機混洗,以便訓練器可以依次讀取每個檔案,並在到達末尾時返回第一個檔案。
如果使用呈現程式碼(透過 tesstrain.sh
),則它會混洗每個檔案中的樣本文字行,但是您將獲得一組檔案,每個檔案都包含來自單一字型的訓練樣本。為了增加更均勻的混合,預設值是依次處理每個檔案中的一個樣本,即「循環」樣式。如果您以其他方式產生訓練資料,或者它們都來自相同的樣式(例如手寫的手稿書),則可以使用 lstmtraining
的 --sequential_training
旗標。這樣做更節省記憶體,因為它一次只會從兩個檔案載入資料,並按順序處理它們。(第二個檔案會預先讀取,以便在需要時可以使用。)
模型輸出
訓練器使用 --model_output
作為基本名稱定期儲存檢查點。因此,可以隨時停止訓練並使用相同的命令列重新啟動它,它會繼續進行。若要強制重新啟動,請使用不同的 --model_output
或刪除所有檔案。
網路模式和最佳化
128
旗標啟用 Adam 優化,它似乎比普通的動量效果更好。
64
旗標啟用自動層特定學習率。當進度停滯時,訓練器會調查應獨立降低哪些層的學習率,並可能降低一個或多個學習率以繼續學習。
net_mode
的預設值 192
同時啟用 Adam 和層特定的學習率。
以下是發散時看到的訊息範例,此時學習率會降低。
Iteration 8999: GROUND TRUTH : . هريغ )9(فرعي ال ؛ ميملا رسكب » رخنم « و » رخنم « اولاق
Iteration 8999: BEST OCR TEXT : . هريغ )6(فرعي ال ؛ ميملا رسكب » رخنم « و » رخنم « اولاق
File /home/ubuntu/OCR_GS_Data/ara/AWN/book_IbnQutayba.Adab_7_final_200_000742.lstmf line 0 :
Mean rms=1.696%, delta=3.16%, train=113.332%(18.851%), skip ratio=0.1%
Warning: LSTMTrainer deserialized an LSTMRecognizer!
At iteration 7794/9000/9011, Mean rms=1.696%, delta=3.16%, char train=113.332%, word train=18.851%, skip ratio=0.1%, New worst char error = 113.332At iteration 7507, stage 0, Eval Char error rate=5.4443537, Word error rate=16.233627
Divergence! Reverted to iteration 5870/6400/6408
Reduced learning rate to :0.00025000001
wrote checkpoint.
Iteration 6400: GROUND TRUTH : بيرق ناك اذإ »)1(ددعقو ددعق لجر « و ، هتصاخ : يأ » هللخدو نالف للخد«
File /home/ubuntu/OCR_GS_Data/ara/AWN/book_IbnQutayba.Adab_7_final_b_200_000438.lstmf line 0 (Perfect):
Mean rms=1.759%, delta=2.898%, train=62.442%(21.232%), skip ratio=0.2%
Iteration 6401: GROUND TRUTH : . )1(هجيه ام ردق ىلع
Iteration 6401: ALIGNED TRUTH : . )1(هجيه ام ردق ىىلع
Iteration 6401: BEST OCR TEXT : . )1(هجيمه ام ردق مع
完美樣本延遲
訓練「簡單」樣本不一定是個好主意,因為這是在浪費時間,但不應讓網路忘記如何處理它們,因此如果太頻繁出現一些簡單樣本,則可以捨棄它們。如果自上次完美樣本以來沒有看到那麼多不完美的樣本,則 --perfect_sample_delay
參數會捨棄完美樣本。目前的預設值零會使用所有樣本。在實務中,該值似乎沒有很大的影響,如果允許訓練運行足夠長的時間,則零會產生最佳結果。
除錯間隔和視覺化除錯
使用零(預設值)--debug_interval
,訓練器每 100 次迭代輸出一個進度報告,類似於以下範例。
At iteration 61239/65000/65015, Mean rms=1.62%, delta=8.587%, char train=16.786%, word train=36.633%, skip ratio=0.1%, wrote checkpoint.
At iteration 61332/65100/65115, Mean rms=1.601%, delta=8.347%, char train=16.497%, word train=36.24%, skip ratio=0.1%, wrote checkpoint.
2 Percent improvement time=44606, best error was 17.77 @ 16817
Warning: LSTMTrainer deserialized an LSTMRecognizer!
At iteration 61423/65200/65215, Mean rms=1.559%, delta=7.841%, char train=15.7%, word train=35.68%, skip ratio=0.1%, New best char error = 15.7At iteration 45481, stage 0, Eval Char error rate=6.9447893, Word error rate=27.039255 wrote best model:./SANLAYER/LAYER15.7_61423.checkpoint wrote checkpoint.
使用 --debug_interval -1
,訓練器會為每次訓練迭代輸出詳細的除錯文字。文字除錯資訊包括真實文字、已識別的文字、迭代次數、訓練樣本 ID(lstmf 檔案和行)以及數個錯誤指標的平均值。在所有情況下都會顯示該行的 GROUND TRUTH
。ALIGNED TRUTH
和 BEST 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-back
和 ConvNL
視窗值得檢視。Output
顯示最終 Softmax 的輸出,它最初是空字元的黃線,並逐漸在它認為有字元的每個點上產生黃色標記。(x 軸是影像 x 坐標,y 軸是字元類別。)Output-back
視窗顯示實際輸出和目標之間的差異,使用相同的佈局,但黃色表示「給我更多這個」,藍色表示「給我更少這個」。隨著網路的學習,ConvNL
視窗會產生您期望從底層獲得的典型邊緣偵測器結果。
LSTMForward
顯示整個網路在訓練圖像上的輸出結果。LSTMTraining
顯示訓練圖像上的訓練目標。在這兩者中,都會繪製綠線來顯示每個字元的峰值輸出,並且字元本身會繪製在線的右側。
另外兩個值得關注的視窗是 CTC Outputs
和 CTC Targets
。這些視窗將網路的當前輸出和目標顯示為輸出強度相對於圖像 x 坐標的折線圖。與 Output
視窗的熱圖不同,每個字元類別都會繪製一條不同顏色的線,而 y 軸是輸出強度。
迭代和檢查點
在訓練期間,我們會看到這類資訊
At iteration 100/100/100, Mean rms=4.514%, delta=19.089%, char train=96.314%, word train=100%, skip ratio=0%, New best char error = 96.314 wrote checkpoint.
...
At iteration 14615/695400/698614, Mean rms=0.158%, delta=0.295%, char train=1.882%, word train=2.285%, 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:「產生非零 delta 錯誤,從而提供有效學習的迭代次數。(learning_iteration <= training_iteration)。learning_iteration 用於衡量學習進度。」 因此,它使用 delta 值來評估迭代是否有用。
要知道的是,當您為訓練過程指定最大迭代次數時,它會使用中間的迭代次數 (training_iteration) 來知道何時停止。但是,當它寫入檢查點時,檢查點名稱也會使用最佳迭代次數 (learning_iteration),以及字元訓練率。因此,檢查點名稱是 model_name & char_train & learning_iteration & training_iteration 的串聯,例如 sanLayer_1.754_347705_659600.checkpoint。
lstmtraining 程式會輸出兩種檢查點檔案
<model_base>_checkpoint
是最新的模型檔案,以及在訓練過程中出現發散時使用的備份模型。<model_base>_<char_error>_<learning_iteration>_<training_iteration>.checkpoint
會定期寫入,作為該訓練點具有最佳訓練錯誤的模型。它是一個訓練傾印,就像<model_base>_checkpoint
一樣,但較小,因為它沒有在訓練過程中出現發散時使用的備份模型。
這些檢查點檔案的任何一種都可以使用帶有 lstmtraining 的 stop_training
和 convert_to_int
標誌,轉換為標準(最佳/浮點)traineddata 檔案或稍微不精確(快速/整數)的 traineddata 檔案。
TessTutorial
建立訓練資料的過程如下所述,接著是lstmtraining 的教學指南,其中介紹了主要的訓練過程,並提供了經過實際測試的命令行。至少在 Linux 上,您應該可以將命令行複製貼上到您的終端機中。
為了使 tesstrain.sh
腳本能夠正常工作,必須設定 PATH
以包含您的本地 training
和 api
目錄,或者使用 make install
。
TessTutorial 的一次性設定
為了成功執行 TessTutorial,您需要安裝可用的 tesseract 和訓練工具,並且在某些目錄中擁有訓練腳本和所需的 traineddata 檔案。這些說明僅涵蓋從字型渲染的情況,因此必須先安裝所需的字型。請注意,您的字型位置可能會有所不同。
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/main/radical-stroke.txt
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/main/common.punc
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/main/font_properties
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/main/Latin.unicharset
wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/main/Latin.xheights
mkdir eng
cd eng
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/main/eng/eng.training_text
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/main/eng/eng.punc
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/main/eng/eng.numbers
wget https://raw.githubusercontent.com/tesseract-ocr/langdata/main/eng/eng.wordlist
cd ~/tesstutorial
git clone --depth 1 https://github.com/tesseract-ocr/tesseract.git
cd tesseract/tessdata
wget https://github.com/tesseract-ocr/tessdata/raw/main/eng.traineddata
wget https://github.com/tesseract-ocr/tessdata/raw/main/osd.traineddata
mkdir best
cd best
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/eng.traineddata
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/heb.traineddata
wget https://github.com/tesseract-ocr/tessdata_best/raw/main/chi_sim.traineddata
建立訓練資料
與基本 Tesseract 一樣,您可以選擇從字型渲染合成訓練資料,或者標記一些現有的圖像(例如古代手稿)。
在任何一種情況下,所需的格式仍然是 tiff/box 檔案對,只是 box 不需要覆蓋單個字元,而是只需要覆蓋文字行。
如果您使用 tesstrain.sh,則會從訓練文字和給定的字型清單中建立所需的 synthetic
訓練資料(box/tiff 對和 lstmf 檔案)。
製作 Box 檔案
Tesseract 4 接受多種格式的 box 檔案用於 LSTM 訓練,儘管它們與 Tesseract 3 使用的格式不同 (詳細資訊)。
box 檔案中的每一行都與 tiff 圖像中的「字元」(字形)相符。
<符號> <左> <底> <右> <上> <頁面>
其中 <左> <底> <右> <上> <頁面>
可以是單個字形或整個文字行的邊界框座標 (請參閱範例)。
為了標記文字行結尾,必須在一系列行之後插入一個特殊行。
<tab> <左> <底> <右> <上> <頁面>
可以使用 Tesseract 4.0,使用來自圖像資料的 lstmbox
設定,利用 tesseract <包含副檔名的圖像名稱> <box 檔案名稱> lstmbox
來產生 box 檔案。例如,tesseract image.png image lstmbox
將為目前目錄中的圖像產生一個名為 image.box
的 box 檔案。
請注意,在所有情況下,即使對於由右至左的語言(例如阿拉伯語),該行的文字轉錄應該由左至右排序。換句話說,無論語言為何,網路都將由左至右學習,而由右至左/雙向處理則在 Tesseract 內部更高層次發生。
使用 tesstrain.sh
執行 tesstrain.sh 的設定與基本 Tesseract 相同。對於 LSTM 訓練,請使用 --linedata_only
選項。請注意,擁有更多的訓練文字並建立更多頁面是有益的,因為神經網路的泛化能力不佳,需要訓練與它們將要運行的內容相似的內容。如果目標領域受到嚴格限制,則所有關於需要大量訓練資料的警告可能不適用,但可能需要變更網路規格。
訓練資料是使用 tesstrain.sh 建立的,如下所示
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
成功執行後,會列印出以下內容
Created starter traineddata for LSTM training of language 'eng'
Run 'lstmtraining' command to continue LSTM training for language 'eng'
上面的命令建立的 LSTM 訓練資料與用於訓練英文基本 Tesseract 的資料等效。對於建立通用的基於 LSTM 的 OCR 引擎而言,這是嚴重不足的,但它是一個很好的教學演示。
現在嘗試使用此方法為「Impact」字型建立評估資料
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 教學指南
建立起始 Traineddata
lstmtraining
在其命令行上接受 traineddata
檔案,以取得其需要了解的所有關於要學習的語言的資訊。traineddata
必須至少包含一個 lstm-unicharset
和 lstm-recoder
元件,並且還可以包含三個 dawg 檔案:lstm-punc-dawg lstm-word-dawg lstm-number-dawg
。config
檔案也是可選的。如果存在,其他元件將會被忽略且不使用。
沒有工具可以直接建立 lstm-recoder
。相反,有一個工具 combine_lang_model
,它以 input_unicharset
和 script_dir
(script_dir
指向 langdata
目錄) 以及 lang
(lang
是正在使用的語言) 和可選的字詞清單檔案作為輸入。它會從 input_unicharset
建立 lstm-recoder
,並在提供字詞清單時建立所有 dawg,將所有內容整合到 traineddata
檔案中。
如果您使用 tesstrain.sh,則起始 traineddata 也會與來自訓練文字和給定字型清單的 synthetic
訓練資料(box/tiff 對和 lstmf 檔案)一起建立。
從頭開始訓練
以下範例顯示從頭開始訓練的命令行。使用以上命令行建立的預設訓練資料嘗試一下。
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
(請注意,網路規格中的「O1c111」表示 111 個輸出類別;這應與 unicharset 檔案中的條目數相符。)
在單獨的視窗中監控日誌檔
tail -f ~/tesstutorial/engoutput/basetrain.log
您應該會觀察到,到 600 次迭代時,空格(白色)開始在 CTC Outputs
視窗中顯示,到 1300 次迭代時,LSTMForward
視窗中會在圖像中存在空格的地方出現綠線。
到 1300 次迭代時,在 CTC Outputs
中會出現明顯的非空格突起。請注意,由於空格的明確輸出以及一些其他字元的暫定輸出,CTC Targets
的高度從一開始的完全相同,現在有所不同。同時,LSTMTraining
視窗中的字元和綠線位置不如一開始準確,因為來自網路的部分輸出會混淆 CTC 演算法。(CTC 假設不同的 x 坐標之間具有統計獨立性,但它們顯然不是獨立的。)
到 2000 次迭代時,應該在 Output
視窗中清楚地看到,出現了一些微弱的黃色標記,表示非空且非空格的輸出正在增加,並且字元開始出現在 LSTMForward
視窗中。
字元錯誤率在 3700 次迭代後剛好降至 50% 以下,到 5000 次迭代時降至約 13%,它將在此終止。(在大約 20 分鐘內,在具有 AVX 的目前高階機器上。)
請注意,此引擎的訓練資料量與舊版 Tesseract 引擎使用的訓練資料量相同,但其在其他字型上的準確性可能非常差。在「Impact」字型上執行獨立測試
training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \
--traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
85% 的字元錯誤率?不太好!
現在基本的 Tesseract 在 ‘Impact’ 字體上的表現不佳,但它被包含在用於訓練新 LSTM 版本的約 4500 種字體中,所以如果你能用它進行比較的話
training/lstmeval --model tessdata/best/eng.traineddata \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
2.45% 的字元錯誤率?好多了!
作為下一節的參考,也請在我們一直在使用的訓練集上運行完整模型的測試
training/lstmeval --model tessdata/best/eng.traineddata \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt
字元錯誤率=0.25047642,單字錯誤率=0.63389585
你可以再訓練 5000 次迭代,並讓訓練集上的錯誤率降低很多,但這對 Impact
字體沒有太大幫助
mkdir -p ~/tesstutorial/engoutput
training/lstmtraining \
--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 10000 &>>~/tesstutorial/engoutput/basetrain.log
Impact
字體的字元錯誤率現在 >100%,即使訓練集上的錯誤率已降至 2.68% 的字元 / 10.01% 的單字
training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \
--traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
這顯示該模型已完全過擬合於提供的訓練集!這是一個很好的例子,說明當訓練集未涵蓋目標資料中所需的變化時會發生什麼。
總而言之,從頭開始訓練需要一個非常受限的問題、大量的訓練資料,或者你需要透過減少上述 --net_spec
中某些層的大小來縮小網路。或者,你可以嘗試微調...
針對影響進行微調
請注意,Impact 的微調只能透過使用 float
模型作為繼續的基礎來完成,也就是說,使用來自 tessdata_best 儲存庫的 traineddata 檔案,而不是來自 tessdata 或 tessdata_fast 的檔案。
微調是在不更改網路任何部分的情況下,在新資料上訓練現有模型的過程,儘管你現在可以將字元添加到字元集中。(請參閱針對 ± 幾個字元的微調)。
training/lstmtraining --model_output /path/to/output [--max_image_MB 6000] \
--continue_from /path/to/existing/model \
--traineddata /path/to/original/traineddata \
[--perfect_sample_delay 0] [--debug_interval 0] \
[--max_iterations 0] [--target_error_rate 0.01] \
--train_listfile /path/to/list/of/filenames.txt
請注意,--continue_from
參數可以指向訓練檢查點或識別模型,即使檔案格式不同。 訓練檢查點是開頭為 --model_output
並以 checkpoint
結尾的檔案。可以使用 combine_tessdata
從現有的 traineddata 檔案中提取識別模型。請注意,也必須提供原始的 traineddata 檔案,因為其中包含 unicharset 和 recoder。讓我們從微調我們之前建立的模型開始,看看我們是否可以讓它適用於 ‘Impact’
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
在 100 次迭代後,它的字元/單字錯誤率為 22.36%/50.0%,在 1200 次迭代時降至 0.3%/1.2%。現在進行獨立測試
training/lstmeval --model ~/tesstutorial/impact_from_small/impact_checkpoint \
--traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
這顯示了更好的結果 0.0086%/0.057%,因為訓練器對 1000 次迭代求平均值,而且它一直在改進。雖然這不是 Impact
字體的代表性結果,因為我們正在訓練資料上進行測試!
這是一個有點像玩具的例子。微調的想法實際上是將其應用於完全訓練的現有模型之一
mkdir -p ~/tesstutorial/impact_from_full
training/combine_tessdata -e tessdata/best/eng.traineddata \
~/tesstutorial/impact_from_full/eng.lstm
training/lstmtraining --model_output ~/tesstutorial/impact_from_full/impact \
--continue_from ~/tesstutorial/impact_from_full/eng.lstm \
--traineddata tessdata/best/eng.traineddata \
--train_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 400
經過 100 次迭代後,它的字元/單字錯誤率為 1.35%/4.56%,在 400 次迭代時降至 0.533%/1.633%。同樣,獨立測試會產生更好的結果
training/lstmeval --model ~/tesstutorial/impact_from_full/impact_checkpoint \
--traineddata tessdata/best/eng.traineddata \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
字元錯誤率 0.017%,單字錯誤率 0.120%。但更有趣的是它對其他字體的影響,因此請在我們一直在使用的基本訓練集上運行測試
training/lstmeval --model ~/tesstutorial/impact_from_full/impact_checkpoint \
--traineddata tessdata/best/eng.traineddata \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt
字元錯誤率=0.25548592,單字錯誤率=0.82523491
儘管在訓練集上已達到接近零的錯誤率,並且僅在 400 次迭代中就實現了這一點,但它僅稍微差一點。請注意,超過 400 次迭代的進一步訓練會使基本集上的錯誤更高。
總而言之,預訓練模型可以微調或調整為小型資料集,而不會對其整體準確性造成太大損害。 然而,避免過度擬合仍然非常重要。
針對 ± 幾個字元進行微調
請注意,針對 ± 幾個字元的微調只能透過使用 float
模型作為繼續的基礎來完成,也就是說,使用來自 tessdata_best 儲存庫的 traineddata 檔案,而不是來自 tessdata 或 tessdata_fast 的檔案。
新功能 可以在字元集中新增一些新字元,並透過微調來訓練它們,而無需大量的訓練資料。
訓練需要新的 unicharset/recoder、可選的語言模型,以及包含舊 unicharset/recoder 的舊 traineddata 檔案。
training/lstmtraining --model_output /path/to/output [--max_image_MB 6000] \
--continue_from /path/to/existing/model \
--traineddata /path/to/traineddata/with/new/unicharset \
--old_traineddata /path/to/existing/traineddata \
[--perfect_sample_delay 0] [--debug_interval 0] \
[--max_iterations 0] [--target_error_rate 0.01] \
--train_listfile /path/to/list/of/filenames.txt
讓我們嘗試將加減號 (±) 新增到現有的英文模型中。修改 langdata/eng/eng.training_text
以包含 ± 的一些範例。我插入了 14 個,如下所示
grep ± ../langdata/eng/eng.training_text
alkoxy of LEAVES ±1.84% by Buying curved RESISTANCE MARKED Your (Vol. SPANIEL
TRAVELED ±85¢ , reliable Events THOUSANDS TRADITIONS. ANTI-US Bedroom Leadership
Inc. with DESIGNS self; ball changed. MANHATTAN Harvey's ±1.31 POPSET Os—C(11)
VOLVO abdomen, ±65°C, AEROMEXICO SUMMONER = (1961) About WASHING Missouri
PATENTSCOPE® # © HOME SECOND HAI Business most COLETTI, ±14¢ Flujo Gilbert
Dresdner Yesterday's Dilated SYSTEMS Your FOUR ±90° Gogol PARTIALLY BOARDS firm
Email ACTUAL QUEENSLAND Carl's Unruly ±8.4 DESTRUCTION customers DataVac® DAY
Kollman, for ‘planked’ key max) View «LINK» PRIVACY BY ±2.96% Ask! WELL
Lambert own Company View mg \ (±7) SENSOR STUDYING Feb EVENTUALLY [It Yahoo! Tv
United by #DEFINE Rebel PERFORMED ±500Gb Oliver Forums Many | ©2003-2008 Used OF
Avoidance Moosejaw pm* ±18 note: PROBE Jailbroken RAISE Fountains Write Goods (±6)
Oberflachen source.” CULTURED CUTTING Home 06-13-2008, § ±44.01189673355 €
netting Bookmark of WE MORE) STRENGTH IDENTICAL ±2? activity PROPERTY MAINTAINED
現在產生新的訓練和評估資料
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
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
在新訓練資料上運行微調。這需要更多迭代,因為它只有少數幾個新目標字元的樣本
training/combine_tessdata -e tessdata/best/eng.traineddata \
~/tesstutorial/trainplusminus/eng.lstm
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
經過 100 次迭代後,它的字元/單字錯誤率為 1.26%/3.98%,在 3600 次迭代時降至 0.041%/0.185%。同樣,獨立測試會產生更好的結果
training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \
--traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/trainplusminus/eng.training_files.txt
字元錯誤率 0.0326%,單字錯誤率 0.128%。但更有趣的是,新字元是否可以在 ‘Impact’ 字體中被識別,因此請在 impact 評估集上運行測試
training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \
--traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/evalplusminus/eng.training_files.txt
字元錯誤率=2.3767074,單字錯誤率=8.3829474
這與原始模型在 impact 資料集上的原始測試相比非常好。此外,如果您檢查錯誤
training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \
--traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/evalplusminus/eng.training_files.txt 2>&1 |
grep ±
...您應該會看到它正確辨識了所有 ± 符號!(每個包含 ± 的正確行,在相應的 OCR 行上也包含 ±,並且 grep 輸出中沒有沒有匹配 OCR 行的正確行。)
這是個好消息!這表示可以新增一個或多個新字元,而不會影響現有的準確性,而且辨識新字元的能力至少在某種程度上會推廣到其他字體!
注意:在微調時,嘗試迭代次數非常重要,因為在小型資料集上進行過度訓練會導致過度擬合。ADAM 非常適合尋找使罕見類別正確的必要特徵組合,但它似乎比更簡單的優化器更過度擬合。
僅訓練幾個層
請注意,僅訓練幾個圖層只能透過使用 float
模型作為繼續的基礎來完成,也就是說,使用來自 tessdata_best 儲存庫的 traineddata 檔案,而不是來自 tessdata 或 tessdata_fast 的檔案。
如果您只想新增新的字體樣式或需要幾個新字元,微調還可以,但是如果您想訓練克林貢語呢?您不太可能有太多訓練資料,而且它與其他任何東西都不同,那麼您該怎麼辦?您可以嘗試移除現有網路模型的一些頂層,將其中一些層替換為新的隨機層,並使用您的資料進行訓練。命令行與從頭開始訓練大致相同,但此外您還必須提供模型來使用 --continue_from
和 --append_index
。
--append_index
參數告訴它移除具有給定索引的圖層之上的所有圖層(從最外層系列的零開始),然後將給定的 --net_spec
參數附加到剩餘的圖層。雖然此索引系統不是引用網路圖層的完美方式,但它是大大簡化的網路規格語言的結果。建構器將輸出一個對應於其產生的網路的字串,使得檢查索引是否指向預期的圖層變得相當容易。
4.00 alpha 的新功能是 combine_tessdata 可以列出 traineddata 檔案的內容及其版本字串。在大多數情況下,版本字串包含用於訓練的 net_spec
training/combine_tessdata -d tessdata/best/heb.traineddata
Version string:4.00.00alpha:heb:synth20170629:[1,36,0,1Ct3,3,16Mp3,3Lfys48Lfx96Lrx96Lfx192O1c1]
17:lstm:size=3022651, offset=192
18:lstm-punc-dawg:size=3022651, offset=3022843
19:lstm-word-dawg:size=673826, offset=3024221
20:lstm-number-dawg:size=625, offset=3698047
21:lstm-unicharset:size=1673826, offset=3703368
22:lstm-recoder:size=4023, offset=3703368
23:version:size=80, offset=3703993
對於 chi_sim 而言
training/combine_tessdata -d tessdata/best/chi_sim.traineddata
Version string:4.00.00alpha:chi_sim:synth20170629:[1,48,0,1Ct3,3,16Mp3,3Lfys64Lfx96Lrx96Lfx512O1c1]
0:config:size=1966, offset=192
17:lstm:size=12152851, offset=2158
18:lstm-punc-dawg:size=282, offset=12155009
19:lstm-word-dawg:size=590634, offset=12155291
20:lstm-number-dawg:size=82, offset=12745925
21:lstm-unicharset:size=258834, offset=12746007
22:lstm-recoder:size=72494, offset=13004841
23:version:size=84, offset=13077335
請注意,圖層數相同,但只有大小不同。因此,在這些模型中,以下 --append_index
的值將保留相關的最後一層,並附加在上方
索引 | 圖層 |
---|---|
0 |
輸入 |
1 |
Ct3,3,16 |
2 |
Mp3,3 |
3 |
Lfys48/64 |
4 |
Lfx96 |
5 |
Lrx96 |
6 |
Lfx192/512 |
現有模型其餘部分的權重最初保持不變,但允許被新訓練資料修改。
作為一個範例,讓我們嘗試將現有的 chi_sim 模型轉換為 eng。我們將截斷最後的 LSTM 圖層(對於 chi_sim 而言比用於訓練 eng 模型的更大)和 softmax,替換為較小的 LSTM 圖層和新的 softmax
mkdir -p ~/tesstutorial/eng_from_chi
training/combine_tessdata -e tessdata/best/chi_sim.traineddata \
~/tesstutorial/eng_from_chi/eng.lstm
training/lstmtraining --debug_interval 100 \
--continue_from ~/tesstutorial/eng_from_chi/eng.lstm \
--traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
--append_index 5 --net_spec '[Lfx256 O1c111]' \
--model_output ~/tesstutorial/eng_from_chi/base \
--train_listfile ~/tesstutorial/engtrain/eng.training_files.txt \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 3000 &>~/tesstutorial/eng_from_chi/basetrain.log
由於較低的圖層已經過訓練,因此學習速度比從頭開始訓練快一些。在 600 次迭代時,它突然開始產生輸出,到 800 次時,它已經能正確辨識大部分字元。當它在 3000 次迭代時停止時,它應該達到 6.00% 的字元/22.42% 的單字。
嘗試在完整訓練集上進行通常的測試
training/lstmeval --model ~/tesstutorial/eng_from_chi/base_checkpoint \
--traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt
以及在 Impact
字體上的獨立測試
training/lstmeval --model ~/tesstutorial/eng_from_chi/base_checkpoint \
--traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
在完整訓練集上,我們得到 5.557%/20.43%,在 Impact
上得到 36.67%/83.23%,這比從頭開始訓練要好得多,但仍然嚴重過度擬合。
總而言之,可以截斷現有網路的頂層並進行訓練,就像從頭開始一樣,但仍然需要相當大量的訓練資料才能避免過度擬合。
訓練中的錯誤訊息
運行訓練時可能會出現各種錯誤訊息,其中一些可能很重要,而另一些則不太重要
當訓練影像的文字字串無法使用給定的 unicharset 進行編碼時,會產生 Encoding of string failed!
。可能的原因是
- 文字中存在未表示的字元,例如不在您的 unicharset 中的英鎊符號。
- 文字中存在未知的不可列印字元(如製表符或控制字元)。
- 文字中存在未表示的印度語字形/字母。
無論如何,這都會導致訓練器忽略該訓練影像。如果錯誤不常發生,則是無害的,但它可能表示您的 unicharset 不足以表示您正在訓練的語言。
Unichar xxx 字元太長,無法編碼!!
(很可能是印度語系文字)。在 recoder 中可使用的 Unicode 字元長度有上限,這樣可以簡化 LSTM 引擎的 unicharset。它會繼續執行,並將該 Aksara 字元排除在可識別的集合之外,但如果有很多這種情況,您就會遇到麻煩。
boxfile 字串中的 box 座標錯誤!
LSTM 訓練器只需要完整文字行的邊界框資訊,而不是字元層級的資訊,但如果您在 box 字串中加入空格,像這樣:
<text for line including spaces> <left> <bottom> <right> <top> <page>
解析器會感到困惑並給您錯誤訊息。
Deserialize header failed
當訓練輸入不是 LSTM 格式或檔案無法讀取時會發生。請檢查您的檔案列表檔案,看看是否包含有效的檔名。
No block overlapping textline:
當版面分析無法正確分割作為訓練資料提供的圖片時會發生。該文字行會被捨棄。如果數量不多,問題不大,但如果有很多,則訓練文字或渲染過程可能存在問題。
<Undecodable>
可能在訓練初期出現在 ALIGNED_TRUTH 或 OCR TEXT 輸出中。這是 unicharset 壓縮和 CTC 訓練的結果。(請參閱上面的 Unicharset 壓縮和 train_mode)。這應該是無害的,可以安全地忽略。它的頻率應隨著訓練的進展而下降。
合併輸出檔案
lstmtraining 程式會輸出兩種檢查點檔案
<model_base>_checkpoint
是最新的模型檔案。<model_base><char_error>_<iteration>.checkpoint
會定期寫入,作為具有最佳訓練誤差的模型。它是一個訓練傾印,就像檢查點一樣,但它更小,因為它沒有備份模型,以便在訓練出現偏差時使用。
這些檔案中的任何一個都可以轉換為標準的 traineddata 檔案,如下所示:
training/lstmtraining --stop_training \
--continue_from ~/tesstutorial/eng_from_chi/base_checkpoint \
--traineddata /path/to/traineddata/used/in/lstmtraining/eng.traineddata \
--model_output ~/tesstutorial/eng_from_chi/eng.traineddata
這會從訓練傾印中提取識別模型,並將其與 unicharset、recoder 和訓練期間提供的任何 dawg 一起插入到 –traineddata 參數中。
注意 Tesseract 4.00 現在可以順利使用僅包含 lang.lstm
、lang.lstm-unicharset
和 lang.lstm-recoder
的 traineddata 檔案。 lstm-*-dawgs
是可選的,如果使用 OEM_LSTM_ONLY 作為 OCR 引擎模式,則不需要或使用其他任何元件。 不需要或甚至不會影響任何 bigrams、unichar ambigs 或其他元件。唯一有作用的其他元件是 lang.config
,它可以影響版面分析和子語言。
如果將 lstm-unicharset
新增到現有的 Tesseract traineddata 檔案中,則不需要與 Tesseract unicharset
匹配,但必須使用相同的 unicharset 來訓練 LSTM 並建構 lstm-*-dawgs
檔案。
幻覺效應
如果您發現您的模型行為異常,例如:
- 在某些單字開頭加上
Capital
大寫字母,而不是Small
小寫字母。 - 在不應該加
Space
空格的地方加上空格。 - 等等...