FCN里面全部都是卷积层(pooling也看成卷积),卷积层不关心input的大小,inputsize和outputsize之间存在线性关系。FCN中经过CNN提取特征和pooling层下采样得到的特征大小与原图大小不一致,但是在分割中,要求输入多大,输出就要多大,所以FCN网络中用到了反卷积和上采样到原图大小,然后做像素级的分类。其中反卷积和deonvolution layer过程和full卷积过程如下:
输入:2x2, 卷积核:4x4, 滑动步长:3, 输出:7x7,即输入为2x2的图片经过4x4的卷积核进行步长为3的反卷积的过程
- 输入图片每个像素进行一次full卷积,根据full卷积大小计算可以知道每个像素的卷积后大小为 1+4-1=4, 即4x4大小的特征图,输入有4个像素所以4个4x4的特征图
- 将4个特征图进行步长为3的fusion(即相加); 例如红色的特征图仍然是在原来输入位置(左上角),绿色还是在原来的位置(右上角),步长为3是指每隔3个像素进行fusion,重叠部分进行相加,即输出的第1行第4列是由红色特阵图的第一行第四列与绿色特征图的第一行第一列相加得到,其他如此类推。
-
可以看出翻卷积的大小是由卷积核大小与滑动步长决定, in是输入大小, k是卷积核大小, s是滑动步长, out是输出大小
得到 output_size = (input_size - 1) * stride + kernel_size - 2 * pad
上图过程就是, (2 - 1) * 3 + 4 = 7
假设图片输入为n×n大小,第一个卷积层输出map就为conv1_out.size=(n-kernelsize)/stride + 1, 记做conv1_out.size = f(n), 依次类推,conv5_out.size = f(conv5_in.size) = f(... f(n)), 反卷积是要使n = f‘(conv5_out.size)成立,要确定f’,就需要设置deconvolution层的kernelsize,stride,padding,计算方法如下:
layer {
name: "upsample",
type: "Deconvolution"
bottom: "{{bottom_name}}"
top: "{{top_name}}"
convolution_param {
num_output: {{C}} group: {{C}}
pad: {{ceil((factor - 1) / 2.)}}
kernel_size: {{2 * factor - factor % 2}}
stride: {{factor}}
weight_filler: { type: "bilinear" }
bias_term: false
}
param { lr_mult: 0 decay_mult: 0 }
}
其中factor是指反卷积之前的所有卷积pooling层的累积采样步长,卷积层使feature map变小,是因为stride,卷积操作造成的影响一般通过padding来消除,因此,累积采样步长factor就等于反卷积之前所有层的stride的乘积。
参考文章:https://blog.csdn.net/gyh_420/article/details/78570415
https://blog.csdn.net/haoji007/article/details/78445298