SENet:卷积神经网络的通道注意力机制.

SENet是由自动驾驶公司Momenta2017年提出的图像识别结构,是2017 ILSVR竞赛的冠军。它通过对特征通道间的相关性进行建模,引入了通道注意力机制。

SENet所使用的通道注意力模块如图所示,包括Squeeze过程和Excitation过程。

Squeeze过程对特征$x$沿着通道维度进行全局平均池化,用于提取特征的一阶统计量:

\[z_c = F_{sq}(x_c) = \frac{1}{H\times W} \sum_{h=1}^H \sum_{w=1}^W x_{c,h,w}\]

Excitation过程通过两层全连接层学习通道之间的相关性。第一个全连接层把通道数$C$压缩为$C/r$,第二个全连接层把通道数恢复为$C$,并通过Sigmoid函数生成特征通道的权重向量。

在全连接层中,引入了$r$倍降采样的瓶颈层(bottleneck)。瓶颈层能够降低模型的计算量。对于一个全连接层,若输入通道数和输出通道数分别为$C_{in}$和$C_{out}$,则该层的参数量为$C_{in} \times C_{out}$。中间引入$r$倍降采样的瓶颈层,则两层的参数总量为$C_{in} \times \frac{C_{in}}{r} + \frac{C_{in}}{r} \times C_{out} = \frac{C_{in}}{r} \times (C_{in}+C_{out})$,该参数量通常远小于之前的参数量。

作者通过实验设定$r=16$时整体性能和计算量最平衡:

SENet使用的通道注意力机制的Pytorch实现代码如下:

import torch.nn as nn

class SELayer(nn.Module):
    def __init__(self, channel, reduction=16):
        super(SELayer, self).__init__()
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(channel, channel//reduction,bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(channel//reduction,channel, bias=False),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        b,c,h,w = x.size()
        y = self.avgpool(x).view(b,c)
        y = self.fc(y).view(b,c,1,1)
        return x * y.expand_as(x)

通道注意力模块可以即插即用到任意卷积神经网络中,作者给出了把SENet嵌入到InceptionResNet网络模块的例子: