yolo检测核心组件3:ECA 注意力机制
!abstract 论文信息
- 论文标题: ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks
- 作者: Qilong Wang, Banggu Wu, Pengfei Zhu, Peihua Li, Wangmeng Zuo, Qinghua Hu
- 发表: CVPR 2020
- 论文地址: https://arxiv.org/abs/1910.03157
- 核心贡献: 提出一种高效的通道注意力机制,避免全连接层的降维操作,仅用一维卷积即可捕获跨通道交互信息
一、核心思想
ECA 的核心思想是避免通道注意力中的降维操作,用一个轻量的一维卷积替代全连接层来捕获局部跨通道交互信息。
SE注意力机制中的全连接层先降维再升维,这种操作会破坏通道与其权重之间的直接对应关系。ECA 通过一维卷积(1D Conv)在相邻通道之间建立局部依赖关系,既保留了通道间的交互信息,又大幅减少了参数量。

ECA 的关键特点:
- 无降维操作:不使用全连接层,避免通道信息的降维损失
- 局部跨通道交互:使用 1D 卷积捕获相邻通道间的依赖关系
- 自适应核大小:根据通道数自动确定 1D 卷积核的大小
- 极低开销:参数量和计算量几乎可以忽略不计
二、模块结构
2.1 SE注意力 vs ECA 对比
SE 通道注意力:
输入 [C×H×W] → GAP → [C×1×1] → FC(C→C/r) → ReLU → FC(C/r→C) → Sigmoid → 加权
参数量: 2 × C²/r
ECA 通道注意力:
输入 [C×H×W] → GAP → [C×1×1] → Conv1D(k) → Sigmoid → 加权
参数量: k(仅一个卷积核大小的参数!)
2.2 ECA 模块结构
输入特征图 F [C×H×W]
│
全局平均池化 (GAP)
│
[C×1×1] → Reshape → [1×C]
│
一维卷积 Conv1D (kernel_size=k)
│
Sigmoid 激活
│
Reshape → [C×1×1]
│
逐通道乘法 × F
│
输出特征图 [C×H×W]
2.3 自适应核大小选择
ECA 的关键创新之一是通过通道数 C 自适应确定卷积核大小 k:
k=∣log2Cγ+bγ∣oddk = \left|\frac{\log_2 C}{\gamma} + \frac{b}{\gamma}\right|_{\text{odd}}k= γlog2C+γb odd
其中 γ=2\gamma = 2γ=2,b=1b = 1b=1,∣⋅∣odd|\cdot|_{\text{odd}}∣⋅∣odd 表示取最近的奇数。
| 通道数 C | 卷积核大小 k |
|---|---|
| 64 | 3 |
| 128 | 5 |
| 256 | 7 |
| 512 | 9 |
| 1024 | 11 |
三、数学公式
3.1 SE-Net 的通道注意力
w=σ(W1⋅δ(W0⋅z))w = \sigma\Big(W_1 \cdot \delta(W_0 \cdot z)\Big)w=σ(W1⋅δ(W0⋅z))
其中 z=GAP(F)∈RC×1z = GAP(F) \in \mathbb{R}^{C \times 1}z=GAP(F)∈RC×1,W0∈RC/r×CW_0 \in \mathbb{R}^{C/r \times C}W0∈RC/r×C,W1∈RC×C/rW_1 \in \mathbb{R}^{C \times C/r}W1∈RC×C/r。
3.2 ECA 的通道注意力
w=σ(C1Dk(z)) w = \sigma\Big(C1D_k(z)\Big) w=σ(C1Dk(z))
其中 z=GAP(F)∈RC×1z = GAP(F) \in \mathbb{R}^{C \times 1}z=GAP(F)∈RC×1,C1DkC1D_kC1Dk 表示核大小为 kkk 的一维卷积,σ\sigmaσ 为 Sigmoid 函数。
3.3 自适应核大小公式
k=∣log2Cγ+bγ∣oddk = \left|\frac{\log_2 C}{\gamma} + \frac{b}{\gamma}\right|_{\text{odd}}k= γlog2C+γb odd
参数说明:
- CCC:通道数
- γ\gammaγ:控制通道与卷积核大小映射的速率(默认 γ=2\gamma = 2γ=2)
- bbb:偏移量(默认 b=1b = 1b=1)
- ∣⋅∣odd|\cdot|_{\text{odd}}∣⋅∣odd:取最近的奇数
3.4 最终输出
F^=w⊗F\hat{F} = w \otimes FF^=w⊗F
其中 ⊗\otimes⊗ 表示逐通道乘法(broadcasting)。
四、代码实现
4.1 ECA 模块(自适应核大小)
python
import torch
import torch.nn as nn
import math
class ECA(nn.Module):
"""Efficient Channel Attention (ECA) 模块
自适应卷积核大小的高效通道注意力机制。
"""
def __init__(self, channels=None, kernel_size=None, gamma=2, b=1):
super().__init__()
# 自适应计算卷积核大小
if kernel_size is None:
assert channels is not None, "需要指定通道数或卷积核大小"
kernel_size = int(abs((math.log2(channels) / gamma) + b / gamma))
kernel_size = kernel_size if kernel_size % 2 else kernel_size + 1
kernel_size = max(kernel_size, 3) # 最小为3
padding = kernel_size // 2
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.conv = nn.Conv1d(
1, 1,
kernel_size=kernel_size,
padding=padding,
bias=False
)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
b, c, h, w = x.size()
# 全局平均池化
y = self.avg_pool(x) # [B, C, 1, 1]
y = y.squeeze(-1).squeeze(-1) # [B, C]
y = y.unsqueeze(1) # [B, 1, C] --- 用于1D卷积
# 一维卷积捕获跨通道交互
y = self.conv(y) # [B, 1, C]
y = self.sigmoid(y)
y = y.squeeze(1).unsqueeze(-1).unsqueeze(-1) # [B, C, 1, 1]
return x * y
4.2 固定核大小版本
python
class ECA_Fixed(nn.Module):
"""固定卷积核大小的 ECA 模块"""
def __init__(self, kernel_size=3):
super().__init__()
padding = kernel_size // 2
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.conv = nn.Conv1d(1, 1, kernel_size=kernel_size,
padding=padding, bias=False)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, 1, c)
y = self.sigmoid(self.conv(y))
return x * y.view(b, c, 1, 1)
4.3 YOLO 中的集成版本
python
class ECA_YOLO(nn.Module):
"""适配 YOLO 的 ECA 模块"""
def __init__(self, c1):
"""c1: 输入通道数"""
super().__init__()
self.eca = ECA(channels=c1)
def forward(self, x):
if isinstance(x, list):
x = x[-1] # 取最后一个特征图
return self.eca(x)
五、在YOLO中的应用
5.1 集成到 C2f 模块
python
class C2f_ECA(nn.Module):
"""在C2f模块后添加ECA注意力"""
def __init__(self, c1, c2, n=1, shortcut=False, e=0.5):
super().__init__()
self.c2f = C2f(c1, c2, n, shortcut, e)
self.eca = ECA(channels=c2)
def forward(self, x):
x = self.c2f(x)
x = self.eca(x)
return x
5.2 参数量对比
| 注意力模块 | 额外参数量 (C=256) | 额外计算量 |
|---|---|---|
| SE | ~33K | ~33K FLOPs |
| CBAM | ~33K | ~33K FLOPs |
| ECA | ~7 | ~7 FLOPs |
| 无注意力 | 0 | 0 |
ECA 的参数量仅为 SE 的约 1/5000,几乎可以忽略不计。
5.3 YOLO 配置示例
yaml
backbone:
- [-1, 1, Conv, [64, 3, 2]]
- [-1, 1, Conv, [128, 3, 2]]
- [-1, 3, C2f, [128, True]]
- [-1, 1, Conv, [256, 3, 2]]
- [-1, 6, C2f_ECA, [256, True]] # 替换C2f为C2f_ECA
- [-1, 1, Conv, [512, 3, 2]]
- [-1, 6, C2f_ECA, [512, True]]
- [-1, 1, Conv, [1024, 3, 2]]
- [-1, 3, C2f_ECA, [1024, True]]
六、优缺点
优点
- 极低开销:参数量仅为卷积核大小级别(约 3~11 个参数),几乎零额外计算
- 无信息损失:避免了 SE-Net 中的降维操作,保留了通道间的完整信息
- 自适应设计:卷积核大小根据通道数自动调整,无需手动调参
- 即插即用:可方便地嵌入到任何 CNN 架构中
- 效果优秀:在 ImageNet 等基准测试上以极低代价达到了与 SE、CBAM 相当甚至更好的效果
缺点
- 局部交互范围:1D 卷积只能捕获相邻通道的局部关系,远距离通道的交互能力有限
- 仅通道注意力:不包含空间注意力机制,对空间维度的特征关注不足
- 固定交互模式:局部通道交互的模式是固定的,可能不适合所有任务
- 对小通道数效果有限:通道数很小时,自适应核大小可能退化为 3,捕获的交互信息有限
参考
- Wang, Q., Wu, B., Zhu, P., Li, P., Zuo, W., & Hu, Q. (2020). ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks. CVPR 2020.
- https://arxiv.org/abs/1910.03157
- https://github.com/BangguWu/ECA-Net