caffe卷積輸入通道如何到輸出通道

卷積過程好像是對 一個通道的圖像進行卷積, 比如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_)

下面看這個就簡單多了, im2col.cpp 的代碼也好理解了

發佈了7 篇原創文章 · 獲贊 35 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章