您的位置:首页 > 其它

TensorFlow中CNN的两种padding方式“SAME”和“VALID”

2017-10-10 14:31 507 查看
转载请标明出处: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操作),没什么问题,如下:
123
456
接下来就是“SAME”和“VALID”的区别所在,由于步长为2,当向右滑动两步之后“VALID”发现余下的窗口不到2x2所以就把第三列直接去了,而“SAME”并不会把多出的一列丢弃,但是只有一列了不够2x2怎么办?填充!
1230
4560
如上图所示,“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

dilation_rate为一个可选的参数,默认为1,这里我们可以先不管它。 

整理一下,对于“VALID”,输出的形状计算如下: 

new_height=new_width=⌈(W–F+1)S⌉

对于“SAME”,输出的形状计算如下: 

new_height=new_width=⌈WS⌉

其中,W为输入的size,F为filter为size,S为步长,⌈⌉为向上取整符号。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息