BaseConvolutionLayer作为卷积操作的类,被ConvolutionLayerDeconvolutionLayer继承。卷积层在计算中总是先把多维图片和多维卷积核都转成二维矩阵,使用矩阵相乘得到最后的数据。BaseConvolutionLayer提供了卷积相关的基本操作。

文件

include/caffe/util/im2col.hpp
src/caffe/util/im2col.cpp
src/caffe/util/im2col.cu
include/caffe/layers/base_conv_layer.hpp
src/caffe/layers/base_conv_layer.cpp

原理

  1. 卷积层可能有多个输入blob且每个blob有多张图片,但做卷积时每次只使用一张图片,产生一张图片,所有图片都使用相同的一组卷积核。对每张图片,输入数据、输出数据都是三维的blob,卷积核数组是四维的blob。其中
    kernel_channel == in_channel/group
    kernel_num == out_channel
    out_h == (in_h+2*pad_h-kernel_h)/stride_h+1
    out_w == (in_w+2*pad_w-kernel_w)/stride_w+1
    
  2. 计算一张图片的卷积时,使用weight矩阵 * im2col矩阵得到最终结果。
    • weight矩阵可以看作一个[kernel_num, kernel_channel*kernel_h*kernel_w]的矩阵,每行是一个完整的三维kernel的一维展开,weight blob中原本的排列方式就满足这种要求。
    • im2col矩阵是由一张in_channel*height*width的图片转成的一个维度为[in_channel*kernel_h*kernel_w, kernel滑动总数]的矩阵。其中每一列是一个原图三维子块的一维展开,大小等于group个kernel的元素数量和。列数是kernel滑动时产生的子块的总数,等于out_h*out_wim2col.hpp/.cpp文件提供了单张图片和im2col矩阵之间的转换。
    • 最终的结果是一个[out_channel, kernel滑动总数]的矩阵,每行看作一个二维feature map的一维展开。
  3. 计算bias时,bias矩阵的维度为[kernel_num, 1],和一个全1的[1, out_h*out_w]矩阵相乘,把结果和输出矩阵做矩阵加。相当于第ifeature map的所有元素都加上bias[i]
  4. group convolution用于模拟Alex Krizhevsky最初的论文中的模型,其他地方没啥用。默认group=1,若group>1,输入输出的数据大小不变,由于kernel_channel = in_channel/group,所以内部weight参数的行数(卷积核数量)不变,列数(卷积核大小)除以group,im2col矩阵行数列数都不变。每张图片需要做group次卷积,每次使用一个group的卷积核和一个group的input channel。weight子矩阵的大小为[kernel_num/group, kernel_channel*kernel_h*kernel_w]im2col子矩阵的大小为[in_channel/group*kernel_h*kernel_w, kernel滑动总数]。每个kernel只会和input的某一组channel做卷积,同一个group的kernel会和相同的这组channel做卷积,所以不同group的weights子矩阵和im2col子矩阵可以分布在不同的GPU上。
  5. dilated convolution用于调整原图中做卷积的子块的元素间隔。当dilation==2时,原图子块是一个元素间间距为2的块。普通卷积所用的连续的[channel, kernel_h, kernel_w]的子块可以看做是dilation==1的实现。通过kernel_h/w计算out_h/w时,需要使用kernel_h_with_dilation = dilation_h * (kernel_h - 1) + 1)

参数

  1. BaseConvolutionLayerConvolutionLayerDeconvolutionLayer都是使用ConvolutionParameter做参数
message LayerParameter {
  optional ConvolutionParameter convolution_param = 106;
}

message ConvolutionParameter {
  optional uint32 num_output = 1;               // 输出map个数
  optional bool bias_term = 2 [default = true]; // 是否包含bias

  // pad,kernel,stride只有一个数字时,认为height和width相等
  repeated uint32 pad = 3;                      // 边缘补齐维度,默认为0
  repeated uint32 kernel_size = 4;              // 卷积核维度,可以只有1个或和图片的维度数相同个
  repeated uint32 stride = 6;                   // 步长维度,默认为1
  repeated uint32 dilation = 18;                // 膨胀卷积(dilated convolution)参数,默认为1

  // 二维卷积时的参数
  optional uint32 pad_h = 9 [default = 0];
  optional uint32 pad_w = 10 [default = 0];
  optional uint32 kernel_h = 11;
  optional uint32 kernel_w = 12;
  optional uint32 stride_h = 13;
  optional uint32 stride_w = 14;

  optional uint32 group = 5 [default = 1];      // group convolution时的组大小

  optional FillerParameter weight_filler = 7;   // 权重weight的填充器
  optional FillerParameter bias_filler = 8;     // 偏置bias的填充器
  enum Engine {
    DEFAULT = 0;
    CAFFE = 1;
    CUDNN = 2;
  }
  optional Engine engine = 15 [default = DEFAULT];

  // channel维度的下标,比如输入是(N, C, D, H, W),axis==1表示以
  // (D, H, W)作输入图片,和(C/group)个通道的卷积核作N次卷积
  optional int32 axis = 16 [default = 1];
  // 是否强制使用普通的N维im2col,目前2维的有特殊实现
  optional bool force_nd_im2col = 17 [default = false];
}

results matching ""

    No results matching ""