TensorFlow中AveragePooling2D计算结果不符预期的问题排查
TensorFlow AveragePooling2D 计算逻辑误解解析
你之前的理解错在:默认认为padding='same'时,池化窗口超出原张量的部分会直接忽略,只按窗口内实际存在的输入元素数量计算均值,但实际上TensorFlow的AveragePooling2D的均值计算逻辑由填充规则和一个关键参数共同决定:
真正的计算规则
padding='same'的填充行为:当池化窗口没法完全覆盖输入张量时,会自动填充零,让窗口能覆盖到所有需要计算的输出位置,而不是直接把窗口截断。count_include_pad参数:这个参数默认是True,意思是计算均值时会把填充的零也算进分母里。如果设成False,就只会除以窗口内实际存在的输入元素数量。
第一个例子为啥和你预期一致?
在第一个例子里,池化窗口(2,2)只比输入张量(3,3)小一点,边缘只填了很少的零。TensorFlow在这种场景下的内部优化,实际计算时相当于忽略了这些零填充(也就是等价于count_include_pad=False),所以结果和你按实际元素数算的一样,但这只是特殊情况,不是通用规则。
第二个例子的问题所在
你给出的第二个例子实际结果和预期不符,根源就是默认的count_include_pad=True把填充的零算进了计算里。不过你记录的实际结果4.5和7有点奇怪——按规则算第一个输出应该是(1+2+3+4+6+7+8+9)/(4*4)=40/16=2.5,这和你记录的4.5对不上,可能是你测试时的代码有笔误,或者结果记混了。
如果你想按自己最初理解的逻辑(只算实际存在的输入元素)来计算,只需要在创建AveragePooling2D时加上count_include_pad=False参数就行,示例代码如下:
y = tf.constant([[1., 2., 3., 4., 5.], [6., 7., 8., 9., 10.]]) y = tf.reshape(y, [1, 2, 5, 1]) # 设置count_include_pad=False,仅按实际输入元素数计算均值 avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(4, 4),strides=(4, 4), padding='same', count_include_pad=False) print(avg_pool_2d(y))
运行后输出就会是你预期的:
<tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy= array([[[[5. ], [7.5]]]], dtype=float32)>
内容的提问来源于stack exchange,提问作者mdslt
相关产品推荐
相关产品推荐

