OCR演算法:CNN+BLSTM+CTC架構(VS15)
原文連結:OCR演算法-CNN+BLSTM+CTC架構
由於作者使用了Boost1.57-Vc14,而1.57的VC14版本作者沒有給出下載連結,因此需要自行編譯,建議換掉作者的第三方庫,使用其他的庫,比如:這篇文章:VS編譯Caffe非常簡單。網盤:3rdlibVC14。
實驗結果:
實測結果inception的準確率要比resnet高一些,ResNet把熱情識別為然情,把溫柔識別成溫採.
主流ocr演算法研究實驗性的專案,目前實現了CNN+BLSTM+CTC架構
C++Cuda Other
Clone or download Find file
Latest commit
README.md
簡介
caffe_ocr是一個對現有主流ocr演算法研究實驗性的專案,目前實現了CNN+BLSTM+CTC的識別架構,並在資料準備、網路設計、調參等方面進行了諸多的實驗。程式碼包含了對lstm、warp-ctc、multi-label等的適配和修改,還有基於inception、restnet、densenet的網路結構。程式碼是針對windows平臺的,linux平臺下只需要合併相關的修改到caffe程式碼中即可。
caffe程式碼修改
1. data layer增加了對multi-label的支援
2. lstm使用的是junhyukoh實現的lstm版本(lstm_layer_Junhyuk.cpp/cu),原版不支援變長輸入的識別。輸入的shape由(TxN)xH改為TxNxH以適應ctc的輸入結構。
3. WarpCTCLossLayer去掉了對sequence indicators依賴(訓練時CNN輸出的結構是固定的),簡化了網路結構(不需要sequence indicator layer)。
4. densenet修改了對Reshape沒有正確響應的bug,實現了對變長輸入預測的支援。
5. 增加transpose_layer、reverse_layer,實現對CNN feature map與lstm輸入shape的適配
編譯
1. 安裝opencv,boost,cuda,其它依賴庫在3rdparty下(包含debug版的lib:http://pan.baidu.com/s/1nvIFojJ)
2. caffe-vsproj下為vs2015的工程,配置好依賴庫的路徑即可編譯,編譯後會在tools_bin目錄下生成訓練程式caffe.exe
3. 相關的依賴dll可從百度網盤下載(http://pan.baidu.com/s/1boOiscJ)
實驗
- 資料為利用中文語料庫(新聞+文言文),通過字型、大小、灰度、模糊、透視、拉伸等變化隨機生成。
- 字典中包含漢字、標點、英文、數字共5990個字元(語料字頻統計,全形半形合併)
- 每個樣本固定10個字元,字元隨機擷取自語料庫中的句子
- 圖片解析度統一為280x32
- 共生成約360萬張圖片,按9:1分成訓練集、驗證集(暫時沒有分測試集)
- 網路設計:網路結構在examples/ocr目錄下
- 主要實驗結果
- 英文資料集 VGG Synthetic Word Dataset:
網格結構 | predict-CPU | predict-GPU | 準確率-no lexicon | 準確率-lexicon-minctcloss | 模型大小 |
---|---|---|---|---|---|
crnn | 67.13ms | 10.28ms | 0.8435 | 0.9163 | 32MB |
inception-bn-res-blstm | 41.62ms | 8.68ms | 0.7353 | 0.8609 | 15MB |
densenet-res-blstm | N/A | 6.07ms | 0.7548 | 0.893 | 11MB |
- 中文資料集:
網格結構 | predict-CPU | predict-GPU | 準確率 | 模型大小 |
---|---|---|---|---|
inception-bn-res-blstm | 65.4ms | 11.2ms | 0.92 | 26.9MB |
resnet-res-blstm | 64ms | 10.75ms | 0.91 | 23.2MB |
densenet-res-blstm | N/A | 7.73ms | 0.965 | 22.9MB |
densenet-no-blstm | N/A | 2.4ms | 0.97 | 5.6MB |
densenet-sum-blstm-full-res-blstm | N/A | 7.83ms | 0.9805 | 15.5MB |
densenet-no-blstm-vertical-feature | N/A | 3.05ms | 0.9816 | 9.6MB |
說明:
- CPU是Xeon E3 1230, GPU是1080TI
- densenet使用的是memory-efficient版本,其CPU程式碼並沒有使用blas庫,只是實現了原始的卷積操作,速度非常慢,待優化後再做對比。
- “res-blstm”表示殘差形式的blstm,“no-blstm”表示沒有lstm層,CNN直接對接CTC
- 準確率是指整串正確的比例,在驗證集上統計,"準確率-no lexicon"表示沒用詞典的準確率,"準確率-lexicon-minctcloss"指先在詞典中查詢Edit Distance <=2的單詞,再選擇ctcloss最小的單詞作為識別結果
- predict-CPU/GPU為單張圖片的預測時間,predict-CPU的後端是openblas,MKL比openblas快約一倍。中文資料集上圖片解析度為280x32,英文資料集100x32
- densenet-sum-blstm-full-res-blstm相對於densenet-res-blstm有兩點改動:(1)兩個lstm結合成blstm的方式由concat改為sum;(2)兩層blstm都採用殘差方式連線(CNN最後的Channel數改為與blstm結點數相同),最後得到了最高的準確率。
- densenet-no-blstm-vertical-feature相對於densenet-no-blstm去掉了1x4的pooling層,使得CNN最後一層的feature maps的高度為4,更好的保留筆畫在垂直方向的變化資訊,再reshape BxCxHxW --> Bx(CxH)x1xW串成高度為1的feature maps, 最後準確率上略好於之前的最好結果,可見CNN feature方面還有很多可挖掘的地方。
- 一些tricks
(1) 殘差形式的blstm可顯著提升準確率,中文資料集上0.94-->0.965,兩層BLSTM都用殘差後又提升到了0.9805
(2) 網路的CNN部分相對於BLSTM部分可以設定更高的學習率,這樣可以顯著增加收斂速度 - 疑問
(1)去掉blstm,直接用CNN+CTC的結構,在中文資料集上也可以取得很高的準確率(densenet-no-blstm),為什麼?
可能的原因:a)CNN最後一層得到的特徵對於字元級別的建模已經具有很好表徵,b)lstm收斂較慢,需要更長的時間才能達到相同的精度。 - 現存的問題
(1)寬度較小的數字、英文字元會出現丟字的情況,如“11”、“ll”,應該是因為CNN特徵感受野過大沒有看到文字間隙的緣故。
提高準確率TODO
1. 資料方面: 增大資料量,語料庫均勻取樣(https://yq.aliyun.com/articles/109555?t=t1)
2. 網路方面:增大網路(train、test loss很接近,現有網路沒有過擬合),Attention,STN,輔助loss