kar*_*TUM 265 python deep-learning tensorflow
什么是"相同"和"有效"填充之间的区别tf.nn.max_pool的tensorflow?
在我看来,'VALID'意味着当我们做最大池时,边缘外没有零填充.
根据深度学习的卷积算法指南,它表示池操作符中没有填充,即只使用'VALID' tensorflow.但是什么是最大池的"相同"填充tensorflow?
Min*_*ark 544
如果你喜欢ascii art:
"VALID" =没有填充:
inputs: 1 2 3 4 5 6 7 8 9 10 11 (12 13)
|________________| dropped
|_________________|
Run Code Online (Sandbox Code Playgroud)"SAME" =零填充:
pad| |pad
inputs: 0 |1 2 3 4 5 6 7 8 9 10 11 12 13|0 0
|________________|
|_________________|
|________________|
Run Code Online (Sandbox Code Playgroud)在这个例子中:
笔记:
"VALID" 只会丢掉最右边的列(或最底部的行)."SAME" 尝试向左和向右均匀填充,但如果要添加的列数是奇数,它将向右添加额外的列,如本示例中的情况(相同的逻辑垂直应用:可能有一个额外的行在底部的零).Oli*_*rot 144
我举一个例子来说明一点:
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.]
Run Code Online (Sandbox Code Playgroud)
Yve*_*reY 138
当stride为1时(更常见的是卷积而不是合并),我们可以想到以下区别:
"SAME":输出大小与输入大小相同.这需要过滤器窗口在输入映射外滑动,因此需要填充."VALID":过滤器窗口保持在输入映射内的有效位置,因此输出大小缩小filter_size - 1.没有填充.Roy*_*eIX 85
所述TensorFlow卷积示例给出关于之间的差的概述SAME和VALID:
对于SAME填充,输出高度和宽度计算如下:
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
Run Code Online (Sandbox Code Playgroud)和
对于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]))
Run Code Online (Sandbox Code Playgroud)zmx*_*zmx 54
补充 YvesgereY 的好答案,我发现这个可视化非常有帮助:
填充“有效”是第一个数字。过滤器窗口保留在图像内。
填充“相同”是第三个数字。输出大小相同。
在这篇文章中找到了
可视化学分:vdumoulin@GitHub
Sal*_*ali 44
填充是一种增加输入数据大小的操作.在一维数据的情况下,您只需在数组中附加/前置一个常数,在二维模拟环绕矩阵中使用这些常数.在n-dim中,您可以使用常量围绕n-dim超立方体.在大多数情况下,此常量为零,称为零填充.
您可以为内核使用任意填充,但某些填充值的使用频率高于其他填充值:
k 
k,此填充等于k - 1.要在TF中使用任意填充,您可以使用 tf.pad()
Shi*_*hah 28
快速解释
VALID:不要应用任何填充,即假设所有尺寸都有效,以便输入图像完全被过滤器覆盖并按指定步幅.
SAME:将填充应用于输入(如果需要),以便输入图像被过滤器完全覆盖并按指定步幅.对于步幅1,这将确保输出图像大小与输入相同.
笔记
NO_PADDING.AUTO_PADDING.SAME(即自动填充模式)中,Tensorflow将尝试在左右两侧均匀分布填充.VALID(即无填充模式)中,如果过滤器和步幅未完全覆盖输入图像,则Tensorflow将向右和/或底部单元格下降.Vai*_*xit 14
我从官方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]))
Run Code Online (Sandbox Code Playgroud)
并且顶部和左侧的填充计算如下:
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
Run Code Online (Sandbox Code Playgroud)
对于'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]))
Run Code Online (Sandbox Code Playgroud)
并且填充值始终为零.
Cha*_*rld 12
填充有三种选择:有效(无填充),相同(或一半),填充.你可以在这里找到解释(在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)).
因此,填充数量:(有效)<=(相同)<=(完整)
总而言之,“有效”填充意味着没有填充。卷积层的输出大小取决于输入大小和内核大小。
相反,“相同”填充意味着使用填充。当stride设置为1时,卷积层的输出大小通过在计算卷积时在输入数据周围附加一定数量的'0-border'来保持为输入大小。
希望这个直观的描述有帮助。
基于此处的解释并跟进Tristan的答案,我通常使用这些快速功能进行健全性检查.
# a function to help us stay clean
def getPaddings(pad_along_height,pad_along_width):
# if even.. easy..
if pad_along_height%2 == 0:
pad_top = pad_along_height / 2
pad_bottom = pad_top
# if odd
else:
pad_top = np.floor( pad_along_height / 2 )
pad_bottom = np.floor( pad_along_height / 2 ) +1
# check if width padding is odd or even
# if even.. easy..
if pad_along_width%2 == 0:
pad_left = pad_along_width / 2
pad_right= pad_left
# if odd
else:
pad_left = np.floor( pad_along_width / 2 )
pad_right = np.floor( pad_along_width / 2 ) +1
#
return pad_top,pad_bottom,pad_left,pad_right
# strides [image index, y, x, depth]
# padding 'SAME' or 'VALID'
# bottom and right sides always get the one additional padded pixel (if padding is odd)
def getOutputDim (inputWidth,inputHeight,filterWidth,filterHeight,strides,padding):
if padding == 'SAME':
out_height = np.ceil(float(inputHeight) / float(strides[1]))
out_width = np.ceil(float(inputWidth) / float(strides[2]))
#
pad_along_height = ((out_height - 1) * strides[1] + filterHeight - inputHeight)
pad_along_width = ((out_width - 1) * strides[2] + filterWidth - inputWidth)
#
# now get padding
pad_top,pad_bottom,pad_left,pad_right = getPaddings(pad_along_height,pad_along_width)
#
print 'output height', out_height
print 'output width' , out_width
print 'total pad along height' , pad_along_height
print 'total pad along width' , pad_along_width
print 'pad at top' , pad_top
print 'pad at bottom' ,pad_bottom
print 'pad at left' , pad_left
print 'pad at right' ,pad_right
elif padding == 'VALID':
out_height = np.ceil(float(inputHeight - filterHeight + 1) / float(strides[1]))
out_width = np.ceil(float(inputWidth - filterWidth + 1) / float(strides[2]))
#
print 'output height', out_height
print 'output width' , out_width
print 'no padding'
# use like so
getOutputDim (80,80,4,4,[1,1,1,1],'SAME')
Run Code Online (Sandbox Code Playgroud)
有效填充:这是零填充。希望没有混乱。
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)
Run Code Online (Sandbox Code Playgroud)
相同的 填充:首先要理解这有点棘手,因为我们必须分别考虑两个条件,如官方文档中所述。
让我们输入为 ,输出为
,填充为
,跨步为
和内核大小为
(仅考虑一个维度)
案例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)
Run Code Online (Sandbox Code Playgroud)
x的维数为(3,4)。然后,如果采取水平方向(3):
如果采用垂直方向(4):
希望这将有助于了解SAME填充在TF中的实际作用。
小智 5
启用/禁用填充。确定输入的有效大小。
VALID:没有填充。卷积运算等操作仅在“有效”的位置执行,即不太靠近张量的边界。
使用3x3的内核和10x10的图像,您将在边界内的8x8区域执行卷积。
SAME:提供填充。每当您的操作引用邻域(无论大小)时,当该邻域扩展到原始张量之外时,都会提供零值,以使该操作也可以处理边界值。
使用3x3的内核和10x10的图像,您将在整个10x10区域上进行卷积。
| 归档时间: |
|
| 查看次数: |
199686 次 |
| 最近记录: |