YOLOv9有效提点|加入SE、CBAM、ECA、SimAM等几十种注意力机制(一)


专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!!


一、本文介绍

        本文将以SE注意力机制为例,演示如何在YOLOv9种添加注意力机制!


 《Squeeze-and-Excitation Networks》

        SENet提出了一种基于“挤压和激励”(SE)的注意力模块,用于改进卷积神经网络(CNN)的性能。SE块可以适应地重新校准通道特征响应,通过建模通道之间的相互依赖关系来增强CNN的表示能力。这些块可以堆叠在一起形成SENet架构,使其在多个数据集上具有非常有效的泛化能力。


《CBAM:Convolutional Block Attention Module》

        CBAM模块能够同时关注CNN的通道和空间两个维度,对输入特征图进行自适应细化。这个模块轻量级且通用,可以无缝集成到任何CNN架构中,并可以进行端到端训练。实验表明,使用CBAM可以显著提高各种模型的分类和检测性能。


《ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks》

        通道注意力模块ECA,可以提升深度卷积神经网络的性能,同时不增加模型复杂性。通过改进现有的通道注意力模块,作者提出了一种无需降维的局部交互策略,并自适应选择卷积核大小。ECA模块在保持性能的同时更高效,实验表明其在多个任务上具有优势。


《SimAM: A Simple, Parameter-Free Attention Module for Convolutional Neural Networks》

        SimAM一种概念简单且非常有效的注意力模块。不同于现有的通道/空域注意力模块,该模块无需额外参数为特征图推导出3D注意力权值。具体来说,SimAM的作者基于著名的神经科学理论提出优化能量函数以挖掘神经元的重要性。该模块的另一个优势在于:大部分操作均基于所定义的能量函数选择,避免了过多的结构调整

适用检测目标:   YOLOv9模块通用改进


二、改进步骤

        以下以SE注意力机制为例在YOLOv9中加入注意力代码,其他注意力机制同理!

 2.1 复制代码

        将SE的代码辅助到models包下common.py文件中。

 2.2 修改yolo.py文件

        在yolo.py脚本的第700行(可能因YOLOv9版本变化而变化)增加下方代码。

        elif m in (SE,):args.insert(0, ch[f])

2.3 创建配置文件

        创建模型配置文件(yaml文件),将我们所作改进加入到配置文件中(这一步的配置文件可以复制models  - > detect 下的yaml修改。)。对YOLO系列yaml文件不熟悉的同学可以看我往期的yaml详解教学!

YOLO系列 “.yaml“文件解读-CSDN博客

# YOLOv9
# Powered bu https://blog.csdn.net/StopAndGoyyy
# 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# avg-conv down[-1, 1, ADown, [256]],  # 4-P3/8# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5# avg-conv down[-1, 1, ADown, [512]],  # 6-P4/16# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7# avg-conv down[-1, 1, ADown, [512]],  # 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]],  # 10# 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]],  # 13# 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]],  # 16 (P3/8-small)# avg-conv-down merge[-1, 1, ADown, [256]],[[-1, 13], 1, Concat, [1]],  # cat head P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 19 (P4/16-medium)# avg-conv-down merge[-1, 1, ADown, [512]],[[-1, 10], 1, Concat, [1]],  # cat head P5# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 22 (P5/32-large)# multi-level reversible auxiliary branch# routing[5, 1, CBLinear, [[256]]], # 23[7, 1, CBLinear, [[256, 512]]], # 24[9, 1, CBLinear, [[256, 512, 512]]], # 25# conv down[0, 1, Conv, [64, 3, 2]],  # 26-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 27-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 28# avg-conv down fuse[-1, 1, ADown, [256]],  # 29-P3/8[[23, 24, 25, -1], 1, CBFuse, [[0, 0, 0]]], # 30  # elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 31# avg-conv down fuse[-1, 1, ADown, [512]],  # 32-P4/16[[24, 25, -1], 1, CBFuse, [[1, 1]]], # 33 # elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 34# avg-conv down fuse[-1, 1, ADown, [512]],  # 35-P5/32[[25, -1], 1, CBFuse, [[2]]], # 36# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 37[-1, 1, SE, [16]],  # 38# detection head# detect[[31, 34, 38, 16, 19, 22], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]

3.1 训练过程

        最后,复制我们创建的模型配置,填入训练脚本(train_dual)中(不会训练的同学可以参考我之前的文章。),运行即可。

YOLOv9 最简训练教学!-CSDN博客

​​

​​


SE代码

class SE(nn.Module):def __init__(self, channel, reduction=16):super(SE, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Sequential(nn.Linear(channel, channel // reduction, bias=False),nn.ReLU(),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)

CBAM代码

class CBAMBlock(nn.Module):def __init__(self, channel=512, reduction=16, kernel_size=7):super().__init__()self.ca = ChannelAttention(channel=channel, reduction=reduction)self.sa = SpatialAttention(kernel_size=kernel_size)def init_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):init.kaiming_normal_(m.weight, mode='fan_out')if m.bias is not None:init.constant_(m.bias, 0)elif isinstance(m, nn.BatchNorm2d):init.constant_(m.weight, 1)init.constant_(m.bias, 0)elif isinstance(m, nn.Linear):init.normal_(m.weight, std=0.001)if m.bias is not None:init.constant_(m.bias, 0)def forward(self, x):b, c, _, _ = x.size()out = x * self.ca(x)out = out * self.sa(out)return out

ECA代码

class ECAAttention(nn.Module):def __init__(self, kernel_size=3):super().__init__()self.gap = nn.AdaptiveAvgPool2d(1)self.conv = nn.Conv1d(1, 1, kernel_size=kernel_size, padding=(kernel_size - 1) // 2)self.sigmoid = nn.Sigmoid()def init_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):init.kaiming_normal_(m.weight, mode='fan_out')if m.bias is not None:init.constant_(m.bias, 0)elif isinstance(m, nn.BatchNorm2d):init.constant_(m.weight, 1)init.constant_(m.bias, 0)elif isinstance(m, nn.Linear):init.normal_(m.weight, std=0.001)if m.bias is not None:init.constant_(m.bias, 0)def forward(self, x):y = self.gap(x)  # bs,c,1,1y = y.squeeze(-1).permute(0, 2, 1)  # bs,1,cy = self.conv(y)  # bs,1,cy = self.sigmoid(y)  # bs,1,cy = y.permute(0, 2, 1).unsqueeze(-1)  # bs,c,1,1return x * y.expand_as(x)

SimAM代码

class SimAM(torch.nn.Module):def __init__(self, e_lambda=1e-4):super(SimAM, self).__init__()self.activaton = nn.Sigmoid()self.e_lambda = e_lambdadef __repr__(self):s = self.__class__.__name__ + '('s += ('lambda=%f)' % self.e_lambda)return s@staticmethoddef get_module_name():return "simam"def forward(self, x):b, c, h, w = x.size()n = w * h - 1x_minus_mu_square = (x - x.mean(dim=[2, 3], keepdim=True)).pow(2)y = x_minus_mu_square / (4 * (x_minus_mu_square.sum(dim=[2, 3], keepdim=True) / n + self.e_lambda)) + 0.5return x * self.activaton(y)

如果觉得本文章有用的话给博主点个关注吧!


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

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

相关文章

向上生长笔记

第一章 成为一个很厉害的人(持续输入,反复练习) 为什么要学习及如何学习 1、自毁趋势(熵增),故需要能量输入(负熵流) //引申:水往低处流是趋势,学习是逆趋势。 2、持续输入能量(物质和信息),…

力扣2月最后三天的每日一题

力扣2月最后三天的每日一题 前言2867.统计树中的合法路径数目思路确定1e5中的质数统计每个点的连接情况开始对质数点进行处理完整代码 2673.使二叉树所有路径值相等的最小代价思路完整代码 2581.统计可能的树根数目思路建立连通关系将猜测数组变为哈希表,方便查询利…

七通道NPN 达林顿管GC2003,专为符合标准 TTL 而制造,最高工作电压 50V,耐压 80V

GC2003 内部集成了 7 个 NPN 达林顿晶体管,连接的阵列,非常适合逻辑接口电平数字电路(例 如 TTL,CMOS 或PMOS 上/NMOS)和较高的电流/电压,如电灯电磁阀,继电器,打印机或其他类似的负…

读《代码整洁之道》有感

最近读了一本书,名字大家都看到了:《代码整洁之道》,之前一直只是听说过这本书的大名,却一直没有进行拜读,最近想起来了就想着看一看,不看不要紧,看了之后就像吃了炫迈,根本停不下来…

MATLAB环境下脑电信号EEG的谱分析

脑电信号一直伴随着人类的生命,脑电波是脑神经细胞发生新陈代谢、离子交换时细胞群兴奋突触电位总和,脑电信号的节律性则和丘脑相关,含有丰富的大脑活动信息。通常我们所接触的脑电图都是头皮脑电图,在有些特殊场合还需要皮下部位…

10.广域网技术

1. PPP实验点这里(拓扑代码) 2. PPPoE配置实验点这里(拓扑代码) 目录 一、广域网二、PPP协议三、PPP链路建立过程1-LCP(链路协商)四、PPP链路建立过程2-PAP/CHAP(认证协商,可选&…

python语言1

一、pytho中的注释 1.1注释的理解 程序员在代码中对代码功能解释说明的标注性文字可以提高代码的可读性注释的内容将被python解释器忽略,不被计算机执行 1.2注释的分类 注释分为:单行注释、多行注释、中文声明注释 (1)单行注…

LeetCode240题:搜索二维矩阵II(python3)

代码思路: “根节点” 对应的是矩阵的 “左下角” 和 “右上角” 元素,以 matrix 中的左下角元素为标志数 flag ,则有: 若 flag > target ,则 target 一定在 flag 所在行的上方 ,即 flag 所在行可被消去&#xff0c…

kotlin安卓开发教程视频,2024年Android开发陷入饱和

Android基础 1、什么是ANR 如何避免它? 如果耗时操作需要让用户等待,那么可以在界面上显示进度条。 2、View的绘制流程;自定义View如何考虑机型适配;自定义View的事件 3、分发机制;View和ViewGroup分别有哪些事件分…

【Leetcode每日一刷】贪心算法|122.买卖股票的最佳时机 II、55. 跳跃游戏

一、122.买卖股票的最佳时机 II 力扣题目链接 🦄解题思路: 首先需要明确的几个点: 当前只能有最大一支股票每一天操作只能3选1:买or卖or休息 此外,对于贪心,总有像下面图示的一种直觉:如果…

力扣SQL50 产品销售分析 I 查询

Problem: 1068. 产品销售分析 I 思路 left join on:左连接 Code select p.product_name, s.year, s.price from Sales s left join Product p on s.product_id p.product_id

靠谱的车【华为OD机试-JAVAPythonC++JS】

题目描述 程序员小明打了一辆出租车去上班。出于职业敏感,他注意到这辆出租车的计费表有点问题,总是偏大。 出租车司机解释说他不喜欢数字4,所以改装了计费表,任何数字位置遇到数字4就直接跳过,其余功能都正常。 比如&…

Scaffold 脚手架

Scaffold 脚手架 Scaffold 脚手架组件是一个核心组件,它为开发者提供了一个标准的、可定制的应用界面框架。androidx.compose.material3.Scaffold 包含了应用界面的基础元素,如状态栏、导航栏、顶部应用栏(TopAppBar)等。通过 Sc…

Windows的Docker-Desktop安装与问题总结

目录 Docker-Desktop安装步骤 环境配置 Docker-Desktop安装问题总结 问题1:docker-desktop setting界面一直加载转圈 问题2:docker镜像的存储位置变更(防止C盘空间不足) 参考文献: Docker-Desktop安装步骤 环境…

又挖到宝了!国人团队研发的AI视频工具PixVerse,这么好用居然还完全免费!(强烈推荐)

昨天发了一款国产免费的 AI 绘画工具 Dreamina 的介绍: 居然才发现!字节跳动旗下国产AI绘画工具Dreamina,这么好用居然还免费!(强烈推荐) 发现大家对国产 AI 工具还挺感兴趣的。今天继续帮大家挖国产的 A…

【Leetcode每日一题】二分查找 - 山脉数组的峰顶索引(难度⭐⭐)(23)

1. 题目解析 Leetcode链接:852. 山脉数组的峰顶索引 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 核心在于找到题目中所说的峰值所在的下标并返回他们的下标即可。 2. 算法原理 峰顶及两侧数据特点分析 峰顶数据…

运算放大电路常用接法

1、反相比例运算电路 2、同相比例运算电路 3、电压跟随器 4、反相求和运算电路 5、同相求和运算电路 6、加减运算电路 7、加减电路 8、积分运算电路 9、实用积分电路 10、微分运算电路 11、实用微分电路 12、压控电压源二阶低通滤波器 13、压控电压源二阶高通滤波器 14、RC桥式…

[剪藏] - 尊湃通讯公司窃密曝光,发现绕不过华为

在科技领域风起云涌的今天,一场惊心动魄的窃密事件悄然发生,涉及华为WIFI6芯片技术的商业秘密被窃取,案中主谋竟然是一位曾在华为海思拥有重量级地位的技术大佬。本文将深入挖掘这起事件的来龙去脉,探讨窃密者的背叛和华为的技术守…

公钥密码体制

公钥密码体制 一个系统中,n个用户之间要进行保密通信,为了确保安全性,两两用户之间的密钥不能一样。这种方式下,需要系统提供C2 n=n(n-1)/2把共享密钥。这样密钥的数量就大幅增加了,随之而来的产生、存储、分配、管理密钥的成本也大幅增加。而使用公钥密码体制可以大大减…

深度学习-回顾经典AlexNet网络:山高我为峰

深度学习-回顾经典AlexNet网络之山高我为峰 深度学习中,经典网络引领一波又一波的技术革命,从LetNet到当前最火的GPT所用的Transformer,它们把AI技术不断推向高潮。2012年AlexNet大放异彩,它把深度学习技术引领第一个高峰&#x…