卷積神經網路(Convolutional neural network, CNN):卷積計算中的步伐(stride)和填充(padding)

Tommy Huang
8 min readJun 29, 2018

--

一般看到的卷積介紹,大概就像上圖,圖會因為你的kernel map大小做完卷積後變的更小,實際上卷積怎麼執行可以參考我之前寫的:
卷積神經網路(Convolutional neural network, CNN) — 卷積運算、池化運算

Note: (2019/01/15增加)一般卷積網路過程中,除了Input image不稱為Feature map外,中間產生的圖我們都稱之為Feature map,原因很簡單就是這些中間產生的圖都是為了「描繪出該任務所應該產生對應的特徵資料」,這也呼應Yann LeCun, Yoshua Bengio & Geoffrey Hinton寫的Deep Learning第一句話寫的「Deep learning allows computational models that are composed of multiple processing layers to learn representations of data with multiple levels of abstraction」,深度學習過程就是在學資料的特性,所以中間出來的結果都是特徵資料,在影像因為是2D,所以用Feature map來稱呼。

所以一個卷積計算基本上有幾個部份:

1. 輸入的圖: 假設大小是W × W。
2. Filter (kernel map)大小是 ks × ks
3. Stride: kernel map在移動時的步伐長度 S
4. 輸出的圖大小為 new_height × new_width

上圖的例子
1. 輸入的圖: W × W =10 × 10。
2. Filter (kernel map): ks × ks=3 × 3
3. Stride: S=1
4. 輸出的圖大小為 new_height × new_width = 8 × 8

上圖的範例產生了2個問題
1. 是不是卷積計算後,卷積後的圖是不是就一定只能變小?
2. 卷積計算是不是一次只能移動一格?

所以如果你有玩過deep learning的API,卷積計算部份除了基本的input和filter (kernel map)通常還有兩個參數可以調(strides, padding),這邊舉tensorflow的例子:
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

stridespadding這兩個參數就是在解決上面說的兩個問題。

是不是卷積計算後,卷積後的圖是不是就一定只能變小?

ANS: 用zero padding

這個手法就是看你會消失多少的大小,在輸入的圖部份就給你加上0元素進去,這個手法稱為zero padding,實際作法如下圖。

此刻的卷積計算如下,這樣卷積後的圖就不會變小了。

上圖舉的例子是kernel map是3x3,假設kernel map為5x5,此刻在輸入的圖上下左右行和列都各加2行和2列的0,讓圖變成14x14,就可以了。

卷積計算是不是一次只能移動一格?

ANS: 當然不是,也可以2格3格,但此時卷積後的圖就會變的更小。

在tensorflow,padding那邊給了兩個選項「padding = ‘VALID’」和「padding = ‘SAME’」

padding = ‘VALID’ 等於最一開始敘述的卷積計算,圖根據filter大小和stride大小而變小。

公式如下: new_height = new_width = (W — F + 1) / S (结果向上取整數,假設算出來結果是4.5,取5)

剛剛的例子
filter 3x3, stride=1, 卷積後的大小: (10–3+1)/1=8
filter 3x3, stride=2, 卷積後的大小: (10–3+1)/2=4

padding = ‘SAME’,會用zero-padding的手法,讓輸入的圖不會受到kernel map的大小影響。

new_height = new_width = W / S (结果向上取整數)

剛剛的例子,filter 3x3, stride=2, 卷積後的大小: 10/2=5 (這邊我沒有做這張圖,可以自己想像一下,做法如下所述)
這邊的作法會先補zero-padding的0元素,然後在作stride=2的卷積,所以實際上是最(10+2)*(10+2)的圖做padding = ‘VALID’的事情,(12–3+1)/2=5。

Padding補充說明 (2019/01/15增加此內容)

上面介紹的公式是針對tensorflow內建的function功能(「padding = ‘VALID’」和「padding = ‘SAME’」),並不是一般算卷積後算新的feature map長寬的公式。

一般卷積後算新的feature map長寬的公式如下:

floor(1.1)=1, floor(1.6)=1

這邊跟前面差別在這邊多了一個pad參數。

對應到caffe prototxt卷積的參數會這麼寫,如下(其他模組應該是一樣可以設pad參數)

convolution_param {
num_output: 32
pad: 1
kernel_size: 3
stride: 2
}

這代表卷積層filter數設定為32,filter的kernel size是3,步伐stride是2,pad是1。pad=1,表示圖外圈額外加1圈0,假設pad=2,圖外圈額外加2圈0,以此類推。
所以kernel size是3的時候,你希望卷積後圖的寬高不要變,pad就要設定為1
假設kernel size是5的時候,你希望卷積後圖的寬高不要變,pad就要設定為2
假設kernel size是7的時候,你希望卷積後圖的寬高不要變,pad就要設定為3

Note: 因為一般大多只會用到卷積後,Feature map寬高會依據kernel size縮小一點(「padding = ‘VALID’」)或Feature map寬高不變(「padding = ‘SAME’」),鮮少搞一些特殊的功能,比如1×1卷積還要加pad=1,這樣出來的圖會比原本大一圈,而且這一圈還全為0。
而且一般卷積網路都是希望卷積後圖越來越小(整體MACC計算量才會小),除了segmentation和一些multi-scale object detection等才會用到deconv.或是一些upsample的方法把feature map放大。
Tensorflow是提供簡單的api,你就不需要自己去算pad要設多少,直接下strin即可(如下說明),多方便阿。
padding: A string from: "SAME", "VALID". The type of padding algorithm to use.

--

--

Tommy Huang
Tommy Huang

Written by Tommy Huang

怕老了忘記這些吃飯的知識,開始寫文章記錄機器/深度學習相關內容。Medium現在有打賞功能(每篇文章最後面都有連結),如果覺得寫的文章不錯,也可以Donate給個Tipping吧。黃志勝 Chih-Sheng Huang (Tommy), mail: chih.sheng.huang821@gmail.com

Responses (4)