在tensorflow 的tf.nn.max_pool 中’SAME’和’VALID’填充有什么区别?
在我看来,’VALID’意味着做最大池时,边外没有零填充。
根据A guide to convolution arithmetic for deep learning,它表示池化操作符中没有填充,即只使用tensorflow 的’VALID’。但是什么是tensorflow 中最大池的’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.]
次佳解决方案
如果你喜欢ascii art:
在这个例子中:
注意:
第三种解决方案
TensorFlow Convolution示例概述了SAME 和VALID 之间的差异:
out_height = ceil(float(in_height)/float(strides [1]))
out_width = ceil(float(in_width)/float(strides [2]))
和
out_height = ceil(float(in_height – filter_height + 1)/float(strides [1]))
out_width = ceil(float(in_width – filter_width + 1)/float(strides [2]))
第四种方案
当stride 为1时(更常见的是卷积而不是合并),我们可以想到以下区别:
第五种方案
填充是一种增加输入数据大小的操作。在一维数据的情况下,您只需在数组中附加/前置一个常数,使用这些常数在2维度环绕矩阵中。在n-dim中,您可以使用常量包围n-dim超立方体。在大多数情况下,此常数为零,称为zero-padding。
以下是zero-padding与p=1 应用于2-d张量的示例:
您可以为内核使用任意填充,但某些填充值的使用频率高于其他填充值:
-
有效填充。最简单的情况,意味着根本没有填充。只需保留您的数据即可。
-
SAME填充有时称为HALF填充。它被称为SAME,因为对于stride = 1的卷积(或用于汇集),它应该产生与输入相同大小的输出。它被称为HALF,因为对于大小为k 的内核
-
FULL填充是最大填充,不会导致仅填充元素的卷积。对于大小为k 的内核,此填充等于k - 1 。
要在TF中使用任意填充,可以使用tf.pad()
第六种方案
填充有三种选择:有效(无填充),相同(或一半),填充。你可以在这里找到解释(在Theano):http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html
有效填充不涉及零填充,因此它仅覆盖有效输入,不包括人工生成的零。如果步幅s = 1,则输出的长度是((输入的长度) – (k-1))对于内核大小k。
当s = 1时,相同的填充使输出的大小与输入的大小相同。如果s = 1,则填充的零的数量是(k-1)。
完整填充意味着内核在整个输入上运行,因此在最后,内核可能只满足一个输入和零。如果s = 1,填充的零的数量是2(k-1)。如果s = 1,则输出长度为((输入长度)+(k-1))。
因此,填充数量:(有效)< =(相同)< =(完整)
第七种方案
快速解释
VALID :不要应用任何填充,即假设所有尺寸都有效,以便输入图像完全被过滤器覆盖并按指定步幅覆盖。
SAME :将填充应用于输入(如果需要),以便输入图像被过滤器完全覆盖并按指定步幅。对于步幅1,这将确保输出图像大小与输入相同。
注意
-
这同样适用于coov图层和最大池化图层
-
术语”valid”有点用词不当,因为如果丢弃部分图像,事情就不会变成”invalid”。有时你甚至可能想要那样。这可能应该被称为”NO_PADDING”。
-
术语”same”也是用词不当,因为当输出维数与输入维度相同时,它只对1的步幅有意义。例如,对于2的步幅,输出尺寸将是一半。这可能应该被称为”AUTO_PADDING”。
-
在SAME (即auto-pad模式)中,Tensorflow将尝试在左右两侧均匀分布填充。
-
在VALID 中(即无填充模式),如果过滤器和步幅未完全覆盖输入图像,则Tensorflow将向右和/或底部单元格下降。
第八种方案
我从官方tensorflow docs 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]))
并且填充值始终为零。
参考资料
- What is the difference between ‘SAME’ and ‘VALID’ padding in tf.nn.max_pool of tensorflow?
|