轉載請標明出處:http://blog.csdn.net/wuzqchom/article/details/74785643
在用tensorflow寫CNN的時候,調用卷積核api的時候,會有填padding方式的參數,找到源碼中的函數定義如下(max pooling也是一樣):
def conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None,
data_format=None, name=None)
源碼中對於padding參數的說明如下:
padding: A
string
from:"SAME", "VALID"
.
The type of padding algorithm to use.
說了padding可以用“SAME”和“VALID”兩種方式,但是對於這兩種方式具體是什麼並沒有多加說明。
這裏用Stack Overflow中的一份代碼來簡單說明一下,代碼如下:
x = tf.constant([[1., 2., 3.],
[4., 5., 6.]])
x = tf.reshape(x, [1, 2, 3, 1]) # give a shape accepted by tf.nn.max_pool
valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
print(valid_pad.get_shape())
print(same_pad.get_shape())
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
最後輸出的結果爲:
(1, 1, 1, 1)
(1, 1, 2, 1)
可以看出“SAME”的填充方式是比“VALID”的填充方式多了一列。
讓我們來看看變量x是一個2x3的矩陣,max pooling窗口爲2x2,兩個維度的strides=2。
第一次由於窗口可以覆蓋(橙色區域做max pool操作),沒什麼問題,如下:
1 | 2 | 3 |
4 | 5 | 6 |
接下來就是“SAME”和“VALID”的區別所在,由於步長爲2,當向右滑動兩步之後“VALID”發現餘下的窗口不到2x2所以就把第三列直接去了,而“SAME”並不會把多出的一列丟棄,但是隻有一列了不夠2x2怎麼辦?填充!
1 | 2 | 3 | 0 |
4 | 5 | 6 | 0 |
如上圖所示,“SAME”會增加第四列以保證可以達到2x2,但爲了不影響原來的圖像像素信息,一般以0來填充。(這裏使用表格的形式展示,markdown不太好控制格式,明白意思就行),這就不難理解不同的padding方式輸出的形狀會有所不同了。
在CNN用在文本中時,一般卷積層設置卷積核的大小爲n×k,其中k爲輸入向量的維度(即[n,k,input_channel_num,output_channel_num]),這時候我們就需要選擇“VALID”填充方式,這時候窗口僅僅是沿着一個維度掃描而不是兩個維度。可以理解爲統計語言模型當中的N-gram。
我們設計網絡結構時需要設置輸入輸出的shape,源碼nn_ops.py中的convolution函數和pool函數給出的計算公式如下:
If padding == "SAME":
output_spatial_shape[i] = ceil(input_spatial_shape[i] / strides[i])
If padding == "VALID":
output_spatial_shape[i] =
ceil((input_spatial_shape[i] -
(spatial_filter_shape[i]-1) * dilation_rate[i])
/ strides[i]).
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
參考:
1.https://blog.csdn.net/wuzqchom/article/details/74785643