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