全局平均池化

卷积神经网络可以解决回归跟分类问题,但是常见的卷积神经网络到最后都要通过全连接层实现分类,这个其实会导致很多时候神经元数目跟计算量在全连接层暴增,特别对一些回归要求比较高的网络往往会带来一些后遗症。所以陆陆续续有人提出了不同全连接层解决方案,最常见的两个就是把最后卷积层flatten改为全局最大/均值池化,对比一下这两种方式,图示如下:

pytorch 均值池化 pytorch全局平均池化_深度学习


可以看到全局池化会根据需要产生神经元,神经元个数可控,可调。而flatten方式就是一个硬链接,无法在flatten的时候调整链接数目。全局均值池化输出最常见的做法是把每个通道feature map输出一个神经元(均值结果输出),图示如下:

pytorch 均值池化 pytorch全局平均池化_python_02


全局最大池化图示如下,它是取每个feature map的最大值:

pytorch 均值池化 pytorch全局平均池化_池化_03


全局均值池化跟全局最大池化的输入一般为NxCxHxW,输出为NxCx1x1但是实际上有时候我们还会有另外一个需求,就是全局深度池化,它的输出是Nx1xHxW。这个方式的池化通常会先把数据转换为NxH*WxC的方式,然后使用一维度最大/均值池化在C上完成,最后在转换为Nx1xHxW即可。了解常见几种全局池化方式之后,下面就来一起看看Pytorch中支持的相关函数。

Pytorch全局池化代码演示

  • 全局最大池化
torch.nn.AdaptiveMaxPool2d(output_size, return_indices=False)
  • 全局平均池化
torch.nn.AdaptiveAvgPool2d(output_size)

其中output_size表示输出HxW正常设为HxW=1x1=(1, 1)。代码演示如下:

## 输入为N x C x H x W=1 x 8 x 4 x 4
# 全局均值池化
 avg_pooling = torch.nn.AdaptiveAvgPool2d((1,1))
 B, C, H, W = input.size()
 output = avg_pooling(input).view(B, -1)
 print("全局均值池化:", output.size())
 print(output, "\n")

 # 全局最大池化
 avg_pooling = torch.nn.AdaptiveMaxPool2d((1, 1))
 B, C, H, W = input.size()
 output = avg_pooling(input).view(B, -1)
 print("全局最大池化:", output.size())
 print(output, "\n")

pytorch 均值池化 pytorch全局平均池化_python_04

  • 全局深度池化: 将特征图维度改成任意维度,且宽高都为1
class DeepWise_Pool(torch.nn.MaxPool1d):
     def __init__(self, channels, isize):
         super(DeepWise_Pool, self).__init__(channels)
         self.kernel_size = channels
         self.stride = isize

     def forward(self, input):
         n, c, w, h = input.size()
         input = input.view(n,c,w*h).permute(0,2,1)
         pooled =  torch.nn.functional.max_pool1d(input, self.kernel_size, self.stride,
                         self.padding, self.dilation, self.ceil_mode,
                         self.return_indices)
         _, _, c = pooled.size()
         pooled = pooled.permute(0,2,1)
         return pooled.view(n,c,w,h).view(w, h)


 input = torch.randn(1, 8, 4, 4)
 print("input data:/n", input)
 print("input data:", input.size())
 B, C, W, H = input.size()
 dw_max_pool = DeepWise_Pool(C, W*H)
 output = dw_max_pool(input)
 print("全局深度池化:", output.view(-1, 16).size())
 print(output, "\n")

pytorch 均值池化 pytorch全局平均池化_深度学习_05

全局池化优点:

CNN在图像分类中,把卷积层作为特征提取,FC层+softmax作为回归分类,缺点就是FC层神经元太多容易过拟合,一般用dropout提高过拟合。但还是避免不了参数量多,速度慢的缺陷。可以用GAP方式来避免FC层的处理,直接通过全局池化+softmax进行分类,参数量低。此外还有一个优点:全局池化还部分保留输入图像的空间结构信息!