SENet结构解读

原文:https://zhuanlan.zhihu.com/p/65459972

一、前言

在深度学习领域,CNN分类网络的发展对其它计算机视觉任务如目标检测和语义分割都起到至关重要的作用,因为检测和分割模型通常是构建在CNN分类网络(称为backbone)之上。提到CNN分类网络,我们所熟知的是VGG,ResNet,Inception,DenseNet等模型,它们的效果已经被充分验证,而且被广泛应用在各类计算机视觉任务上。这里我们介绍一篇CVPR2017的文章SENet,它赢得了最后一届ImageNet 2017竞赛分类任务的冠军。重要的一点是SENet思路很简单,很容易扩展在已有网络结构中。

二、Squeeze-and-Excitation (SE) 模块解读

SENet的全称是Squeeze-and-Excitation Networks,中文可以翻译为压缩和激励网络。主要由两部分组成:

1. Squeeze部分。即为压缩部分,原始feature map的维度为H*W*C,其中H是高度(Height),W是宽度(width),C是通道数(channel)。Squeeze做的事情是把H*W*C压缩为1*1*C,相当于把H*W压缩成一维了,实际中一般是用global average pooling实现的。H*W压缩成一维后,相当于这一维参数获得了之前H*W全局的视野,感受区域更广。

2. Excitation部分。得到Squeeze的1*1*C的表示后,加入一个FC全连接层(Fully Connected),对每个通道的重要性进行预测,得到不同channel的重要性大小后再作用(激励)到之前的feature map的对应channel上,再进行后续操作。

 

 

三、SE模块的应用

SE模块的灵活性在于它可以直接应用现有的网络结构中。这里以Inception和ResNet为例。对于Inception网络,没有残差结构,这里对整个Inception模块应用SE模块。对于ResNet,SE模块嵌入到残差结构中的残差学习分支中。

具体如下图所示:

同样地,SE模块也可以应用在其它网络结构,如ResNetXt,Inception-ResNet,MobileNet和ShuffleNet中。

这里给出SE-ResNet-50和SE-ResNetXt-50的具体结构,如下表所示:

模型效果

SE模块很容易嵌入到其它网络中,作者为了验证SE模块的作用,在其它流行网络如ResNet和VGG中引入SE模块,测试其在ImageNet上的效果,如下表所示:

四、SE模块的实现

SE模块是非常简单的,实现起来也比较容易,这里给出PyTorch版本的实现(参考senet.pytorch):

class SELayer(nn.Module):
    def __init__(self, channel, reduction=16):
        super(SELayer, self).__init__()
        self.avg_pool = 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, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y.expand_as(x)

对于SE-ResNet模型,只需要将SE模块加入到残差单元(应用在残差学习那一部分)就可以:

class SEBottleneck(nn.Module):
        expansion = 4

        def __init__(self, inplanes, planes, stride=1, downsample=None, reduction=16):
            super(SEBottleneck, self).__init__()
            self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
            self.bn1 = nn.BatchNorm2d(planes)
            self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                                   padding=1, bias=False)
            self.bn2 = nn.BatchNorm2d(planes)
            self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
            self.bn3 = nn.BatchNorm2d(planes * 4)
            self.relu = nn.ReLU(inplace=True)
            self.se = SELayer(planes * 4, reduction)
            self.downsample = downsample
            self.stride = stride

        def forward(self, x):
            residual = x

            out = self.conv1(x)
            out = self.bn1(out)
            out = self.relu(out)

            out = self.conv2(out)
            out = self.bn2(out)
            out = self.relu(out)

            out = self.conv3(out)
            out = self.bn3(out)
            out = self.se(out)

            if self.downsample is not None:
                residual = self.downsample(x)

            out += residual
            out = self.relu(out)

            return out

五、总结

SE模块主要为了提升模型对channel特征的敏感性,这个模块是轻量级的,而且可以应用在现有的网络结构中,只需要增加较少的计算量就可以带来性能的提升。

<think>好的,用户想了解SENet的网络结构图解和架构说明。首先我需要回忆一下SENet的基本原理和结构。根据引用[4]提到的,SENet是经典CNN架构之一,而引用[2]和引用[1]中提到了SENet与其他网络如ResNet、DenseNet的区别,特别是与GCNet的关联。 SENet的核心是Squeeze-and-Excitation模块,这个模块通过显式建模通道之间的依赖关系来增强网络的表示能力。我应该先解释SE模块的结构,包括Squeeze和Excitation两个步骤。Squeeze阶段使用全局平均池化将空间信息压缩成一个通道描述符,Excitation阶段通过全连接层学习通道间的权重,然后对原始特征图进行重新校准。 接下来需要结合图表说明,但由于用户需要图解,可能需要描述结构而不是直接提供图片。可以分步骤说明,比如输入特征图经过卷积后得到U,然后进行Squeeze得到全局描述符,再经过两个全连接层生成权重,最后与U相乘得到加权后的特征图。 引用[2]提到SENet与非局部网络和GC块的关系,这里可以指出SE模块属于全局上下文建模的一种方法,但更注重通道维度的注意力。同时,引用[1]中比较了ResNet和DenseNet的不同连接方式,而SENet则是在通道维度进行调整,因此结构上的区别需要明确。 用户可能需要了解SE模块在整体网络中的位置,通常是在每个卷积块之后添加,例如在ResNet的残差结构中嵌入SE模块形成SE-ResNet。此外,应用场景和效果也需要提及,比如在ImageNet上的表现提升,以及如何减少计算量同时保持性能。 最后,生成相关问题时要围绕SENet结构、与其他网络的对比、应用场景等展开,确保问题具有针对性,帮助用户深入理解。</think>### SENet网络结构图解与架构说明 SENet(Squeeze-and-Excitation Network)是一种通过动态调整通道注意力提升模型性能的卷积神经网络,核心模块是**SE Block**,其结构可分为以下三步: 1. **Squeeze操作** 对输入特征图$U \in \mathbb{R}^{H \times W \times C}$进行全局平均池化,将每个通道的空间信息压缩为一个标量: $$z_c = \frac{1}{H \times W} \sum_{i=1}^{H} \sum_{j=1}^{W} u_c(i,j)$$ 输出向量$z \in \mathbb{R}^C$,表征通道的全局分布[^4]。 2. **Excitation操作** 通过全连接层学习通道权重: $$s = \sigma(W_2 \cdot \delta(W_1 \cdot z))$$ 其中$W_1 \in \mathbb{R}^{\frac{C}{r} \times C}$和$W_2 \in \mathbb{R}^{C \times \frac{C}{r}}$为可学习参数,$r$为压缩比(通常取16),$\delta$为ReLU激活函数,$\sigma$为Sigmoid函数[^2]。 3. **特征重标定** 将学习到的通道权重$s$与原特征图逐通道相乘: $$\tilde{u}_c = s_c \cdot u_c$$ 输出$\tilde{U} \in \mathbb{R}^{H \times W \times C}$,强化重要通道的特征响应。 #### 典型应用示例:SE-ResNet 在ResNet的残差块中嵌入SE模块,结构如下: ``` Input → Conv → SE Block → Skip Connection → Output ``` 通过残差连接保留原始信息,同时利用SE Block增强特征选择性[^1]。 #### 性能优势 - 在ImageNet数据集上,SE-ResNet-50将top-5错误率从7.48%降至6.62%[^4] - 计算量仅增加约2%,但显著提升模型表达能力
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值