caffe卷积原理
作为cnn中最重要的卷积,最简单的理解就为:
按照一定步长,卷积核与图片点乘求和得到新的值其中,卷积主要的参数有:
stride 步长 stride_w,stride_h
kernel_size kernel_w,kernel_w
dilation 膨胀系数
padding pad_w,pad_h
卷积层:conv_layer.cpp
里面主要有
compute_output_shape() 计算输出blob的大小
Forward_cpu
Backward_cpu
其中Forword_cpu主要用到了forward_cpu_gemm,这个位于base_conv_layer,
forward_cpu_gemm里面使用到了conv_im2col_cpu,caffe_cpu_gemm。
conv_im2col_cpu 是把输入图像变为一个矩阵,这样子做能直接和卷积核组成的矩阵做点乘,得到的矩阵就为 卷积后每一个特征图就为为这矩阵中一个行向量。
查看cov_im2col_cpu;
根据条件满足与否,分为二维卷积以及n维卷积我们先以im2col_cpu为入手:
主要参数为:
1.data
2.conv_channels 卷积的通道数
3.conv_input_shape.cpu_data()[1] 即image_h 输入图像的height,主要下标
4conv_input_shape.cpu_data()[1] image_w
5.padding_h,padding_w
6.stride_h,stride_w
7.dilation 膨胀系数
推导过程太复杂了,这里有一个单通道的完整的推导过程:lib.csdn.net/article/aiframework/62849
总之,im2col,就是把一个图片上的对应每一个卷积核大小的窗函数里面的元素,变为列向量,随着步长的移动,得到不同的列向量,合并起来得到一个矩阵,也就是col_buff
那caffe中是怎么样计算卷积的:
我们先从单通道入手,用一个单通道卷积核去卷积一个单通道图像:
在不考虑膨胀系数的情况下,N=((image_h+2*pad_h-kenrel_h)/stride_h+1)*((image_w+2*pad_w-kenrel_w)/stride_w+1),其实就是计算经卷积后输出的图像的长与宽,再相乘,得到feature map的大小。
那当是多通道图片(比如说最开始的三通道,以及经过一层卷积后的拥有很多通道的特征图)的情况是什么样的?
c通道的情况下面以一个实际的例子:
这就是caffe卷积的原理。
caffe_gpu_gemm(CblasNoTrans,CblasTrans,M,N,K(Dtype)1,top_diff,bottom_data,(Dtype)1,weights_diff)
voidcaffe_gpu_gemm(constCBLAS_TRANSPOSETransA,constCBLAS_TRANSPOSETransB,const intM,const intN,const intK,constDtypealpha,constDtype* A,constDtype*B,constDtypebeta,
Dtype* C);
caffe_gpu_gemm(CblasTrans,CblasNoTrans,kernel_dim_,
conv_out_spatial_dim_,conv_out_channels_/group_,
(Dtype)1.,weights +weight_offset_* g,output +output_offset_* g,
(Dtype)0.,col_buff +col_offset_* g);