SENet:Squeeze-and-Excitation Networks

基本信息
-
📰标题: Squeeze-and-Excitation Networks
-
🖋️作者: Jie Hu
-
🏛️机构: Momenta (Beijing) / 北京Momenta
-
🔗链接: arXiv:1709.01507
-
🔥关键词: CNN, SE block, channel attention, image recognition
摘要概述
项目 | 内容 |
---|---|
📖研究背景 | 卷积神经网络(CNN)中通道关系建模不足 |
🎯研究目的 | 提出轻量级模块显式建模通道间依赖关系 |
✍️研究方法 | 设计Squeeze-and-Excitation(SE)模块:全局信息压缩+通道自适应重校准 |
🕊️研究对象 | ImageNet等图像分类数据集 |
🔍研究结论 | SE模块显著提升模型性能(ImageNet上top-5误差降低25%)且计算代价极小 |
⭐创新点 | 1. 通道注意力机制 2. 即插即用设计 3. 仅增加0.5%计算量 |
注:SE模块通过特征重标定实现通道自适应,后续发展为计算机视觉基础模块之一。 |
背景
-
研究背景:CNN在视觉任务中表现出色,但传统卷积层主要关注局部空间连接模式,缺乏对channel-wise关系的显式建模。Inception等架构通过多尺度处理提升性能,近期研究多聚焦于空间依赖性建模和空间注意力机制。
-
过去方案:现有方法(如Inception、空间注意力模型)侧重于优化空间维度特征交互,但未系统解决通道间依赖关系建模问题。这类方法需引入额外超参数或复杂结构,工程实现成本较高。
-
研究动机:针对CNN通道关系建模不足的核心问题,提出轻量化SE模块,通过特征重标定机制自适应调整通道特征响应。该方法以极小计算代价(仅增0.5%参数量)实现全局通道依赖建模,在ImageNet等任务中验证其普适性。
方法
-
理论背景
基于CNN特征通道的全局上下文建模需求,受神经系统注意力机制启发,提出特征通道的显式动态调控理论。核心假设:通道特征响应应具备自适应重标定能力,通过建模通道间非线性依赖关系提升特征判别性。 -
技术路线
-
Squeeze操作:全局平均池化(GAP)压缩空间维度,生成通道级统计描述符(C×1×1)
-
Excitation操作:
- 两层全连接网络(含ReLU和Sigmoid)学习通道间非线性交互
- 生成通道注意力权重(C×1×1)
-
特征重标定:原始特征图与注意力权重逐通道相乘,实现通道自适应校准
-
模块部署:灵活嵌入现有网络(如ResNet单元后),形成SE-ResNet等变体
结论
- 提出SE block架构单元,通过动态通道特征重标定机制显著增强网络的表征能力,为CNN通道依赖建模提供新范式
- 优点:
1) 在多个数据集实现SOTA性能
2) 模块轻量化且即插即用
3) 特征重要性分析对网络压缩等衍生任务有启发价值 - 主要结论:
- SE模块有效解决了传统架构在channel-wise特征依赖建模上的局限性
- 实验证明SENets在保持计算效率的同时提升判别特征学习能力
- 模块诱导的特征重要性可迁移至网络剪枝等应用场景
pytorch代码
import torch
import torch.nn as nn
import torch.nn.functional as F
class SEBlock(nn.Module):
def __init__(self, in_channels, reduction_ratio=16):
"""
SE Block 实现
Args:
in_channels: 输入特征图的通道数
reduction_ratio: 压缩比例(用于中间层通道数)
"""
super(SEBlock, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1) # 全局平均池化 (Squeeze)
# Excitation 部分:两层全连接层 + 激活函数
self.fc = nn.Sequential(
nn.Linear(in_channels, in_channels // reduction_ratio, bias=False),
nn.ReLU(inplace=True),
nn.Linear(in_channels // reduction_ratio, in_channels, bias=False),
nn.Sigmoid() # 输出通道权重 [0, 1]
)
def forward(self, x):
b, c, _, _ = x.shape # batch_size, channels, height, width
# Squeeze: 全局平均池化得到通道描述符
y = self.avg_pool(x).view(b, c) # shape: [b, c]
# Excitation: 生成通道权重
y = self.fc(y).view(b, c, 1, 1) # shape: [b, c, 1, 1]
# 特征图重标定(通道乘法)
return x * y.expand_as(x)
# ------------------- 用法示例 -------------------
if __name__ == "__main__":
# 1. 初始化SE Block(输入通道数为256,压缩比例16)
se_block = SEBlock(in_channels=256, reduction_ratio=16)
# 2. 模拟输入数据(batch_size=4, 通道=256, 特征图尺寸=56x56)
dummy_input = torch.randn(4, 256, 56, 56)
# 3. 前向传播
output = se_block(dummy_input)
print(f"输入形状: {dummy_input.shape}")
print(f"输出形状: {output.shape}") # 应与输入形状一致
关键点解析
-
Squeeze 操作
通过 nn.AdaptiveAvgPool2d(1) 将每个通道的全局空间信息压缩为一个标量。
-
Excitation 操作
两层全连接层:
第一层降维(reduction_ratio 控制压缩比例,默认16)。
第二层恢复原始通道数,并通过 Sigmoid 输出权重值(0~1)。
-
特征重标定
将通道权重与原始特征图逐通道相乘(x * y),实现自适应校准。
作者
arwin.yu.98@gmail.com