詳解CNN中的stride 和 padding 到底是怎麼計算的
平時不注意的細節,別人一問的時候就會很懵逼,所以認真對待每一個引數。
先看一下 tensorflow中自帶的卷積操作是什麼樣子的呢?
https://tensorflow.google.cn/api_docs/python/tf/nn/conv2d
tf.nn.conv2d(
input,
filter,
strides,
padding,
use_cudnn_on_gpu=True,
data_format='NHWC',
dilations=[1, 1, 1, 1],
name=None
)
其中data_format這個引數我們很少了解,其實它是固定你input的格式,NHWC對應著你的輸入資料的維度時[batch_size,Heigth,Width,Channel],NCHW對應[batch_size,Channel,Heigth,Width]。
其實strides裡面的引數和這個data_format是一一對應的,什麼意思呢?就是說,如果我們採用NHWC的方式和strides=[a,b,c,d]的情況下,計算卷積核移動過程是怎麼樣的呢?它會在batch的維度上按照 step=a的大小進行移動計算,同理,分別在HWC的維度上移動的step為b c d。因為我們需要對每一個batch和channel都需要進行計算,所以這裡 a,d 的值為1。b c的值可以根據實際情況進行改變,他們的值直接關係到輸出的feature map 的維度。
在來看一下在padding 等於 same 和valid 兩個引數下的計算方式。
可以參考:https://www.jianshu.com/p/05c4f1621c7e
假設,我們輸入的影象的大小為:W*H
kernel size的大小為: k_h*k_w
在 H 方向的stride為 h, 在W方向 的stride為 w
來求我們新輸出的特徵圖的大小,n_h 和 n_w
如果是 valid 模式,他是隻在原圖進行修改
則 n_h =( H-k_h)/ h 向上取整後加 1 ;
n_w = (W-k_w)/ h 向上取整後加 1 ;
如果是 SAME 模式,他會在填充的時候自動補0(在必要的時候)。
那麼什麼是必要的時候呢?它是先根據公式 n_h = H/h 向上取整
在 H 方向 pad_need_H = (n_h -1 ) * h +K_h - H
在矩陣每一行的上方需要新增的畫素數為:
pad_need_H/2 取整
在矩陣每一行的下方需要新增的畫素數為
pad_need_H - pad_need_H/2
同理可得在W方向,
原始碼如下。
例如輸入的是feature map 是4*4 ,kernel size 為1*1,strides 1,1
則它需要補充後的圖為
這裡畫斜槓的為填充的0
加入輸入的feature map 為 2*5 kernel size 為2*2 , strides 為【1,2,1,1】
則它需要填充後的圖為
最後一列為需要填充的0值,最後輸出的feature map 為1*5
歡迎指正和補充。