当前位置: 首页>>技术问答>>正文


TensorFlow的tf.nn.max_pool中'SAME'和'VALID'填充有什么区别?

qingchuanTR 技术问答 , , , 去评论

tensorflowtf.nn.max_pool中'SAME'和'VALID'填充有什么区别?

在我看来,'VALID'意味着做最大池时,边外没有零填充。

根据A guide to convolution arithmetic for deep learning,它表示池化操作符中没有填充,即只使用tensorflow的'VALID'。但是什么是tensorflow中最大池的'SAME'填充?

最佳解决方案

我举一个例子来说明一点:

  • x:shape[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.]

次佳解决方案

如果你喜欢ascii art:

  • "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
                   |________________|
                                  |_________________|
                                                 |________________|
    

在这个例子中:

  • 输入宽度= 13

  • 过滤宽度= 6

  • 步幅= 5

注意:

  • "VALID"只丢弃最右边的列(或最底部的行)。

  • "SAME"尝试向左和向右均匀填充,但如果要添加的列数是奇数,它将向右添加额外的列,如本示例中的情况(相同的逻辑垂直应用:可能有一个额外的底部的一排零)。

第三种解决方案

TensorFlow Convolution示例概述了SAMEVALID之间的差异:

  • 对于SAME填充,输出高度和宽度计算如下:

out_height = ceil(float(in_height)/float(strides [1]))

out_width = ceil(float(in_width)/float(strides [2]))

  • 对于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]))

第四种方案

stride为1时(更常见的是卷积而不是合并),我们可以想到以下区别:

  • "SAME":输出大小与输入大小相同。这需要过滤器窗口在输入映射外滑动,因此需要填充。

  • "VALID":过滤器窗口保持在输入映射内的有效位置,因此输出大小会缩小filter_size - 1。没有填充。

第五种方案

填充是一种增加输入数据大小的操作。在一维数据的情况下,您只需在数组中附加/前置一个常数,使用这些常数在2维度环绕矩阵中。在n-dim中,您可以使用常量包围n-dim超立方体。在大多数情况下,此常数为零,称为zero-padding。

以下是zero-padding与p=1应用于2-d张量的示例:

python,tensorflow,deep-learning


您可以为内核使用任意填充,但某些填充值的使用频率高于其他填充值:

  • 有效填充。最简单的情况,意味着根本没有填充。只需保留您的数据即可。

  • 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]))

并且填充值始终为零。

max pooling

参考资料

本文由《纯净的天空》出品。文章地址: https://vimsky.com/article/3881.html,未经允许,请勿转载。