Python Tensorflow:tf.nn.avg_pool()与';相同';填充不会平均覆盖填充的像素

Python Tensorflow:tf.nn.avg_pool()与';相同';填充不会平均覆盖填充的像素,python,tensorflow,Python,Tensorflow,我试图理解tf.nn.avg\u pool()。我不知道结果的第一行是怎样的[1.0,1.0,1.0,1.0] img = tf.constant([ [[0,4], [0,4], [0,4], [0,4]], [[1,5], [1,5], [1,5], [1,5]], [[2,6], [2,6], [2,6], [2,6]], [[3,7], [3,7], [3,7], [3,7]] ], dtype=tf.float32) pooling2 = tf.nn.

我试图理解
tf.nn.avg\u pool()
。我不知道结果的第一行是怎样的
[1.0,1.0,1.0,1.0]

img = tf.constant([
    [[0,4], [0,4], [0,4], [0,4]],
    [[1,5], [1,5], [1,5], [1,5]],
    [[2,6], [2,6], [2,6], [2,6]],
    [[3,7], [3,7], [3,7], [3,7]]
], dtype=tf.float32)

pooling2 = tf.nn.avg_pool(img, ksize=[1,4,4,1], strides=[1,1,1,1], padding='SAME')

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    print('pooling2.shape: {}'.format(sess.run(pooling2).shape))
    print('pooling2:\n{}'.format(
        sess.run(pooling2).transpose([0,3,1,2]).reshape([2,4,4])             ))
打印结果为

pooling2.shape: (1, 4, 4, 2)
pooling2:
[[[1.  1.  1.  1. ]
  [1.5 1.5 1.5 1.5]
  [2.  2.  2.  2. ]
  [2.5 2.5 2.5 2.5]]

 [[5.  5.  5.  5. ]
  [5.5 5.5 5.5 5.5]
  [6.  6.  6.  6. ]
  [6.5 6.5 6.5 6.5]]]
似乎它在顶部填充了一行,在左侧填充了一列,在右侧和底部填充了两行和两列,然后将4x4窗口/内核应用于与左上角对齐的填充结果:

_ _ _ _ _ _ _
_ 0 0 0 0 _ _
_ 1 1 1 1 _ _
_ 2 2 2 2 _ _
_ 3 3 3 3 _ _
_ _ _ _ _ _ _
_ _ _ _ _ _ _
放大到左上角

_ _ _ _
_ 0 0 0
_ 1 1 1
_ 2 2 2
为什么它看起来像是重新成形的
池2[0,0,0]
,即
1
,来自

(0+0+0 + 1+1+1 + 2+2+2) / 9,

为什么不
/16

是的,在平均值中不考虑填充的像素。因此,使用<代码> 4x4< /代码>池,在图像中间计算的结果平均超过16个值,但是如果两个边沿填充,则角中的值只能使用代码>9 < /代码>值。

例如,您可以在调用CuDNN时看到它,其中为平均填充选择了选项
CuDNN\u POOLING\u AVERAGE\u COUNT\u EXCLUDE\u PADDING
。CuDNN还建议
CuDNN\u POOLING\u AVERAGE\u COUNT\u INCLUDE\u PADDING
,这将考虑平均值中的填充像素,但tensorflow没有公开此选项

这可能是一种平均池行为不同于(跨步)卷积的方式,特别是对于空间范围较小的层

请注意,这种情况与最大池类似:填充像素被忽略(或等效地,虚拟设置为
-inf
)的值


显然,文档可以更明确地说明这一点

我认为这很重要,但为什么他们没有在文档/他们的网站教程中添加这个…,或者这只是cnn的常识…?非常感谢!谢谢你的时间!你救了我对tensorflow的爱。
import tensorflow as tf

x = -tf.ones((1, 4, 4, 1))
max_pool = tf.nn.max_pool(x, (1, 4, 4, 1), (1, 1, 1, 1), 'SAME')
sess = tf.InteractiveSession()
print(max_pool.eval().squeeze())
# [[-1. -1. -1. -1.]
#  [-1. -1. -1. -1.]
#  [-1. -1. -1. -1.]
#  [-1. -1. -1. -1.]]