平均池化CNN中是常用的操作,下面介绍一下tensorflow中keras的GlobalAveragePooling2D和AveragePooling2D的返回的tensor的维度的区别。
GlobalAveragePooling2D是平均池化的一个特例,它不需要指定pool_size和strides等参数,操作的实质是将输入特征图的每一个通道求平均得到一个数值。它的输入和输出维度为:
Input shape:
- If `data_format='channels_last'`:
4D tensor with shape:
`(batch_size, rows, cols, channels)`
- If `data_format='channels_first'`:
4D tensor with shape:
`(batch_size, channels, rows, cols)`
Output shape:
2D tensor with shape:
`(batch_size, channels)`
可以看到GlobalAveragePooling2D最后返回的tensor是[batch_size, channels]两个维度的。
AveragePooling2D的输入和输出维度为:
Input shape:
- If `data_format='channels_last'`:
4D tensor with shape:
`(batch_size, rows, cols, channels)`
- If `data_format='channels_first'`:
4D tensor with shape:
`(batch_size, channels, rows, cols)`
Output shape:
- If `data_format='channels_last'`:
4D tensor with shape:
`(batch_size, pooled_rows, pooled_cols, channels)`
- If `data_format='channels_first'`:
4D tensor with shape:
`(batch_size, channels, pooled_rows, pooled_cols)`
AveragePooling2D最后返回的tensor是 [batch_size, channels, pooled_rows, pooled_cols] 4个维度的。
而我们在使用keras实现PSPNet和Deeplabv3+时,需要在一个并联的分支中实现全局平均池化,然后将池化后的结果与其他结果串联或者相加,这时要求池化后返回的tensor维度为 [batch_size, channels, pooled_rows, pooled_cols] 4个维度的,因此就不能直接使用 GlobalAveragePooling2D 进行池化,这样会得到2维的tensor。
一个解决方案是使用 AveragePooling2D 代替 GlobalAveragePooling2D 进行全局平均池化。
只需要设置 AveragePooling2D 的 pool_size 和 strides 都为输入特征图的尺寸即可。
比如输入的特征图 x 为 [batch, 32, 32, channels],那么进行全局平均池化并返回4维tensor的操作为:
# 在不指定strides时,strides默认与pool_size 一样
x = keras.layers.AveragePooling2D(pool_size = (32, 32))(x)