出處:
將尺寸為k×k的卷積核在某個位置對應的feature map區域表示為k×k的一維向量;
將feature map各個通道對應的向量之間,串聯起來;
那麼尺寸k×k的卷積核在某個位置對應的各個通道的feature map,組合起來就是長度為c×k×k的一維向量。
當卷積核對應到新的位置上,又得到新的一維向量。
那麼卷積核對應整張的所有位置,就得到乙個(h×w)×(c×k×k)的矩陣(假設卷積核每次移動的步數為1)。
同樣地,將卷積核也表示為一維向量;
用於輸出乙個特徵圖的卷積核對應乙個c×k×k的一維向量(因為用於輸出同乙個特徵圖的卷積核是共享權值的,所以在整張圖的各個位置進行卷積的都是同乙個卷積核);
假設要輸出co
ut個特徵圖,就需要co
ut個卷積核,那麼所有卷積核對應乙個co
ut×c×k×k的矩陣。
最後,特徵圖對應矩陣乘以卷積核對應矩陣的轉置,得到輸出矩陣co
ut×(h×w),這就是輸出的三維blob(co
ut×h×w)。
用下圖舉個例子,請對號入座。
convolutionlayer 是 baseconvolutionlayer的子類,baseconvolutionlayer 是 layer 的子類。compute_output_shapeconvolutionlayer 除了繼承了相應的成員變數和函式以外,自己的成員函式主要有:compute_output_shape,forward_cpu 和 backward_cpu。
template
void convolutionlayer::compute_output_shape()
forward_cpu
template
void convolutionlayer::forward_cpu(const
vector
*>& bottom,
const
vector
*>& top) //加上bias}}}
forward_cpu_gemm
template
void baseconvolutionlayer::forward_cpu_gemm(const dtype* input,
const dtype* weights, dtype* output, bool skip_im2col)
col_buff = col_buffer_.cpu_data();
} // 使用caffe的cpu_gemm來進行計算
for (int g = 0; g < group_; ++g)
}
forward_cpu_bias
template type>
void baseconvolutionlayertype>::forward_cpu_bias(dtype* output,
const dtype* bias)
backward_cpu
template
void convolutionlayer::backward_cpu(const
vector
*>& top,
const
vector
& propagate_down, const
vector
*>& bottom)
if (this->bias_term_ && this->param_propagate_down_[1])
for (int i = 0; i < top.size(); ++i)
}if (this->param_propagate_down_[0] || propagate_down[i]) //對weight 計算導數(用來更新weight)
if (propagate_down[i]) //對bottom資料計算導數(傳給下一層)}}
}}
本篇部落格主要參考自
《 (caffe)卷積的實現 》
《在 caffe 中如何計算卷積?》
《caffe原始碼(五):conv_layer 分析 》
Caffe中如果高效實現卷積層
卷積層是caffe中比較關鍵的的乙個層,其裡面實現運用了大量技巧,關鍵卷積層的實現可以看看賈清楊是如何吐槽的 按照一般卷積層的實現思路就是用多層迴圈來實現,針對乙個w h的,深度為d,卷積kernel為k k,共有m個濾波,則實現一般如下 for w in 1.w for h in 1.h for ...
caffe原始碼 卷積層
input 3 5 5 c h w pading 1 步長 2 卷積核 2 3 3 3 n c k k output 2 3 3 c h w 如下圖所示 首先需要理解caffe裡面的im2col和col2im 然後 卷積層 其實和 全連線層 差不多了 input 3 4 4 c h w 卷積核 1 ...
caffe中的卷積
如上,將三維的操作轉換到二維上面去做,然後呼叫gemm庫進行矩陣間的運算得到最後結果。兩個矩陣相乘,需要中間的那個維度相同,這個相同的維度就是c k k,其中c是feature map的維度,k為卷積核的邊長。按照卷積核在feature map上面滑窗的順序將其展開成二維的。在三維上面看,就是卷積核...