YOLOv8改进 | 添加注意力篇 | 利用YOLOv10提出的PSA注意力机制助力YOLOv8有效涨点(附代码 + 详细修改教程)

本文介绍了YOLOv10的PSA(部分自注意力)模块,解决自注意力机制的计算复杂度问题。通过1×1卷积划分特征并仅在Stage 4后应用,实现全局表示学习。提供了详细的代码修改教程,指导如何在YOLOv8中添加PSA,包括创建文件、导入模块和配置yaml文件。文章还分享了训练过程和结果。

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

一、本文介绍

本文给大家带来的改进机制是YOLOv10提出的PSA注意力机制,自注意力在各种视觉任务中得到了广泛应用,因为它具有显著的全局建模能力。然而,自注意力机制表现出较高的计算复杂度和内存占用。为了解决这个问题,鉴于注意力头冗余的普遍存在,我们提出了一种高效的部分自注意力(PSA)模块设计,其能够在不显著增加计算成本的情况下提升YOLO模型的性能!本文附其网络结构图辅助大家理解该结构,同时本文包含YOLOv8添加该注意力机制的方法!

欢迎大家订阅我的专栏一起学习YOLO!

专栏目录:YOLOv8改进有效系列目录 | 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制 

目录

一、本文介绍

二、PSA介绍

三、PSA核心代码 

四、手把手教你添加PSA注意力机制

4.1 修改一

4.2 修改二 

4.3 修改三 

4.4 修改四 

五、PSA的yaml文件和运行记录

5.1 PSA的yaml文件1

5.2 训练代码 

### YOLOv8改进 MSHA 注意力机制的方法实现 在YOLOv8中,可以通过引入高效的注意力机制来增强模型性能。具体来说,可以借鉴其他版本(如YOLOv10)以及相关研究中的方法,对多尺度混合注意力(MSHA, Multi-Scale Hybrid Attention)机制进行优化。 #### 1. **基于 NAMA 的改进** 为了提升效率和轻量化特性,可以在 C2F 模块的不同位置嵌入 NAMA (Non-Aligned Movement Attention)[^1]。这种注意力机制通过重新设计 CBAM 的通道和空间注意力子模块,进一步增强了特征提取能力。对于通道注意力子模块,利用 BN 层的比例因子测量信道方差并指示其重要性。以下是其实现方式: ```python import torch.nn as nn class ChannelAttention(nn.Module): def __init__(self, num_channels, reduction_ratio=16): super(ChannelAttention, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(num_channels, num_channels // reduction_ratio), nn.ReLU(), nn.Linear(num_channels // reduction_ratio, num_channels), 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) 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.conv = 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.conv(out) return x * self.sigmoid(out) class NAMAAttention(nn.Module): def __init__(self, num_channels): super(NAMAAttention, self).__init__() self.channel_attention = ChannelAttention(num_channels) self.spatial_attention = SpatialAttention() def forward(self, x): x_ca = self.channel_attention(x) x_sa = self.spatial_attention(x_ca) return x_sa ``` 上述代码定义了一个新的 NAMA 注意力模块,该模块结合了通道注意力和空间注意力的功能,并将其应用于网络的各个阶段。 --- #### 2. **引入 MSDA 多尺度空洞注意力模块** 另一种有效改进方案是从 YOLOv10 借鉴 MSDA(Multi-Scale Dilated Attention)模块的设计思路[^3]。MSDA 能够捕获不同尺度的信息并通过空洞卷积扩展感受野。以下是一个简单的实现示例: ```python class MSADilatedBlock(nn.Module): def __init__(self, channels, dilations=[1, 2, 4]): super(MSADilatedBlock, self).__init__() self.dilations = dilations self.convs = nn.ModuleList([ nn.Conv2d(channels, channels//len(dilations), 3, padding=dilation, dilation=dilation) for dilation in dilations ]) self.fusion_conv = nn.Conv2d(channels, channels, 1) def forward(self, x): features = [] for conv in self.convs: features.append(conv(x)) fused_feature = torch.cat(features, dim=1) output = self.fusion_conv(fused_feature) return output class ImprovedMSHA(nn.Module): def __init__(self, input_dim, hidden_dim, heads=4, dropout=0.1): super(ImprovedMSHA, self).__init__() self.msa_heads = heads self.hidden_dim_per_head = hidden_dim // heads self.query_proj = nn.Linear(input_dim, hidden_dim) self.key_proj = nn.Linear(input_dim, hidden_dim) self.value_proj = nn.Linear(input_dim, hidden_dim) self.dropout = nn.Dropout(dropout) self.out_proj = nn.Linear(hidden_dim, input_dim) self.msda_block = MSADilatedBlock(input_dim) def forward(self, x): batch_size, seq_len, embed_dim = x.shape q = self.query_proj(x).reshape(batch_size, seq_len, self.msa_heads, -1).transpose(1, 2) k = self.key_proj(x).reshape(batch_size, seq_len, self.msa_heads, -1).transpose(1, 2) v = self.value_proj(x).reshape(batch_size, seq_len, self.msa_heads, -1).transpose(1, 2) attention_scores = torch.matmul(q, k.transpose(-2, -1)) / (embed_dim ** 0.5) attention_probs = torch.softmax(attention_scores, dim=-1) attended_values = torch.matmul(attention_probs, v).transpose(1, 2).contiguous().view(batch_size, seq_len, -1) msda_output = self.msda_block(attended_values.permute(0, 2, 1).unsqueeze(-1)).squeeze(-1).permute(0, 2, 1) final_output = self.out_proj(msda_output) return final_output ``` 在此基础上,`ImprovedMSHA` 将传统的自注意力与多尺度空洞注意力相结合,从而更好地捕捉全局上下文信息。 --- #### 3. **部分自注意力PSA)的应用** 除了以上两种方法外,还可以采用 PSA(Partial Self-Attention)模块来简化计算复杂度[^4]。这种方法的核心在于仅将部分特征送入 MHSA 和 FFN 进行处理,而其余部分保持不变。最终通过 1×1 卷积层完成特征融合。 ```python class PartialSelfAttention(nn.Module): def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1): super(PartialSelfAttention, self).__init__() self.nhead = nhead self.head_dim = d_model // nhead self.qkv_linear = nn.Linear(d_model, 3 * d_model) self.attn_dropout = nn.Dropout(dropout) self.proj = nn.Linear(d_model, d_model) self.ffn = nn.Sequential( nn.Linear(d_model, dim_feedforward), nn.ReLU(), nn.Linear(dim_feedforward, d_model) ) def split_heads(self, x, batch_size): return x.view(batch_size, -1, self.nhead, self.head_dim).transpose(1, 2) def forward(self, x): batch_size, seq_len, _ = x.shape qkv = self.qkv_linear(x).chunk(3, dim=-1) q, k, v = map(lambda t: self.split_heads(t, batch_size), qkv) scores = torch.einsum('bhqd,bhkd->bhqk', q, k) / (self.head_dim ** 0.5) attn_weights = torch.softmax(scores, dim=-1) context = torch.einsum('bhqk,bhvd->bhqv', attn_weights, v).transpose(1, 2).contiguous().view(batch_size, seq_len, -1) partial_context = self.proj(context[:, :seq_len//2]) full_context = torch.cat((partial_context, context[:, seq_len//2:]), dim=1) ffn_output = self.ffn(full_context) return ffn_output ``` 此模块能够显著降低内存消耗,同时保留足够的表达能力。 --- ### 结论 综上所述,在 YOLOv8改进 MSHA 可以从多个角度入手,包括但不限于 NAMA、MSDA 和 PSA 等技术手段。这些方法各有侧重,可根据实际需求灵活组合使用。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Snu77

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

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

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

打赏作者

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

抵扣说明:

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

余额充值