多通道(比方RGB三通道)卷積過程
今天一個同學問 卷積過程好像是對 一個通道的圖像進行卷積, 比方10個卷積核,得到10個feature map, 那麽輸入圖像為RGB三個通道呢,輸出就為 30個feature map 嗎, 答案肯定不是的, 輸出的個數依舊是 卷積核的個數。 能夠查看經常使用模型。比方lenet 手寫體,Alex imagenet 模型, 每一層輸出feature map 個數 就是該層卷積核的個數。
1、 一通道單個卷積核卷積過程
2、 一通道 多個卷積核卷積過程
一個卷積核得到的特征提取是不充分的。我們能夠加入多個卷積核,比方32個卷積核,能夠學習32種特征。
在有多個卷積核時,例如以下圖所看到的:輸出就為32個feature map
3、 多通道的多個卷積核
下圖展示了在四個通道上的卷積操作。有兩個卷積核,生成兩個通道。當中須要註意的是,四個通道上每一個通道相應一個卷積核,先將w2忽略,僅僅看w1,那麽在w1的某位置(i,j)處的值,是由四個通道上(i,j)處的卷積結果相加然後再取激活函數值得到的。
所以最後得到兩個feature map。 即輸出層的卷積核核個數為 feature map 的個數。
所以。在上圖由4個通道卷積得到2個通道的過程中,參數的數目為4×2×2×2個。當中4表示4個通道。第一個2表示生成2個通道。最後的2×2表示卷積核大小。
以下是常見模型, 理解一下 每層feature map 個數。為上一層卷積核的個數
下圖即為Alex的CNN結構圖。須要註意的是。該模型採用了2-GPU並行結構,即第1、2、4、5卷積層都是將模型參數分為2部分進行訓練的。
在這裏。更進一步,並行結構分為數據並行與模型並行。
數據並行是指在不同的GPU上,模型結構同樣,但將訓練數據進行切分。分別訓練得到不同的模型,然後再將模型進行融合。
而模型並行則是,將若幹層的模型參數進行切分,不同的GPU上使用同樣的數據進行訓練,得到的結果直接連接作為下一層的輸入。
上圖模型的基本參數為:
輸入:224×224大小的圖片,3通道
第一層卷積:5×5大小的卷積核96個,每一個GPU上48個。
第一層max-pooling:2×2的核。
第二層卷積:3×3卷積核256個,每一個GPU上128個。
第二層max-pooling:2×2的核。
第三層卷積:與上一層是全連接,3*3的卷積核384個。分到兩個GPU上個192個。
第四層卷積:3×3的卷積核384個,兩個GPU各192個。該層與上一層連接沒有經過pooling層。
第五層卷積:3×3的卷積核256個,兩個GPU上個128個。
第五層max-pooling:2×2的核。
第一層全連接:4096維,將第五層max-pooling的輸出連接成為一個一維向量,作為該層的輸入。
第二層全連接:4096維
Softmax層:輸出為1000,輸出的每一維都是圖片屬於該類別的概率。
4 DeepID網絡結構
DeepID網絡結構是香港中文大學的Sun Yi開發出來用來學習人臉特征的卷積神經網絡。每張輸入的人臉被表示為160維的向量。學習到的向量經過其它模型進行分類,在人臉驗證試驗上得到了97.45%的正確率,更進一步的,原作者改進了CNN,又得到了99.15%的正確率。
例如以下圖所看到的,該結構與ImageNet的詳細參數類似,所以僅僅解釋一下不同的部分吧。
上圖中的結構。在最後僅僅有一層全連接層,然後就是softmax層了。論文中就是以該全連接層作為圖像的表示。
在全連接層,以第四層卷積和第三層max-pooling的輸出作為全連接層的輸入,這樣能夠學習到局部的和全局的特征。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
以下講一下,caffe中的實現。
Caffe中的卷積計算是將卷積核矩陣和輸入圖像矩陣變換為兩個大的矩陣A與B,然後A與B進行矩陣相乘得到結果C(利用GPU進行矩陣相乘的高效性),三個矩陣的說明例如以下:
(1)在矩陣A中
M為卷積核個數,K=k*k,等於卷積核大小。即第一個矩陣每行為一個卷積核向量(是將二維的卷積核轉化為一維),總共同擁有M行。表示有M個卷積核。
(2)在矩陣B中
N=((image_h + 2*pad_h – kernel_h)/stride_h+ 1)*((image_w +2*pad_w – kernel_w)/stride_w + 1)
image_h:輸入圖像的高度
image_w:輸入圖像的寬度
pad_h:在輸入圖像的高度方向兩邊各添加pad_h個單位長度(由於有兩邊。所以乘以2)
pad_w:在輸入圖像的寬度方向兩邊各添加pad_w個單位長度(由於有兩邊。所以乘以2)
kernel_h:卷積核的高度
kernel_w:卷積核的寬度
stride_h:高度方向的滑動步長;
stride_w:寬度方向的滑動步長。
因此,N為輸出圖像大小的長寬乘積。也是卷積核在輸入圖像上滑動可截取的最大特征數。
K=k*k。表示利用卷積核大小的框在輸入圖像上滑動所截取的數據大小。與卷積核大小一樣大。
(3)在矩陣C中
矩陣C為矩陣A和矩陣B相乘的結果,得到一個M*N的矩陣,當中每行表示一個輸出圖像即feature map,共同擁有M個輸出圖像(輸出圖像數目等於卷積核數目)
(在Caffe中是使用src/caffe/util/im2col.cu中的im2col和col2im來完畢矩陣的變形和還原操作)
舉個樣例(方便理解):
如果有兩個卷積核為與,因此M=2。kernel_h=2。kernel_w=2,K= kernel_h * kernel_w=4
輸入圖像矩陣為,因此image_h=3,image_w=3。令邊界擴展為0即pad_h=0。pad_w=0。滑動步長為1,即stride_h=1。stride_w=1
故N=[(3+2*0-2)/1+1]*[ (3+2*0-2)/1+1]=2*2=4
A矩陣(M*K)為(一行為一個卷積核),B矩陣(K*N)為(B矩陣的每一列為一個卷積核要卷積的大小)
A 矩陣的由來:::
B矩陣的由來:(caffe 有 imtocol.cpp代碼,專門用於實現)
C=A*B=*=
C中的與分別為兩個輸出特征圖像即feature map。驗證了 有幾個卷積核就有幾個feature map
在Caffe源代碼中,src/caffe/util/math_functions.cu(假設使用CPU則是src/util/math_functions.cpp)中的caffe_gpu_gemm()函數。當中有兩個矩陣A(M*K)
與矩陣 B(K*N)。大家能夠通過輸出M、K、N的值即對應的矩陣內容來驗證上述的原理。代碼中的C矩陣與上述的C矩陣不一樣,代碼中的C矩陣存儲的是偏置bias。
是A 與B相乘後得到M*N大小的矩陣,然後再跟這個存儲偏置的矩陣C相加完畢卷積過程。假設是跑Mnist訓練網絡的話,能夠看到第一個卷積層卷積過程中,
M=20,K=25。N=24*24=576。
(caffe中涉及卷積詳細過程的文件主要有:src/caffe/layers/conv_layer.cu、src/caffe/layers/base_conv_layer.cpp、 src/caffe/util/math_functions.cu、src/caffe/util/im2col.cu)
另外大家也能夠參考知乎上賈揚清大神的回答,幫助理解http://www.zhihu.com/question/28385679
(對於他給出的ppt上的C表示圖像通道個數,假設是RGB圖像則通道數為3。相應於caffe代碼中的變量為src/caffe/layers/base_conv_layer.cpp中
函數forward_gpu_gemm中的group_)
賈揚清的PPT例如以下:
以下看這個就簡單多了, im2col.cpp 的代碼也好理解了
多通道(比方RGB三通道)卷積過程