YOLOv11改进策略【注意力机制篇】| 添加SE、CBAM、ECA、CA、Swin Transformer等注意力和多头注意力机制

前言

这篇文章带来一个经典注意力模块的汇总,虽然有些模块已经发布很久了,但后续的注意力模块也都是在此基础之上进行改进的,对于初学者来说还是有必要去学习了解一下,以加深对模块,模型的理解。


专栏目录:YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

专栏地址:YOLOv11改进专栏——以发表论文的角度,快速准确的找到有效涨点的创新点!


一、为什么要引入注意力机制?

来源:注意力机制的设计灵感来源于人类视觉系统。当我们在观察外界事物时,会自动将注意力集中在重要或感兴趣的区域,而忽略无关信息。计算机视觉中的注意力机制就是在试图模拟这一过程,以提高模型的感知和理解能力。

问题:随着图像数据量的增加,模型需要处理的信息量也随之增大。传统的卷积神经网络在处理大量数据时可能会遇到信息过载的问题,导致性能下降。注意力机制通过有选择地关注重要信息,帮助模型在海量数据中筛选出关键内容,从而提高检测精度。

好处

  • 注意力机制能够赋予输入数据的不同部分以不同的权重,使模型更加关注重要的特征信息。
  • 通过生成热力图,显示模型在做出决策时关注的具体区域,有助于更好地理解模型的决策过程,增强模型的可解释性。
  • 注意力机制使模型在处理不同数据集和任务时能够更灵活地调整其关注点。有助于提升模型的泛化能力,使其在面对新数据集或新任务时仍能保持较高的性能水平。

除了能够提升性能外,其最主要的还是其即插即用的特性,无论模块放在什么地方,都可以运行查看训练效果,更方便炼丹成功~

二、SE

2.1 SE的原理

通道注意力模块关注于网络中每个通道的重要性,通过为每个通道分配不同的权重,使得网络能够更加关注那些对任务更为关键的通道特

### 如何在Swin Transformer模型中实现或添加注意力机制 Swin Transformer 是一种基于窗口划分的分层架构,它通过局部-全局注意力机制实现了高效的视觉建模[^1]。为了增强 Swin Transformer 的表现能力,可以引入额外的注意力机制来捕捉更丰富的特征表示。 #### 1. **标准窗口注意力** Swin Transformer 已经内置了一种特殊的多头自注意力机制——窗口化多头自注意力(Window-based Multi-head Self-Attention)。这种机制将输入图像划分为固定大小的非重叠窗口,并在每个窗口内部执行自注意力操作,从而显著降低了计算复杂度[^4]。 具体而言,窗口化的多头自注意力可以通过以下方式定义: ```python class WindowAttention(nn.Module): def __init__(self, dim, window_size, num_heads, qkv_bias=True, attn_drop=0., proj_drop=0.): super().__init__() self.dim = dim self.window_size = window_size self.num_heads = num_heads # 初始化查询、键值矩阵 self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) # 注意力权重缩放因子 self.scale = (dim // num_heads) ** -0.5 # Dropout 层 self.attn_drop = nn.Dropout(attn_drop) self.proj = nn.Linear(dim, dim) self.proj_drop = nn.Dropout(proj_drop) def forward(self, x): B_, N, C = x.shape qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) q, k, v = qkv.unbind(0) # 计算注意力分数并应用 softmax 函数 attn = (q @ k.transpose(-2, -1)) * self.scale attn = attn.softmax(dim=-1) attn = self.attn_drop(attn) # 加权求得到最终输出 x = (attn @ v).transpose(1, 2).reshape(B_, N, C) x = self.proj(x) x = self.proj_drop(x) return x ``` --- #### 2. **扩展注意力机制** 除了默认的窗口注意力外,还可以结合其他类型的注意力机制来提升 Swin Transformer 的性能: ##### a. **SE 注意力机制** SENet(Squeeze-and-Excitation Network)是一种通道注意力机制,能够动态调整不同通道的重要性。可以在 Swin Transformer 的残差块之后加入 SE 模块,以强化重要特征的学习效果[^5]。 ```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) ``` ##### b. **CBAM 注意力机制** CBAM(Convolutional Block Attention Module)综合了通道注意力空间注意力两种形式。它可以作为附加模块嵌入到 Swin Transformer 中,进一步提高特征表达能力[^2]。 ```python class SpatialAttention(nn.Module): def __init__(self, kernel_size=7): super(SpatialAttention, self).__init__() assert kernel_size in (3, 7), 'kernel size must be 3 or 7' padding = 3 if kernel_size == 7 else 1 self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): avg_out = torch.mean(x, dim=1, keepdim=True) max_out, _ = torch.max(x, dim=1, keepdim=True) out = torch.cat([avg_out, max_out], dim=1) out = self.conv1(out) return self.sigmoid(out) ``` ##### c. **ECA 注意力机制** ECA(Efficient Channel Attention)是对 SE 注意力的一种优化版本,减少了参数量的同时保持了良好的性能。适合用于轻量化场景下的 Swin Transformer 改进[^3]。 ```python class ECALayer(nn.Module): """Constructs a ECA module. Args: channels: Number of input feature map's channels. gamma: Used to calculate the number of reduced dimensions `k`. Default value is set according to original paper. b: Used to calculate the number of reduced dimensions `k`. Default value is set according to original paper. """ def __init__(self, channels, gamma=2, b=1): super(ECALayer, self).__init__() t = int(abs((math.log(channels, 2) + b) / gamma)) k = t if t % 2 else t + 1 self.avg_pool = nn.AdaptiveAvgPool2d(1) self.conv = nn.Conv1d(1, 1, kernel_size=k, padding=(k - 1) // 2, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): y = self.avg_pool(x) y = self.conv(y.squeeze(-1).transpose(-1, -2)).transpose(-1, -2).unsqueeze(-1) y = self.sigmoid(y) return x * y.expand_as(x) ``` --- #### 3. **注意事项** 当向 Swin Transformer 添加新的注意力机制时,需特别关注以下几个方面: - **维度一致性**:确保新引入的注意力模块与原始模型各层的输入/输出尺寸相匹配。 - **计算开销控制**:虽然某些注意力机制能带来性能增益,但也可能增加训练时间或内存消耗。因此应合理评估其实际效益[^4]。 - **代码结构调整**:如果是在现有框架基础上进行改造,则需要同步更新配置文件以及初始化逻辑。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Limiiiing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值