Caffe的卷積原理

2021-07-24 02:43:09 字數 1833 閱讀 5761

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來完成矩陣的變形和還原操作)

舉個例子(方便理解):

假設有兩個卷積核為

輸入影象矩陣為

故n=[(3+2*0-2)/1+1]*[ (3+2*0-2)/1+1]=2*2=4

a矩陣(m*k)為

=c中的在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)

另外大家也可以參考知乎上賈揚清大神的回答,幫助理解

(對於他給出的ppt上的c表示影象通道個數,如果是rgb影象則通道數為3,對應於caffe**中的變數為src/caffe/layers/base_conv_layer.cpp中

函式forward_gpu_gemm中的group_)

Caffe中卷積運算的原理與實現

caffe中卷積運算設計的很巧妙,今天就來討論一下caffe中卷積運算的原理,最後會給出乙個自己的實現版本,便於初學者理解。俗話說,一圖勝千言,首先先給出原理示意圖,為了方便理解,這裡以二維核為例 滑動視窗在影象中每滑動乙個地方,將影象中該滑動視窗影象展開為一列,所有列組成圖中的滑動視窗矩陣,這裡假...

caffe中的卷積

如上,將三維的操作轉換到二維上面去做,然後呼叫gemm庫進行矩陣間的運算得到最後結果。兩個矩陣相乘,需要中間的那個維度相同,這個相同的維度就是c k k,其中c是feature map的維度,k為卷積核的邊長。按照卷積核在feature map上面滑窗的順序將其展開成二維的。在三維上面看,就是卷積核...

caffe學習 卷積計算

在caffe中如何計算卷積的?caffe中,卷積網路的前向傳播過程需要計算類似w x b 這樣的連線,forward cpu gemm 函式用weight矩陣和輸入的bottom相乘,然後對bias進行處理,bias程式會根據情況決定是否對bias進行scale 放大 縮小 另外可以參考知乎問題 在...