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

  一、本文介绍

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

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

 专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 


目录

  一、本文介绍

二、PSA介绍

三、PSA核心代码 

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

 4.1 修改一

4.2 修改二 

4.3 修改三 

4.4 修改四 

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

5.1 PSA的yaml文件

5.2 训练过程截图 

五、本文总结


二、PSA介绍

论文地址:官方论文地址点击此处即可跳转

代码地址:官方代码地址点击此处即可跳转


自注意力在各种视觉任务中得到了广泛应用,因为它具有显著的全局建模能力。然而,自注意力机制表现出较高的计算复杂度和内存占用。为了解决这个问题,鉴于注意力头冗余的普遍存在,我们提出了一种高效的部分自注意力(PSA)模块设计,如图3(c)所示。

具体来说,我们通过1×1卷积将特征均匀地划分为两部分。然后,我们仅将其中一部分输入到由多头自注意力模块(MHSA)和前馈网络(FFN)组成的NPSA块中。两部分特征随后被连接并通过1×1卷积融合。此外,我们遵循将MHSA中查询和键的维度分配为值的一半,并将LayerNorm替换为BatchNorm以加快推理速度。

PSA仅在分辨率最低的Stage 4之后放置,以避免自注意力二次复杂性带来的过多开销。通过这种方式,可以在低计算成本下将全局表示学习能力引入YOLO模型,从而增强模型能力并提高性能。

通过这些精度驱动的设计,我们能够在不显著增加计算成本的情况下提升YOLO模型的性能。


三、PSA核心代码 

核心代码的使用方式看章节四!

import torch
import torch.nn as nn__all__ = ['PSA']def autopad(k, p=None, d=1):  # kernel, padding, dilation"""Pad to 'same' shape outputs."""if d > 1:k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k]  # actual kernel-sizeif p is None:p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-padreturn pclass Conv(nn.Module):"""Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)."""default_act = nn.SiLU()  # default activationdef __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):"""Initialize Conv layer with given arguments including activation."""super().__init__()self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)self.bn = nn.BatchNorm2d(c2)self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()def forward(self, x):"""Apply convolution, batch normalization and activation to input tensor."""return self.act(self.bn(self.conv(x)))def forward_fuse(self, x):"""Perform transposed convolution of 2D data."""return self.act(self.conv(x))class Attention(nn.Module):def __init__(self, dim, num_heads=8,attn_ratio=0.5):super().__init__()self.num_heads = num_headsself.head_dim = dim // num_headsself.key_dim = int(self.head_dim * attn_ratio)self.scale = self.key_dim ** -0.5nh_kd = nh_kd = self.key_dim * num_headsh = dim + nh_kd * 2self.qkv = Conv(dim, h, 1, act=False)self.proj = Conv(dim, dim, 1, act=False)self.pe = Conv(dim, dim, 3, 1, g=dim, act=False)def forward(self, x):B, _, H, W = x.shapeN = H * Wqkv = self.qkv(x)q, k, v = qkv.view(B, self.num_heads, -1, N).split([self.key_dim, self.key_dim, self.head_dim], dim=2)attn = ((q.transpose(-2, -1) @ k) * self.scale)attn = attn.softmax(dim=-1)x = (v @ attn.transpose(-2, -1)).view(B, -1, H, W) + self.pe(v.reshape(B, -1, H, W))x = self.proj(x)return xclass PSA(nn.Module):def __init__(self, c1, c2, e=0.5):super().__init__()assert (c1 == c2)self.c = int(c1 * e)self.cv1 = Conv(c1, 2 * self.c, 1, 1)self.cv2 = Conv(2 * self.c, c1, 1)self.attn = Attention(self.c, attn_ratio=0.5, num_heads=self.c // 64)self.ffn = nn.Sequential(Conv(self.c, self.c * 2, 1),Conv(self.c * 2, self.c, 1, act=False))def forward(self, x):a, b = self.cv1(x).split((self.c, self.c), dim=1)b = b + self.attn(b)b = b + self.ffn(b)return self.cv2(torch.cat((a, b), 1))


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

 4.1 修改一

第一还是建立文件,我们找到如下yolov9-main/models文件夹下建立一个目录名字呢就是'modules'文件夹(用群内的文件的话已经有了无需新建)!然后在其内部建立一个新的py文件将核心代码复制粘贴进去即可。


4.2 修改二 

第二步我们在该目录下创建一个新的py文件名字为'__init__.py'(用群内的文件的话已经有了无需新建),然后在其内部导入我们的检测头如下图所示。


4.3 修改三 

第三步我门中到如下文件'yolov9-main/models/yolo.py'进行导入和注册我们的模块(用群内的文件的话已经有了无需重新导入直接开始第四步即可)!

从今天开始以后的教程就都统一成这个样子了,因为我默认大家用了我群内的文件来进行修改!!


4.4 修改四 

然后我们找到parse_model方法,按照如下修改->

到此就修改完成了,大家可以复制下面的yaml文件运行。


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

5.1 PSA的yaml文件

此yaml文件使用方法和YOLOv10保持一致,大家如果可以尝试替换更多的Conv!

# YOLOv9# parameters
nc: 80  # number of classes
depth_multiple: 1  # model depth multiple
width_multiple: 1  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()# anchors
anchors: 3# YOLOv9 backbone
backbone:[[-1, 1, Silence, []],# conv down[-1, 1, Conv, [64, 3, 2]],  # 1-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 2-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 3# conv down[-1, 1, Conv, [256, 3, 2]],  # 4-P3/8# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5# conv down[-1, 1, Conv, [512, 3, 2]],  # 6-P4/16# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7# conv down[-1, 1, Conv, [512, 3, 2]],  # 8-P5/32# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 9]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 11[-1, 1, PSA, [512]],  # 添加一行我们的改进机制# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 7], 1, Concat, [1]],  # cat backbone P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 14# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 5], 1, Concat, [1]],  # cat backbone P3# elan-2 block[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]],  # 17 (P3/8-small)# conv-down merge[-1, 1, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]],  # cat head P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 20 (P4/16-medium)# conv-down merge[-1, 1, Conv, [512, 3, 2]],[[-1, 11], 1, Concat, [1]],  # cat head P5# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 23 (P5/32-large)# routing[5, 1, CBLinear, [[256]]], # 24[7, 1, CBLinear, [[256, 512]]], # 25[9, 1, CBLinear, [[256, 512, 512]]], # 26# conv down[0, 1, Conv, [64, 3, 2]],  # 27-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 28-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 29# conv down fuse[-1, 1, Conv, [256, 3, 2]],  # 30-P3/8[[24, 25, 26, -1], 1, CBFuse, [[0, 0, 0]]], # 31# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 32# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 33-P4/16[[25, 26, -1], 1, CBFuse, [[1, 1]]], # 34# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 35# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 36-P5/32[[26, -1], 1, CBFuse, [[2]]], # 37# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 38# detect[[32, 35, 38, 17, 20, 23], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]


5.2 训练过程截图 


五、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv9改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

 专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/21982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【iOS】Runtime

文章目录 前言一、Runtime简介二、NSObject库起源isaisa_t结构体cache_t的具体实现class_data_bits_t的具体实现 三、[self class] 与 [super class]四、消息发送与转发五、Runtime应用场景 前言 之前分part学习了Runtime的内容,但是没有系统的总结,这篇…

网络工程师----第四十七天

1、请简述super vlan和sub vlan的区别? 2、请简述mux vlan 中不同vlan的特点? 3、请基于工作原理简述GVRP协议中三种接口模式的特点? 4、请简述STP的选举过程? 5、两台交换机在不增加成本的情况下为提高链路带宽和可靠性采用链路聚…

网络原理——HTTP/HTTPS ---- HTTPS

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 目录 HTTPS加密与解密HTTPS的工作流程使用对称密钥来加密使用非对称密钥 来对 对称密钥进行加密第三方公证总结 HTTPS https本质上就是在http的基础之上 增加了加密层,抛开加密层之后,剩下的部…

号称超级增程电动,领克07EM-P带来技术变革?

近年来,自主品牌在新能源汽车领域百花齐放,尤其是在混合动力市场上,比亚迪的DM-i技术引领了风潮,秦L的一经亮相,整个车圈都沸腾了,“超级混动”的概念深入人心。 各大自主品牌都有了自己的混动平台和技术。…

使用import语句导入模块

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 创建模块后,就可以在其他程序中使用该模块了。要使用模块需要先以模块的形式加载模块中的代码,这可以使用import语句实现。im…

步进电机双闭环细分控制(matlab仿真)内含课设等参考文件

1.1 步进电机工作原理 步进电机是一种用电脉冲进行控制,将电脉冲信号转换成相位移的电机,其机械位移和转速分别与输入电机绕组的脉冲个数和脉冲频率成正比,每一个脉冲信号可使步进电机旋转一个固定的角度。脉冲的数量决定了旋转的总角度,脉…

(ICLR,2024)HarMA:高效的协同迁移学习与模态对齐遥感技术

文章目录 相关资料摘要引言方法多模态门控适配器目标函数 实验 相关资料 论文:Efficient Remote Sensing with Harmonized Transfer Learning and Modality Alignment 代码:https://github.com/seekerhuang/HarMA 摘要 随着视觉和语言预训练&#xf…

seRsync + Rsync 实时同步

文章目录 1,结构图2,节点A2.1 安装rsync2.2 安装seRsync2.3, 创建seRsync的守护进程用systemd管理并启动2.4,上传rsync.pass密码文件到配置文件目录:/etc/2.5 ,重新加载systemd,启动sersyncd守护…

React路由学习

官方文档:https://reactrouter.com/en/main 学习时以Tutorial(教程)为主 一、创建项目 //创建项目 npm create vitelatest [项目名] -- --template react//安装react-router cd [项目名] npm i react-router-dom localforage match-sorter…

从关键新闻和最新技术看AI行业发展(2024.5.20-6.2第二十四期) |【WeThinkIn老实人报】

写在前面 【WeThinkIn老实人报】旨在整理&挖掘AI行业的关键新闻和最新技术,同时Rocky会对这些关键信息进行解读,力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的优化建议,一起交流学习💪 欢迎大家关注Rocky的公众号&…

使用Xshell一键在多个会话中执行多个命令

背景 平时在工作中经常通过ssh远程操作Linux,由于我们负责的服务部署在超过5台服务器(相同的代码及路径),每次发布后执行重启都得重复操作5次关闭、检查、启动、查看日志,特别繁琐。 后来发现Xshell 7可以录制脚本&am…

大模型时代的具身智能系列专题(十一)

UMass Amherst 淦创团队 淦创是马萨诸塞大学阿默斯特分校的一名教员,也是麻省理工学院- ibm沃森人工智能实验室的研究经理。在麻省理工学院博士后期间,和Antonio Torralba教授、Daniela Rus教授和Josh Tenenbaum教授一起工作。在此之前,在清…

Ai绘画工具Stable Diffusion,手把手教你训练你的专属Lora模型,神级教程建议收藏!

哈喽,大家好,我是设计师阿威。 今天给大家带来的是Stable Diffusion训练Lora的教程,希望对大家有帮助。 一、硬件要求 我们知道Stable Diffusion WebUI对显卡要求比较高,同样Lora训练对显卡要求更高,所以要想训练一…

【Endnote】如何在word界面加载Endnote

如何在word界面加载Endnote 方法1:方法2:从word入手方法3:从CWYW入手参考 已下载EndNote,但Word中没有显示EndNote,应如何加载显示呢? 方法1: 使用EndNote的Configure EndNote.exe 。 具体步骤为&#x…

通过异步请求上传文件到七牛云

一、准备工作 创建账号、创建空间这种大家自己研究就行(有手就行) 只需要根据步骤查找对应文档 从服务端获取七牛云上传的token,生成token参考官方文档 在七牛云文档查找上传的存储区域 在七牛云控制台找到空间管理的cdn加速域名 二、后台token获取 基于准备工作1中&…

将 KNX 接入 Home Assistant 之三 功能配置

万事俱备只欠东风,不管是ETS还是HA都需要配置才能使用。还是期待以后发展到可以开箱即用。 KNXD的配置 在 《将 KNX 接入 Home Assistant 之二 准备软件》,我们已经装好了KNXD的插件,现在就需要进行配置了 配置的界面 注意图中加框的选择&…

UI 自动化测试(Selenuim + Java )

关于 UI 自动化测试工具 selenuim Java 的环境搭建推荐看SeleniumJava 环境搭建 什么是自动化测试? 自动化测试指软件测试的自动化,在预设状态下运行应用程序或者系统,预设条件包括正常和异常,最后评估运行结果。将人为驱动的测…

分享两种论文降重最有效的方法(论文降重网站)

论文降重最有效的方法可以分为手动方法和使用降重网站两种方法。以下是详细的分析和归纳: 手动方法 删减冗余内容:对于论文中的某些内容,特别是信息冗余或不必要的描述,可以通过删减和简化来减少篇幅。确保每一段落和每一个例子都…

[FreeRTOS 基础知识] 栈

文章目录 栈的概念使用C语言实现 栈通过代码反汇编解析 栈 栈的概念 所谓的栈就是一块空间的内存,CPU的SP寄存器指向它,它可以用于函数调用,局部变量,多任务系统里保存现场。 使用C语言实现 栈 volatile int num0;int fun_b(vol…

i.MX8MP平台开发分享(RDC资源分配控制器篇)

1.spec RDC 配置信息被发送到结构端口、内存垫片、信号控制器和外设,以根据域分配控制访问。 结构使用与每个端口相关的域标识符,将此信息与总线事务一起包含在内。当从属加密垫圈遇到总线事务时,它会将事务域 ID 与 RDC 提供的允许域列表进…