前言:在阅读SSD网络的时候,看到conv6层中pad=6,且有个参数dilation: 6。在平时没怎么注意到整个参数,今天对其进行记录。
layer {
name: "fc6"
type: "Convolution"
bottom: "pool5"
top: "fc6"
param {
lr_mult: 1.0
decay_mult: 1.0
}
param {
lr_mult: 2.0
decay_mult: 0.0
}
convolution_param {
num_output: 1024
pad: 6
kernel_size: 3
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0.0
}
dilation: 6
}
}
caffe源码中conv_layer.cpp关于空洞卷积的计算:
const int kernel_extent = dilation_data[i] * (kernel_shape_data[i] - 1) + 1;
caffe源码中caffe.proto关于dilation的定义:
// Factor used to dilate the kernel, (implicitly) zero-filling the resulting
// holes. (Kernel dilation is sometimes referred to by its use in the
// algorithme à trous from Holschneider et al. 1987.)
repeated uint32 dilation = 18; // The dilation; defaults to 1
下面以卷积核3*3为例,膨胀系数为2,那么卷积核膨胀之后,卷积核的单边尺寸就变成了2*(3-1)+1,即卷积核的尺寸变成了5*5。
卷积核膨胀是将卷积核扩张到膨胀尺度约束的尺度中,并将原卷积核没有占用的区域填充零
上图中,卷积核由3*3膨胀到了5*5,从图中可以看到,膨胀后的卷积核中空洞的部分填充了一些0,在caffe源码中具体的膨胀操作是在img2col中实现。
1)下面分析一下膨胀系数与卷积核膨胀的关系,首先回顾卷积核膨胀公式:
膨胀后卷积核尺寸 = 膨胀系数 * (原始卷积核尺寸 - 1) + 1
2)卷积核的膨胀系数等于卷积核高和宽方向的扩张倍数,将上式中1移到等式左侧:
膨胀的卷积核尺寸 - 1 = 膨胀系数 * (原始卷积核尺寸 - 1)
3)原始卷积核在膨胀后,元素间的空洞间隔与膨胀系数的关系:
元素间隔 = 膨胀系数 - 1
例如:上图中膨胀系数为2,那么膨胀后卷积核元素间的空洞间隔为2-1=1.
空洞卷积的作用:
①:使输出变得更稠密。
②:在不增加计算量的情况下,扩大了卷积核视野(卷积核尺寸变大)。