在tensorflow的tf.nn.max_pool
中,“SAME”和“VALID”填充有什么区别?
我认为,“VALID”表示在进行最大池化时,边缘外部不会进行零填充。
根据用于深度学习的卷积算术指南,它说池操作中不会进行填充,即只需使用tensorflow的“VALID”。 但是,在tensorflow的最大池化中,“SAME”填充是什么意思呢?
在tensorflow的tf.nn.max_pool
中,“SAME”和“VALID”填充有什么区别?
我认为,“VALID”表示在进行最大池化时,边缘外部不会进行零填充。
根据用于深度学习的卷积算术指南,它说池操作中不会进行填充,即只需使用tensorflow的“VALID”。 但是,在tensorflow的最大池化中,“SAME”填充是什么意思呢?
如果您喜欢ASCII艺术:
"VALID"
= 没有填充:
inputs: 1 2 3 4 5 6 7 8 9 10 11 (12 13)
|________________| dropped
|_________________|
"SAME"
意为用零填充:
pad| |pad
inputs: 0 |1 2 3 4 5 6 7 8 9 10 11 12 13|0 0
|________________|
|_________________|
|________________|
在这个例子中:
注意:
"VALID"
只会丢弃最右边的列(或最下面的行)。"SAME"
会尝试左右均匀填充,但如果要添加的列数是奇数,则会将额外的一列添加到右边,就像这个例子中一样(垂直方向上也适用类似的逻辑:底部可能有多出一行零填充)。编辑:
关于名称:
"SAME"
填充会使得层的输出具有与其输入相同的空间维度。"VALID"
填充时,不存在“捏造”的填充输入。该层只使用有效的输入数据。当stride
等于1时(在卷积中更为常见),我们可以思考以下区别:
"SAME"
: 输出尺寸与输入尺寸相同。这需要过滤窗口在输入映射外滑动,因此需要填充。"VALID"
: 过滤窗口保持在输入映射内的有效位置,因此输出尺寸会缩小filter_size - 1
。不发生填充。我将举一个例子以使问题更清晰:
x
:输入图像形状为[2, 3],1个通道valid_pad
:最大池化使用2x2内核,步幅2和VALID填充。same_pad
:最大池化使用2x2内核,步幅2和SAME填充(这是经典方法)输出形状为:
valid_pad
:这里没有填充,因此输出形状为[1, 1]same_pad
:在此处,我们对图像进行填充,使其形状为[2, 4](使用-inf
填充),然后应用最大池化,所以输出形状为[1, 2]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')
valid_pad.get_shape() == [1, 1, 1, 1] # valid_pad is [5.]
same_pad.get_shape() == [1, 1, 2, 1] # same_pad is [5., 6.]
TensorFlow卷积示例概述了SAME
和VALID
之间的区别:
For the SAME
padding, the output height and width are computed as:
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
和
For the VALID
padding, the output height and width are computed as:
out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))
作为 YvesgereY 的出色回答的补充,我发现这个可视化非常有帮助:
填充方式 'valid' 是第一种。滤波窗口保持在图像内。
填充方式 'same' 是第三种。输出与输入大小相同。
我在这篇文章中找到了它
可视化制作:vdumoulin@GitHub
填充(Padding)是一种增加输入数据大小的操作。对于一维数据,您只需使用常量附加/前置数组,在二维数据中,您需要在矩阵周围用这些常量进行包围。在n维数据中,您需要使用常量来包围n维超立方体。在大多数情况下,这个常量是零,被称为零填充。
您可以使用任意填充(kernel),但其中一些填充值比其他填充值更常用,它们包括:
k
的核k
的核,此填充等于k - 1
。要在TF中使用任意填充,请使用tf.pad()
简要说明
VALID
:不应用任何填充,即假定所有维度都是有效的,以便输入图像完全被你指定的过滤器和步长所覆盖。
SAME
:对输入进行填充(如果需要),以便输入图像被你指定的过滤器和步长完全覆盖。对于步长为1,这将确保输出图像大小与输入相同。
注
NO_PADDING
而不是VALID
。AUTO_PADDING
而不是SAME
。SAME
(即自动填充模式)中,Tensorflow将尝试在左右两侧平均分配填充。VALID
(即无填充模式)中,如果你的过滤器和步幅不能完全覆盖输入图像,则Tensorflow将丢弃右边和/或底部的单元格。我从官方 TensorFlow 文档中引用了这个答案 https://www.tensorflow.org/api_guides/python/nn#Convolution 对于“SAME”填充,输出的高度和宽度计算如下:
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
并且顶部和左侧的填充是根据以下计算得出的:
pad_along_height = max((out_height - 1) * strides[1] +
filter_height - in_height, 0)
pad_along_width = max((out_width - 1) * strides[2] +
filter_width - in_width, 0)
pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left
对于 'VALID' 填充,输出的高度和宽度计算如下:
out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))
并且填充值始终为零。
填充有三个选择:valid(无填充),same(或half),full。您可以在这里找到(Theano的)解释: http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html
有效的填充不涉及零填充,因此仅覆盖有效输入,不包括人为生成的零。如果步长s=1,则输出长度为(输入长度)-(k-1))对于内核大小k。
Same填充使得输出尺寸与输入尺寸相同,当s=1时。如果s=1,则填充的零数为(k-1)。
全填充意味着核在整个输入上运行,因此在末尾,核可能会遇到唯一的一个输入和其他零。如果s=1,则填充的零数为2(k-1)。 如果s=1,则输出长度为(输入长度)+(k-1)。
因此,填充数量为:(valid)≤(same)≤(full)