【即插即用】Squeeze-and-Excitation Networks——2018CVPR

在这里插入图片描述
  引用:Hu, Jie, Li Shen, and Gang Sun. “Squeeze-and-excitation networks.” Proceedings of the IEEE conference on computer vision and pattern recognition. 2018.
  论文题目:Squeeze-and-Excitation Networks
  论文链接:下载地址(不用看)
  论文代码:下载地址(不用看)
  直接Copy!! 试

1、作用

  SENet通过引入一个新的结构单元——“Squeeze-and-Excitation”(SE)块——来增强卷积神经网络的代表能力。是提高卷积神经网络(CNN)的表征能力,通过显式地建模卷积特征通道之间的依赖关系,从而在几乎不增加计算成本的情况下显著提升网络性能。SE模块由两个主要操作组成:压缩(Squeeze)和激励(Excitation)

2、机制

1、压缩操作:
  SE模块首先通过全局平均池化操作对输入特征图的空间维度(高度H和宽度W)进行聚合,为每个通道生成一个通道描述符。这一步有效地将全局空间信息压缩成一个通道向量,捕获了通道特征响应的全局分布。这一全局信息对于接下来的重新校准过程至关重要。
2、激励操作:
  在压缩步骤之后,应用一个激励机制,该机制本质上是由两个全连接(FC)层和一个非线性激活函数(通常是sigmoid)组成的自门控机制。第一个FC层降低了通道描述符的维度,应用ReLU非线性激活,随后第二个FC层将其投影回原始通道维度。这个过程建模了通道间的非线性交互,并产生了一组通道权重。
3、特征重新校准:
  激励操作的输出用于重新校准原始输入特征图。输入特征图的每个通道都由激励输出中对应的标量进行缩放。这一步骤有选择地强调信息丰富的特征,同时抑制不太有用的特征,使模型能够专注于任务中最相关的特征。

3、独特优势

1、通道间依赖的显式建模
  SE Net的核心贡献是通过SE块显式建模通道间的依赖关系,有效地提升了网络对不同通道特征重要性的适应性和敏感性。这种方法允许网络学会动态地调整各个通道的特征响应,以增强有用的特征并抑制不那么重要的特征。
2、轻量级且高效
  尽管SE块为网络引入了额外的计算,但其设计非常高效,额外的参数量和计算量相对较小。这意味着SENet可以在几乎不影响模型大小和推理速度的情况下,显著提升模型性能。
3、模块化和灵活性
  SE块可以视为一个模块,轻松插入到现有CNN架构中的任何位置,包括ResNet、Inception和VGG等流行模型。这种模块化设计提供了极大的灵活性,使得SENet可以广泛应用于各种架构和任务中,无需对原始网络架构进行大幅度修改。
4、跨任务和跨数据集的泛化能力
  SENet在多个基准数据集上展现出了优异的性能,包括图像分类、目标检测和语义分割等多个视觉任务。这表明SE块不仅能提升特定任务的性能,还具有良好的泛化能力,能够跨任务和跨数据集提升模型的效果。
5、增强的特征表征能力
  通过调整通道特征的重要性,SENet能够更有效地利用模型的特征表征能力。这种增强的表征能力使得模型能够在更细粒度上理解图像内容,从而提高决策的准确性和鲁棒性。

4、代码:

import numpy as np
import torch
from torch import nn
from torch.nn import init

class SEAttention(nn.Module):
    # 初始化SE模块,channel为通道数,reduction为降维比率
    def __init__(self, channel=512, reduction=16):
        super().__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)  # 自适应平均池化层,将特征图的空间维度压缩为1x1
        self.fc = nn.Sequential(  # 定义两个全连接层作为激励操作,通过降维和升维调整通道重要性
            nn.Linear(channel, channel // reduction, bias=False),  # 降维,减少参数数量和计算量
            nn.ReLU(inplace=True),  # ReLU激活函数,引入非线性
            nn.Linear(channel // reduction, channel, bias=False),  # 升维,恢复到原始通道数
            nn.Sigmoid()  # Sigmoid激活函数,输出每个通道的重要性系数
        )

    # 权重初始化方法
    def init_weights(self):
        for m in self.modules():  # 遍历模块中的所有子模块
            if isinstance(m, nn.Conv2d):  # 对于卷积层
                init.kaiming_normal_(m.weight, mode='fan_out')  # 使用Kaiming初始化方法初始化权重
                if m.bias is not None:
                    init.constant_(m.bias, 0)  # 如果有偏置项,则初始化为0
            elif isinstance(m, nn.BatchNorm2d):  # 对于批归一化层
                init.constant_(m.weight, 1)  # 权重初始化为1
                init.constant_(m.bias, 0)  # 偏置初始化为0
            elif isinstance(m, nn.Linear):  # 对于全连接层
                init.normal_(m.weight, std=0.001)  # 权重使用正态分布初始化
                if m.bias is not None:
                    init.constant_(m.bias, 0)  # 偏置初始化为0

    # 前向传播方法
    def forward(self, x):
        b, c, _, _ = x.size()  # 获取输入x的批量大小b和通道数c
        y = self.avg_pool(x).view(b, c)  # 通过自适应平均池化层后,调整形状以匹配全连接层的输入
        y = self.fc(y).view(b, c, 1, 1)  # 通过全连接层计算通道重要性,调整形状以匹配原始特征图的形状
        return x * y.expand_as(x)  # 将通道重要性系数应用到原始特征图上,进行特征重新校准

# 示例使用
if __name__ == '__main__':
    input = torch.randn(50, 512, 7, 7)  # 随机生成一个输入特征图
    se = SEAttention(channel=512, reduction=8)  # 实例化SE模块,设置降维比率为8
    output = se(input)  # 将输入特征图通过SE模块进行处理
    print(output.shape)  # 打印处理后的特征图形状,验证SE模块的作用
### Squeeze-and-Excitation Networks (SENet) 的实现细节与算法原理 #### 算法原理 Squeeze-and-Excitation Networks 是一种用于增强卷积神经网络性能的技术,其核心思想在于通过学习通道之间的关系来重新校准特征的重要性。具体来说,它通过对不同通道的特征进行全局池化操作(squeeze),然后基于这些统计信息生成权重向量(excitation),最后将这些权重应用于原始特征图上以突出重要特征并抑制不重要的部分[^4]。 以下是 SE 模块的主要组成部分及其作用: 1. **Squeeze**: 对于输入的特征图 \( X \in \mathbb{R}^{C \times H \times W} \),其中 \( C \) 表示通道数,\( H \) 和 \( W \) 分别表示高度和宽度,SE 模块会对每个通道执行全局平均池化操作,得到一个描述全局空间分布的一维向量 \( z_c \in \mathbb{R}^C \)[^4]。 2. **Excitation**: 使用两个全连接层构建一个小规模的子网络,第一个全连接层会减少维度至 \( r \)-th 倍 (\( r \geq 1 \)),第二个全连接层恢复到原来的维度,并通过激活函数(如 ReLU 或 sigmoid)调整权重值范围。最终输出的是一个归一化的权重视图 \( s \in [0, 1]^C \)[^4]。 3. **Reweight**: 将上述计算所得的权重加权应用回原特征图上的每一个对应位置处,形成新的特征表达形式\[ Y_{ijc}=X_{ijc}\cdot s_c\][^4]。 这种机制允许模型自适应地关注更有意义的部分而忽略其他无关紧要的内容,从而提升整体表现效果。 #### 实现细节 下面展示了一个简单的 PyTorch 版本的 SEBlock 定义方式: ```python import torch.nn as nn import torch 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() # 获取batch size以及channel数量 y = self.avg_pool(x).view(b, c) y = self.fc(y).view(b, c, 1, 1) return x * y.expand_as(x) # Example usage within Residual Block or any other architecture component. ``` 此代码片段定义了一种标准型态下的 SE 层结构,可以嵌入到现有的 CNN 架构之中作为附加组件使用。 #### 论文下载链接 关于 SENet 更详细的理论阐述可参阅原文献《Squeeze-and-Excitation Networks》,该文章发表于 CVPR 2018 年会上。可以通过以下地址访问 PDF 文件版本: https://arxiv.org/abs/1709.01507 另外值得注意的是,在实际工程实践中也可以考虑直接调用预训练好的模型库比如 torchvision.models 中已经包含了支持 SE 结构的各种经典分类器变体供快速部署测试之需。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值