背景介紹見:深度學習:識別圖片中的電話號碼(1)
識別電話號碼最終采用的是:循環卷積網絡。先看下網絡的結構,有幾處比較trick的地方,后面會講到。
注意的地方
1. 上圖中的網絡是訓練網絡的結構,訓練的輸入有三個:image圖片;seq是時序的標識,如果時序長度為5則為[0,1,1,1,1],0表示序列的開始,1表示序列繼續(當前時刻有信號輸入),上一時刻的細胞狀態會傳遞給當前時刻。label表示序列的真實結果,如“123”應該表示為[1,2,3,-1,-1],長度和seq一致。
在batchsize中,多個樣本的seq大小如果不同,短序列的seq=[0,1,1,…1,0,0..0],表示短序列提前結束了。當然電話識別中,把圖片特征按列等分了n份,大家的序列長度是一致的。
2. 序列的分割
輸入image的大小是:batch_size*3*h*w
輸入seq的大小是:batch_size*n ,n表示序列的長度=圖片特征要切割的份數
輸入label的大小是:batch_size*n
經過ZF特征提取網絡,relu5的輸出為:batch_size*num_output*height*width,num_output表示featureMap的數據,width/height特征層的寬高。
trans1轉置層,參數為:
transpose_param {
dim: 0
dim: 3
dim: 2
dim: 1
}
輸出的維度為:batch_size*width*num_output*height。trick的做法是:n的大小可以設置為width,即把特征層的每一列作為一個時刻的輸入。
conv5_trans為全連接層,當然它的全連接只針對某一列在num_output個featureMap上的節點進行,參數為:
inner_product_param {
num_output: 4096
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
axis: 2
}
輸出為:batch_size*width(n)*4096。
3. 構建序列,主要是構建LSTM的輸入格式,注意LSTM的輸入是:T*batch_size*C,T就是時序長度n,C是特征的維度即4096。
4. LSTM的輸出為:T*batch_size*lstm_c,lstm_c表示LSTM中特征維度的大小,這里取256。
經過fc-final,全連接為字符的種類數目+1(背景)。比如數字,輸出為T*batch_size*11。
5. 最終輸入CTC網絡,CTC網絡會對T時刻的數據做后處理計算與真實label的差異,返回loss。正如上節說的,T的大小應該大於label的長度,因為CTC的后處理會把結果中的空格(背景)和連續相同字符去除(重復識別)去除,如果T<len(label),后處理后得到的字符一定和label不同了,這樣就沒意義了。
比如T=20,序列為:“1_88_8_1_1_66_10_16_8”,處理后得到“18811610168”。
檢測網絡
檢測網絡和訓練類似,只是CTCLoss層替換為CTCDecoder即可。
由於新加了一些層的依賴,基於的caffe為:https://github.com/houkai/caffe