在tf.nn中“SAME”和“VALID”填充之间的区别是什么?tensorflow的Max_pool ?

在我看来,'VALID'意味着当我们做max pool时,边缘外不会有零填充。

根据深度学习卷积算法指南,它说池操作符中不会有填充,即只使用tensorflow的“VALID”。 但什么是'SAME'填充的最大池张量流量?


当前回答

当stride为1时(卷积比池化更典型),我们可以想到以下区别:

“SAME”:输出大小与输入大小相同。这就要求滤镜窗口要在输入贴图外滑动,因此需要垫片。 "VALID":过滤器窗口保持在输入映射中的有效位置,因此输出大小缩小为filter_size - 1。没有填充。

其他回答

为了补充YvesgereY的回答,我发现这个可视化非常有用:

填充'valid'是第一个数字。滤镜窗口停留在图像内部。

填充'same'是第三个数字。输出是相同的大小。


在这篇文章里找到的

可视化致谢:vdumoulin@GitHub

有效填充:这是零填充。希望没有混淆。

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
print (valid_pad.get_shape()) # output-->(1, 2, 1, 1)

相同填充:首先,这有点难以理解,因为我们必须分别考虑官方文档中提到的两个条件。

假设输入为,输出为,填充为,步幅为,内核大小为(只考虑单个维度)

案例01::

案例02::

被计算为可用于填充的最小值。由于的值是已知的,可以用这个公式求出值。

让我们来做这个例子:

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
print (same_pad.get_shape()) # --> output (1, 2, 2, 1)

这里x的维数是(3,4)那么如果取水平方向(3):

若取垂直方向(4):

希望这将有助于理解实际上相同填充是如何在TF中工作的。

有效填充是没有填充。 相同的填充在某种程度上是输出与输入大小相同的填充。

我举个例子来说明:

X:输入形状[2,3]的图像,1通道 valid_pad: max pool with 2x2 kernel, stride 2和VALID padding。 same_pad: max pool with 2x2 kernel, stride 2和SAME padding(这是经典的方法)

输出形状为:

Valid_pad:这里没有填充,所以输出形状是[1,1] Same_pad:在这里,我们将图像填充到形状[2,4](使用-inf,然后应用Max pool),因此输出形状是[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文档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]))

填充值总是0。