SENet学习笔记

SENet是一种在卷积神经网络中引入特征通道自适应校准机制的方法。通过Squeeze和Excitation两个步骤,SENet能够在不增加额外空间维度的情况下,有效建模特征通道间的相互依赖关系。这种机制有助于网络更好地关注于有用的特征,同时抑制不重要的信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SENet总结

论文:《Squeeze-and-Excitation Networks》
论文链接:https://arxiv.org/abs/1709.01507
代码地址:https://github.com/hujie-frank/SENet

1. 概述

  此论文是由Momenta公司所作并发于2017CVPR,论文中的SENet赢得了ImageNet最后一届(ImageNet 2017)的图像识别冠军,论文的作者也很无私开源了其代码,并有caffe版本的实现。论文的核心点在对CNN中的feature channel(特征通道依赖性)利用和创新。看了论文最后第六节的分析,感觉作者肯定在网络架构上尝试了无数次实验才得到最后的相关的一些结论,这里膜拜一下。
  卷积核作为CNN的核心,通常都是在局部感受野上将空间(spatial)信息和特征维度(channel-wise)的信息进行聚合最后获取全局信息。卷积神经网络由一系列卷积层、非线性层和下采样层构成,这样它们能够从全局感受野上去捕获图像的特征来进行图像的描述,然而去学到一个性能非常强劲的网络是相当困难的。
论文的动机是从特征通道之间的关系入手,希望显式地建模特征通道之间的相互依赖关系。另外,没有引入一个新的空间维度来进行特征通道间的融合,而是采用了一种全新的“特征重标定”策略。具体来说,就是通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去增强有用的特征并抑制对当前任务用处不大的特征,通俗来讲,就是让网络利用全局信息有选择的增强有益feature通道并抑制无用feature通道,从而能实现feature通道自适应校准。
2. 论文的核心

  论文通过显式地建模通道之间的相互依赖关系,自适应地重新校准通道的特征响应,从而设计了SE block如图1所示。论文的核心就是Squeeze和Excitation(论文牛的地方)两个操作。下面先介绍一下这两个操作是怎么实现的并介绍其主要的作用,论文中给出了几个公式很清晰的表示出了其原理,我将结合这几个公式阐述Squeeze和Excitation的原理。
  这里写图片描述
                          图1 SE block结构图
         这里写图片描述
  如图1所示X→U的实现过程就是公式1,一般就是CNN中的一些普通的操作,例如卷积或一组卷积。
2.1 Squeeze(挤压)

       这里写图片描述
  Squeeze操作就是在得到U(多个feature map)之后采用全局平均池化操作对其每个feature map进行压缩,使其C个feature map最后变成1*1*C的实数数列,如图2中红色框标记的区域就是Squeeze操作。一般CNN中的每个通道学习到的滤波器都对局部感受野进行操作,因此U中每个feature map都无法利用其它feature map的上下文信息,而且网络较低的层次上其感受野尺寸都是很小的,这样情况就会更严重。
  U(多个feature map)可以被解释为局部描述子的集合,这些描述子的统计信息对于整个图像来说是有表现力的。论文选择最简单的全局平均池化操作,从而使其具有全局的感受野,使得网络低层也能利用全局信息。
2.2 Excitation(激励)

     这里写图片描述
  论文通过Excitation操作(如图2紫色框标注)来全面捕获通道依赖性,论文提出需要满足两个标准:
    (1) 它必须是灵活的(特别是它必须能够学习通道之间的非线性交互);
    (2) 它必须学习一个非互斥的关系,因为独热激活相反,这里允许强调多个通道。
  为了满足这些要求,论文选择采用一个简单的gating mechanism,使用了sigmoid激活函数。其中δ是指ReLU函数(不明白为什么使用了ReLU,个人理解是为了弥补sigmoid的不足之处),
这里写图片描述
  (论文厉害之处)为了限制模型复杂度和辅助泛化,论文通过引入两个全连接(FC)层(都是1*1的conv层),即降维层参数为W1,降维比例为r(论文把它设置为16),然后经过一个ReLU,然后是一个参数为W2的升维层。
最后得到1*1*C的实数数列结合U(原始缝feature map)通过公式4进行Scale操作得到最终的输出。
              这里写图片描述
这里写图片描述
                     这里写图片描述
                       图2 Inception 嵌入SE block结构
   图2所示就是SE block流程结构,给定一个输入x,其特征通道数为c_1,通过一系列卷积等一般变换后得到一个特征通道数为c_2的特征。与传统的CNN不一样的是,接下来论文通过三个操作来重标定前面得到的特征。
   首先是Squeeze操作,顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得浅层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。
其次是Excitation操作,它是一个类似于循环神经网络中门的机制。通过参数来为每个特征通道生成权重,其中参数被学习用来显式地建模特征通道间的相关性。
   最后是一个Reweight的操作,我们将Excitation的输出的权重看做是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。

3. 附加

3.1 Excitation的作用

  论文比较有趣的地方在论文后面,作者对比不同类之间做了一些实验,阐述了Excitation在网络中不同层中的作用是不同的。
这里写图片描述
                  图4 SE-ResNet-50不同模块在ImageNet上由Excitation引起的激活
论文对SENets中Excitation的作用提出以下三点看法:
  首先,不同类别的分布在较低层中几乎相同,例如,SE_2_3表明在网络的最初阶段特征通道的重要性很可能由不同的类别共享。
  当网络层数较深时,每个通道的值变得更具类别特定性,因为不同类别对特征的判别性值具有不同的偏好,例如,SE_4_6和SE_5_1这两个观察结果与以前的研究结果一致,即低层特征通常更普遍(即分类中不可知的类别),而高层特征具有更高的特异性。因此,表示特征学习从SE block的重新校准中受益,其自适应地促进特征提取和专业化。
(没看懂)最后,论文在网络的最后阶段观察到一个有些不同的现象,例如,SE_5_2呈现出朝向饱和状态的有趣趋势,其中大部分激活接近于1,其余激活接近于0,在所有激活值取1的点处,该块将成为标准残差块。
在网络的末端SE_5_3中(在分类器之前紧接着是全局池化),不同的类出现了尺度上只有轻微的变化的相似模式(可以通过分类器来调整)。这表明,SE_5_2和SE_5_3在为网络提供重新校准方面比前面的块更不重要,这一发现与第四节实证研究的结果是一致的。这表明,通过删除最后一个阶段的SE块,网络总体参数数量可以显著减少,而性能只有一点损失(<0.1%的top-1错误率)。

  3.2附录的一些细节可以在以后应用中作为参考

03-23
### SE Net 深度学习架构简介 SENetSqueeze-and-Excitation Network)是一种用于提升卷积神经网络性能的深度学习架构,它通过引入一种称为“通道注意力机制”的方式来增强特征表示能力[^1]。具体来说,SENet通过对不同通道上的特征图赋予不同的权重,使得模型能够更加关注重要的特征。 #### 架构组成 SENet的核心思想可以分为三个部分: 1. **Squeeze(压缩)**:全局平均池化操作被用来获取每个通道上特征图的空间信息,并将其转换为一维向量。这一步骤减少了计算复杂度并保留了重要信息[^3]。 2. **Excitation(激励)**:通过全连接层和激活函数构建一个小型子网络,该子网络会生成一组权重值,这些权重反映了各个通道的重要性程度。 3. **Reweight(重加权)**:最后将得到的权重重新作用于原始输入张量中的对应位置,从而实现动态调整各通道贡献的效果。 以下是基于 PyTorch 的简单实现代码示例: ```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, 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) # 将 SEBlock 添加到 ResNet 中的一个例子 def se_resnet_block(): block = nn.Sequential( nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=1), nn.BatchNorm2d(64), nn.ReLU(), SELayer(channel=64), # 插入 SE Layer nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=1), nn.BatchNorm2d(64), nn.ReLU() ) return block ``` 上述代码展示了如何创建一个基本的 Squeeze-and-Excitation 层以及如何将其嵌入到现有的 CNN 结构中[^2]。 #### 使用教程 为了更好地理解 SENet 并实际运用到项目当中,可以从以下几个方面入手: 1. 学习官方论文《Squeeze-and-Excitation Networks》及其背后的理论基础; 2. 参考已有的开源实现案例,比如 GitHub 上由 `moskomule` 提供的 PyTorch 版本 或者 Keras 社区分享的文章; 3. 实践过程中注意调试超参数设置,例如缩减比例 (`reduction`) 对最终效果的影响。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值