一文读懂CRNN+CTC文字识别
轉自:https://zhuanlan.zhihu.com/p/43534801
文字識別也是圖像領域一個常見問題。然而,對于自然場景圖像,首先要定位圖像中的文字位置,然后才能進行識別。
所以一般來說,從自然場景圖片中進行文字識別,需要包括2個步驟:
- 文字檢測:解決的問題是哪里有文字,文字的范圍有多少
- 文字識別:對定位好的文字區域進行識別,主要解決的問題是每個文字是什么,將圖像中的文字區域進轉化為字符信息。
圖1 文字識別的步驟
文字檢測類似于目標檢測,即用 box 標識出圖像中所有文字位置。對于文字檢測不了解的讀者,請參考本專欄文章:
場景文字檢測—CTPN原理與實現?zhuanlan.zhihu.com
本文的重點是如何對已經定位好的文字區域圖片進行識別。假設之前已經文字檢測算法已經定位圖中的“subway”區域(紅框),接下來就是文字識別。
圖2 文字檢測定位文字圖像區域
基于RNN文字識別算法主要有兩個框架:
?
圖3 基于RNN文字識別2種基本算法框架
本文主要介紹第一種框架CRNN+CTC,對應TensorFlow 1.15實現代碼如下。本文介紹的CRNN網絡結構都基于此代碼。另外該代碼已經支持不定長英文識別。
bai-shang/crnn_ctc_ocr_tf?github.com
需要說明該代碼非常簡單,只用于原理介紹,不保證泛化性等工程問題,也請勿提問。
CRNN基本網絡結構
圖4 CRNN網絡結構(此圖按照本文給出的github實現代碼畫的)
整個CRNN網絡可以分為三個部分:
假設輸入圖像大小為?,注意提及圖像都是??形式。
- Convlutional Layers
這里的卷積層就是一個普通的CNN網絡,用于提取輸入圖像的Convolutional feature maps,即將大小為??的圖像轉換為??大小的卷積特征矩陣,網絡細節請參考本文給出的實現代碼。
- Recurrent Layers
這里的循環網絡層是一個深層雙向LSTM網絡,在卷積特征的基礎上繼續提取文字序列特征。對RNN不了解的讀者,建議參考:
完全解析RNN, Seq2Seq, Attention注意力機制?zhuanlan.zhihu.com
所謂深層RNN網絡,是指超過兩層的RNN網絡。對于單層雙向RNN網絡,結構如下:
圖5 單層雙向RNN網絡
而對于深層雙向RNN網絡,主要有2種不同的實現:
tf.nn.bidirectional_dynamic_rnn圖6 深層雙向RNN網絡
tf.contrib.rnn.stack_bidirectional_dynamic_rnn圖7 stack形深層雙向RNN網絡
在CRNN中顯然使用了第二種stack形深層雙向結構。
由于CNN輸出的Feature map是大小,所以對于RNN最大時間長度??(即有25個時間輸入,每個輸入??列向量有??)。
- Transcription Layers
將RNN輸出做softmax后,為字符輸出。
關于代碼中輸入圖片大小的解釋:
在本文給出的實現中,為了將特征輸入到Recurrent Layers,做如下處理:
- 首先會將圖像在固定長寬比的情況下縮放到??大小(??代表任意寬度)
- 然后經過CNN后變為?
- 針對LSTM設置??,即可將特征輸入LSTM。
所以在處理輸入圖像的時候,建議在保持長寬比的情況下將高縮放到?,這樣能夠盡量不破壞圖像中的文本細節(當然也可以將輸入圖像縮放到固定寬度,但是這樣由于破壞文本的形狀,肯定會造成性能下降)。
考慮訓練Recurrent Layers時的一個問題:
圖8 感受野與RNN標簽的關系
對于Recurrent Layers,如果使用常見的Softmax cross-entropy loss,則每一列輸出都需要對應一個字符元素。那么訓練時候每張樣本圖片都需要標記出每個字符在圖片中的位置,再通過CNN感受野對齊到Feature map的每一列獲取該列輸出對應的Label才能進行訓練,如圖9。
在實際情況中,標記這種對齊樣本非常困難(除了標記字符,還要標記每個字符的位置),工作量非常大。另外,由于每張樣本的字符數量不同,字體樣式不同,字體大小不同,導致每列輸出并不一定能與每個字符一一對應。
當然這種問題同樣存在于語音識別領域。例如有人說話快,有人說話慢,那么如何進行語音幀對齊,是一直以來困擾語音識別的巨大難題。
圖9
所以CTC提出一種對不需要對齊的Loss計算方法,用于訓練網絡,被廣泛應用于文本行識別和語音識別中。
Connectionist Temporal Classification(CTC)詳解
在分析過程中盡量保持和原文符號一致。
Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks?ftp.idsia.ch
?
整個CRNN的流程如圖10。先通過CNN提取文本圖片的Feature map,然后將每一個channel作為??的時間序列輸入到LSTM中。
圖10 CRNN+CTC框架
為了說明問題,我們定義:
- CNN Feature map
Feature map的每一列作為一個時間片輸入到LSTM中。設Feature map大小為??(圖11中??,?)。下文中的時間序列??都從??開始,即??。
定義為:
其中??每一列??為:
- LSTM
LSTM的每一個時間片后接softmax,輸出??是一個后驗概率矩陣,定義為:
其中,??的每一列??為:
其中??代表需要識別的字符集合長度。由于??是概率,所以服從概率假設:
對??每一列進行??操作,即可獲得每一列輸出字符的類別。
那么LSTM可以表示為:
其中??代表LSTM的參數。LSTM在輸入和輸出間做了如下變換:
圖11
- 空白blank符號
如果要進行??的26個英文字符識別,考慮到有的位置沒有字符,定義插入blank的字符集合:
其中blank表示當前列對應的圖像位置沒有字符(下文以符號表示blank)。
- 關于?變換
定義變換??如下(原文是大寫的??,知乎沒這個符號):
其中??是上述加入blank的長度為??的字符集合,經過??變換后得到原始??,顯然對于的最大長度有??。
舉例說明,當??時:
對于字符間有blank符號的則不合并:
當獲得LSTM輸出后進行變換,即可獲得輸出結果。顯然??變換不是單對單映射,例如對于不同的都可獲得英文單詞state。同時??成立。
那么CTC怎么做?
對于LSTM給定輸入??的情況下,輸出為??的概率為:
其中??代表所有經過??變換后是??的路徑??。
其中,對于任意一條路徑??有:
注意這里的??中的??,下標??表示??路徑的每一個時刻;而上面??的下標表示不同的路徑。兩個下標含義不同注意區分。
*注意上式??成立有條件,此項不做進一步討論,有興趣的讀者請自行研究。
如對于??的路徑??來說:
實際情況中一般手工設置??,所以有非常多條??路徑,即??非常大,無法逐條求和直接計算??。所以需要一種快速計算方法。
CTC的訓練目標
圖14
CTC的訓練過程,本質上是通過梯度??調整LSTM的參數??,使得對于輸入樣本為??時使得??取得最大。
例如下面圖14的訓練樣本,目標都是使得??時的輸出??變大。
圖14
CTC借用了HMM的“向前—向后”(forward-backward)算法來計算?
要計算??,由于有blank的存在,定義路徑??為在路徑??每兩個元素以及頭尾插入blank。那么對于任意的??都有??(其中??)。如:
顯然??,其中??是路徑的最大長度,如上述例子中??。
定義所有經??變換后結果是??且在??時刻結果為?(記為?)的路徑集合為??。
求導:
注意上式中第二項與??無關,所以:
而上述??就是恰好與概率??相關的路徑,即??時刻都經過??(?)。
舉例說明,還是看上面的例子??(這里的下標??代表不同的路徑):
圖15
藍色路徑??:
紅色路徑??:
還有??沒有畫出來。
而??在??時恰好都經過??(此處下標代表路徑??的??時刻的字符)。所有類似于??經過??變換后結果是??且在??的路徑集合表示為??。
觀察??。記??藍色為??,??紅色路徑為??,??可以表示:
那么??可以表示為:
計算:
為了觀察規律,單獨計算??。
不妨令:
那么可以表示為:
推廣一下,所有經過??變換為??且??的路徑(即??)可以寫成如下形式:
進一步推廣,所有經過??變換為??且??的路徑(即??)也都可以寫作:
所以,定義前向遞推概率和??:
對于一個長度為??的路徑??,其中??代表該路徑前??個字符,??代表后??個字符。
其中??表示前??個字符??經過??變換為的??的前半段子路徑。??代表了??時刻經過??的路徑概率中??概率之和,即前向遞推概率和。
由于當??時路徑只能從blank或??開始,所以??有如下性質:
如上面的例子中??,??,??。對于所有??路徑,當??時只能從blank和??字符開始。
圖16
圖16是??時經過壓縮路徑后能夠變為??的所有路徑??。觀察圖15會發現對于??有如下遞推關系:
也就是說,如果??時刻是字符??,那么??時刻只可能是字符??三選一,否則經過??變換后無法壓縮成??。
那么更一般的:
同理,定義反向遞推概率和??:
其中??表示后??個字符??經過??變換為的??的后半段子路徑。??代表了??時刻經過??的路徑概率中??概率之和,即反向遞推概率和。
由于當??時路徑只能以blank或??結束,所以有如下性質:
如上面的例子中??,??,??,??。對于所有??路徑,當??時只能以??(blank字符)或??字符結束。
觀察圖15會發現對于??有如下遞推關系
與??同理,對于??有如下遞推關系:
那么forward和backward相乘有:
或:
注意,??可以通過圖16的關系對應,如??,。
對比??:
可以得到??與forward和backward遞推公式之間的關系:
* 為什么有上式??成立呢?
回到圖15,為了方便分析,假設只有??共4條在??時刻經過字符??且??變換為??的路徑,即 :
那么此時(注意雖然表示路徑用??加法,但是由于??和??兩件獨立事情同時發生,所以??路徑的概率??是乘法):
則有:
訓練CTC
對于LSTM,有訓練集合??,其中??是圖片經過CNN計算獲得的Feature map,??是圖片對應的OCR字符label(label里面沒有blank字符)。
現在我們要做的事情就是:通過梯度調整LSTM的參數,使得對于輸入樣本為時有??取得最大。所以如何計算梯度才是核心。
單獨來看CTC輸入(即LSTM輸出)??矩陣中的某一個值??(注意??與??含義相同,都是在??時??的概率):
上式中的??是通過遞推計算的常數,任何時候都可以通過遞推快速獲得,那么即可快速計算梯度??,之后梯度上升算法你懂的。
總結
以上是生活随笔為你收集整理的一文读懂CRNN+CTC文字识别的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: SSRS(rdl报表)分页显示表头和对表
- 下一篇: 【codeforces round#80
