SENet

SENet

  ImageNet冠军
  SE模块相当于channel-wise attention。卷积核作为卷积神经网络的核心,通常被看做是在局部感受野上,将空间上(spatial)的信息和特征维度上(channel-wise)的信息进行聚合的信息聚合体。
  最近很多工作被提出来从空间维度层面来提升网络的性能,如Inception结构中嵌入了多尺度信息,聚合多种不同感受野上的特征来获得性能增益;在Inside-Outside网络中考虑了空间中的上下文信息;还有将Attention机制引入到空间维度上等等。

  参考资料:
  https://zhuanlan.zhihu.com/p/39530147
  http://www.sohu.com/a/161793789_642762

  在SE结构中,Squeeze和Excitation是两个非常关键的操作,所以我们以此来命名。我们的动机是希望显式地建模特征通道之间的相互依赖关系。另外,我们并不打算引入一个新的空间维度来进行特征通道间的融合,而是采用了一种全新的“特征重标定”策略。具体来说,就是通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征。

网络结构

在这里插入图片描述

  给定一个输入x,其特征通道数为c_1,通过一系列卷积等一般变换后得到一个特征通道数为c_2的特征。与传统的CNN不一样的是,接下来我们通过三个操作来重标定前面得到的特征:

  1)首先是Squeeze操作,我们顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。

  2)其次是Excitation操作,它是一个类似于循环神经网络中门的机制。通过参数 来为每个特征通道生成权重,其中参数 被学习用来显式地建模特征通道间的相关性。

  3)最后是一个Reweight的操作,我们将Excitation的输出的权重看做是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。

具体的实例

在这里插入图片描述

  1)左图是将SE模块嵌入到Inception结构的一个示例
  使用global average pooling作为Squeeze操作。紧接着两个Fully Connected 层组成一个Bottleneck结构去建模通道间的相关性,并输出和输入特征同样数目的权重。我们首先将特征维度降低到输入的1/16,然后经过ReLu激活后再通过一个Fully Connected 层升回到原来的维度。这样做比直接用一个Fully Connected层的好处在于:a)具有更多的非线性,可以更好地拟合通道间复杂的相关性;b)极大地减少了参数量和计算量。然后通过一个Sigmoid的门获得0~1之间归一化的权重,最后通过一个Scale的操作来将归一化后的权重加权到每个通道的特征上。

  2)右图是将SE嵌入到 ResNet模块中的一个例子,嵌入到含有skip-connections的模块中。
  操作过程基本和SE-Inception一样,只不过是在Addition前对分支上Residual的特征进行了特征重标定。如果对Addition后主支上的特征进行重标定,由于在主干上存在0~1的scale操作,在网络较深BP优化时就会在靠近输入层容易出现梯度消散的情况,导致模型难以优化。

实验

  它还在模型和计算复杂度上具有良好的特性。
  拿ResNet-50和SE-ResNet-50对比举例来说,SE-ResNet-50相对于ResNet-50有着10%模型参数的增长。额外的模型参数都存在于Bottleneck设计的两个Fully Connected中,由于ResNet结构中最后一个stage的特征通道数目为2048,导致模型参数有着较大的增长,实验发现移除掉最后一个stage中3个build block上的SE设定,可以将10%参数量的增长减少到2%。此时模型的精度几乎无损失。

  由于在现有的GPU实现中,都没有对global pooling和较小计算量的Fully Connected进行优化,这导致了在GPU上的运行时间SE-ResNet-50相对于ResNet-50有着约10% 的增长。尽管如此,其理论增长的额外计算量仅仅不到1%,这与其在CPU 运行时间上的增长相匹配(~2%)。可以看出,在现有网络架构中嵌入SE模块而导致额外的参数和计算量的增长微乎其微。

### SENet 模块使用教程 对于希望集成 SE (Squeeze-and-Excitation) 模块到神经网络中的开发者而言,理解其工作原理以及如何将其嵌入现有框架至关重要。SE模块能够增强卷积神经网络的表现力,在不显著增加计算成本的情况下提升性能。 #### 基础概念 SENet通过引入通道注意力机制来改进传统 CNN 架构。具体来说,该方法允许模型自适应地重新校准特征图上的权重分配,从而聚焦于更重要的信息[^2]。 #### 集成至其他架构 由于 SE 块的设计具有高度通用性和灵活性,因此可以方便地插入大多数现有的 CNN 结构之中。这意味着几乎不需要对原生网络做任何结构性改动即可享受由 SE 技术带来的好处。例如,可以在 ResNet、Inception 或 VGG 这样的经典模型里加入 SE 组件以提高它们的效果。 #### 训练配置与执行 当准备训练一个基于 SE 的新模型或者微调已有预训练模型时,可以通过命令行传递必要的参数给 `train.py` 脚本来指定各项设置: ```bash python scripts/train.py --dataset <DATASET_PATH> --model SENet --epochs 100 ``` 上述指令展示了最基本的用法,其中 `<DATASET_PATH>` 应替换为实际的数据集路径;而 `--model SENet` 表明要使用的特定模型类型即 SENet;最后指定了迭代次数为 100 epoch[^1]。 #### Python实现片段 下面给出了一段简化版的 PyTorch 实现代码作为参考,演示了怎样定义并应用 SE 层: ```python import torch.nn as nn 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), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel), 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 Layer 添加到任意 Convolutional Block 中... def make_layer(block, planes, blocks, stride=1, se_reduction=None): layers = [] ... if se_reduction is not None: layers.append(SELayer(planes*block.expansion, se_reduction)) ... return nn.Sequential(*layers) ``` 这段代码实现了 SE 层的核心逻辑,并提供了一个函数用于构建带有可选 SE 单元的标准层序列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值