文字識別是對序列的預測方法,所以采用了對序列預測的RNN網絡。通過CNN將圖片的特征提取出來後采用RNN對序列進行預測,最後通過壹個CTC的翻譯層得到最終結果。
所以CRNN算法主要采用的是CNN+RNN+CTC三層網絡結構,從下到上,依次為:
(1)卷積層,使用CNN,從輸入圖像中提取特征序列;
(2)循環層,使用RNN,預測從卷積層獲取的特征序列的標簽(真實值)分布;
(3)轉錄層,使用CTC,把從循環層獲取的標簽分布通過去重整合等操作轉換成最終的識別結果。
卷積層***包含7層卷積神經網絡,基礎結構采用的是VGC的結構,其中輸入是把灰度圖縮放到尺寸為W*32,即固定高。在第三個和第四個池化層的時候,為了追求真實的高寬比例,采用的核尺寸為1*2(並非2*2)。為了加速收斂並引入了BN層。 把CNN提取到的特征圖按列切分,每壹列的512維特征,輸入到兩層各256單元的雙向LSTM進行分類。在訓練過程中,通過CTC損失函數的指導,實現字符位置與類標的近似軟對齊。
如圖:
現在需要從CNN模型產生的特征圖中提取特征向量序列,每壹個特征向量(紅色框)在特征圖上按列從左到右生成,每壹列包含512維特征,這意味著第i個特征向量是所有的特征圖第i列像素的連接,這些特征向量就構成壹個序列。
由於卷積層,最大池化層和激活函數在局部區域上執行,因此它們是平移不變的。因此特征圖的每列(即壹個特征向量)對應於原始圖像的壹個矩形區域(成為感受野),並且這些矩形區域與特征圖上從左到右的相應列具有相同的順序。特征序列中的每個向量關聯壹個感受野。
提取的特征序列中的向量是從特征圖上從左到右按照順序生成的,每個特征向量表示了圖像上壹定寬度上的特征,論文中使用的這個寬度是1,就是單個像素。
如果壹張包含10個字符的圖片大小為100×32,經過上述的CNN網絡得到的特征尺度為25×1(這裏忽略通道數),這樣得到壹個序列,每壹列特征對應原圖的壹個矩形區域(如下圖所示),這樣就很方便作為RNN的輸入進行下壹步的計算了,而且每個特征與輸入有壹個壹對壹的對應關系。
從上圖可以看出,對VGG的調整如下:
1.為了能將CNN提取的特征作為輸入,輸入到RNN網絡中,文章將第三和第四個maxpooling的核尺度從2×2改為了1×2
2.為了加速網絡的訓練,在第五和第六個卷積層後面加上了BN層。
為什麽將第三和第四個maxpooling的核尺度從2×2改為1×2是為了方便的將CNN的提取特征作為RNN的輸入.首先要註意的是這個網絡的輸入為W×32,也就是說該網絡對輸入圖片的寬沒有特殊的要求,但是高都必須resize到32。
假設現在輸入有個圖像,為了將特征輸入到Recurrent Layers,做如下處理:
關於CNN原理詳解,具體可以參考: /writer#/notebooks/46006121/notes/71156459
因為 RNN 有梯度消失的問題,不能獲取更多上下文信息,所以 CRNN 中使用的是 LSTM,LSTM 的特殊設計允許它捕獲長距離依賴。
RNN網絡是對於CNN輸出的特征序列x=x1,?,xt,每壹個輸入xt,都有壹個輸出yt, 為了防止訓練時梯度的消失,文章采用了LSTM神經單元作為RNN的單元。文章認為對於序列的預測,序列的前向信息和後向信息都有助於序列的預測,所以文章采用了雙向RNN網絡。LSTM神經元的結構和雙向RNN結構如下圖所示。
示例:
通過上面壹步,我們得到了40個特征向量,每個特征向量長度為512,在 LSTM 中壹個時間步就傳入壹個特征向量進行分類,這裏壹***有40個時間步。
我們知道壹個特征向量就相當於原圖中的壹個小矩形區域,RNN 的目標就是預測這個矩形區域為哪個字符,即根據輸入的特征向量,進行預測,得到所有字符的softmax概率分布,這是壹個長度為字符類別數的向量,作為CTC層的輸入。
因為每個時間步都會有壹個輸入特征向量 ,輸出壹個所有字符的概率分布 ,所以輸出為 40 個長度為字符類別數的向量構成的後驗概率矩陣,然後將這個後驗概率矩陣傳入轉錄層。
測試時,翻譯分為兩種,壹種是帶字典的,壹種是沒有字典的。
帶字典的就是在測試的時候,測試集是有字典的,測試的輸出結果計算出所有字典的概率,取最大的即為最終的預測字符串
不帶字典的,是指測試集沒有給出測試集包含哪些字符串,預測時就選取輸出概率最大的作為最終的預測字符串。
端到端OCR識別的難點在於怎麽處理不定長序列對齊的問題!(因為是不定長序列,按照以前的方法我們很難去計算loss,如果是定長的話容易造成信息的丟失,而且局限性太大!)
轉錄是將 RNN 對每個特征向量所做的預測轉換成標簽序列的過程。數學上,轉錄是根據每幀預測找到具有最高概率組合的標簽序列。
具體可以參考: /writer#/notebooks/46006121/notes/71156474