YOLOv8 C2f模块融合shuffleAttention注意力机制

news2025/1/8 0:45:36

1. 引言

1.1YOLOv8直接添加注意力机制

yolov8添加注意力机制是一个非常常见的操作,常见的操作直接将注意力机制添加至YOLOv8的某一层之后,这种改进特别常见。
示例如下:
新版yolov8添加注意力机制(以NAMAttention注意力机制为例)
YOLOv8添加注意力机制(ShuffleAttention为例)


知网上常见的添加注意力机制的论文均使用的上述方式。
下面展示一种将注意力机制融合至模块中的方法。

1.2 YOLOv8 C2f融合注意力机制

C2f模块融合注意力机制,而不是直接放置在某一层后面。
示例如下:
YOLOv8将注意力机制融合进入C2f模块(SE注意力机制为例)


以及本篇shuffleAttention注意力机制。

1.3常见注意力机制

以下是一些常见的注意力机制实现的代码,具体看此贴。
常见注意力机制代码实现

2. 实验

2.1 ShuffleAttention

Shuffle注意力机制,代码如下:

class ShuffleAttention(nn.Module):

    def __init__(self, channel=512, reduction=16, G=8):
        super().__init__()
        self.G = G
        self.channel = channel
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.gn = nn.GroupNorm(channel // (2 * G), channel // (2 * G))
        self.cweight = Parameter(torch.zeros(1, channel // (2 * G), 1, 1))
        self.cbias = Parameter(torch.ones(1, channel // (2 * G), 1, 1))
        self.sweight = Parameter(torch.zeros(1, channel // (2 * G), 1, 1))
        self.sbias = Parameter(torch.ones(1, channel // (2 * G), 1, 1))
        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)

    @staticmethod
    def channel_shuffle(x, groups):
        b, c, h, w = x.shape
        x = x.reshape(b, groups, -1, h, w)
        x = x.permute(0, 2, 1, 3, 4)

        # flatten
        x = x.reshape(b, -1, h, w)

        return x

    def forward(self, x):
        b, c, h, w = x.size()
        # group into subfeatures
        x = x.view(b * self.G, -1, h, w)  # bs*G,c//G,h,w

        # channel_split
        x_0, x_1 = x.chunk(2, dim=1)  # bs*G,c//(2*G),h,w

        # channel attention
        x_channel = self.avg_pool(x_0)  # bs*G,c//(2*G),1,1
        x_channel = self.cweight * x_channel + self.cbias  # bs*G,c//(2*G),1,1
        x_channel = x_0 * self.sigmoid(x_channel)

        # spatial attention
        x_spatial = self.gn(x_1)  # bs*G,c//(2*G),h,w
        x_spatial = self.sweight * x_spatial + self.sbias  # bs*G,c//(2*G),h,w
        x_spatial = x_1 * self.sigmoid(x_spatial)  # bs*G,c//(2*G),h,w

        # concatenate along channel axis
        out = torch.cat([x_channel, x_spatial], dim=1)  # bs*G,c//G,h,w
        out = out.contiguous().view(b, -1, h, w)

        # channel shuffle
        out = self.channel_shuffle(out, 2)
        return out

可以将以上注意力机制的代码放到ultralytics/nn/modules/conv.py目录的最后。

2.2 模块添加

ShuffleAttention_Bottleneck和C2f_ShuffleAttention模块代码如下:

class ShuffleAttention_Bottleneck(nn.Module):
    def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):
        super().__init__()
        c_ = int(c2 * e)
        self.cv1 = Conv(c1, c_, k[0], 1)
        self.cv2 = Conv(c_, c2, k[1], 1, g=g)
        self.se = ShuffleAttention(c2, 16, 8)
        self.add = shortcut and c1 == c2

    def forward(self, x):
        return x + self.se(self.cv2(self.cv1(x))) if self.add else self.se(self.cv2(self.cv1(x)))


class C2f_ShuffleAttention(nn.Module):
    def __init__(self, c1, c2, shortcut = False, g = 1, n = 1, e = 0.5):
        super().__init__()
        self.c = int(c2 * e)
        self.cv1 = Conv(c1, 2 * self.c, 1, 1)
        self.cv2 = Conv((2 + n) * self.c, c2, 1)
        self.m = nn.ModuleList(ShuffleAttention_Bottleneck(self.c, self.c, shortcut, g, k=((3,3),(3,3)), e = 1.0) for _ in range(n))
   	def forward(self, x):
        y = list(self.cv1(x).chunk(2,1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))
    def forward_split(self, x):
        y = list(self.cv1(x).split((self.c, self.c), 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))

可以将以上ShuffleAttention_Bottleneck和C2f_ShuffleAttention模块的代码放到ultralytics/nn/modules/conv.py目录的最后。


在ultralytics/nn/modules/conv.py文件的最前面添加C2f_ShuffleAttention。
在这里插入图片描述
在ultralytics/nn/modules/ __ init__.py中,添加C2f_ShuffleAttention模块。
在这里插入图片描述

2.3 task.py改写

在ultralytics/nn/tasks.py中,在parse_model(d, ch, verbose=True)方法中,添加C2f_ShuffleAttention即可。
保持与C2f的调用一样。
在这里插入图片描述

2.4 模型改写

创建模块:ultralytics/cfg/models/v8/yolov8n-C2f_ShuffleAttention.yaml,以yolov8n为例:修改后的模型如下:

 # Ultralytics YOLO 🚀, GPL-3.0 license

# Parameters
nc: 1  # number of classes
depth_multiple: 0.33  # scales module repeats
width_multiple: 0.25  # scales convolution channels

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4
  - [-1, 3, C2f_ShuffleAttention, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f_ShuffleAttention, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f_ShuffleAttention, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f_ShuffleAttention, [1024, True]]
  - [-1, 1, SPPF, [1024, 5]]  # 9


# YOLOv8.0n head
head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [512]]  # 12

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)

  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)

也可以尝试不替换backbone中的C2f模块而替换head模块中的某些模块。

3.运行截图

模型运行图片如下
在这里插入图片描述
没有报错
在这里插入图片描述

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

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

相关文章

jsonlite库

jsonlite是一个R语言中用于处理JSON数据的库。它提供了一组简单而强大的函数,用于解析、生成和转换JSON数据。 使用jsonlite库,您可以轻松地将JSON数据解析为R语言中的数据结构,如列表或数据框。您还可以将R语言中的数据结构转换为JSON格式&…

解决vue3父组件执行子组件方法报错:TypeError: Cannot read properties of null

现象: 父组件执行子组件的代码: 原因: Vue3使用的所有变量除了来自父组件传值的props以外,其他的html绑定的所有本地变量都必须通过return导出! 这一点是vue3 最坑爹的一点。很容易忘记。 解决办法:使用t…

世界500强通信巨头全面推进SDLC,打造高质量的数字解决方案

某通信巨头是世界500强企业,全球领先的信息与通信技术解决方案供应商。多年来,该公司在数字化领域一直走在前列,打造了大量数字化创新解决方案和成功案例,助力合作伙伴更好地理解和应用数字化技术,实现自身的发展和价值…

c语言 简单认识 指针和结构体

指针 代码 #include <stdio.h>int main(){int a 10;//指针类型需要与变量的类型相同&#xff0c;且后面需要添加一个*符号&#xff08;注意这里不是乘法运算&#xff09;表示是对于类型的指针int * p &a; //这里的&并不是进行按位与运算&#xff0c;而是取…

Kubernetes 的四个网络挑战

Kubernetes 的主要职责之一是在应用程序之间共享节点。由于这些应用程序需要相互通信并与外部世界通信&#xff0c;因此网络是一个基本的需求。 Kubernetes 托管的分布式应用程序架构 来自 Kubernetes 集群外部的请求通常通过负责将它们代理到适当服务的路由器或 API 网关进行…

mac安装python3

文章目录 1. 安装1.1 brew安装&#xff08;失败&#xff09;2. 下载安装包 2. 查看版本3. 配置 1. 安装 1.1 brew安装&#xff08;失败&#xff09; brew install python3下载完成后报错&#xff1a;Error: python3.10: unknown or unsupported macOS version: :dunno 解决&a…

边缘计算助力低速无人驾驶驶入多场景落地快车道

自动驾驶刮起的风&#xff0c;如今正吹向低速无人驾驶赛道。近期不完全统计显示&#xff0c;当前A股及港股正在排队IPO的自动驾驶相关企业共有12家&#xff0c;其中实现盈利的企业仅两家&#xff0c;而且实现盈利的两家企业最主要的收入并不完全源于自动驾驶领域。 相比之下&am…

微信小程序webview中嵌套uniapp时的文件下载问题

文章目录 背景解决方案一、思路二、引入依赖三、H5端代码四、微信小程序端代码 效果图参考 前往闪闪の小窝以获得更好的阅读和评论体验 背景 这个标题就已经够抽象了吧 本来用微信小程序的web-view去嵌套h5已经因为微信的种种限制&#xff08;微信不希望你把微信小程序当做一…

五、计算机网络

&#xff08;一&#xff09;OSI/RM 七层模型 七层模型是计算机网络的基石&#xff0c;整个计算机网络是构建与七层模型之上的。 在数据链路层&#xff0c;数据开始以帧为单位&#xff0c;网卡的 MAC 地址就是数据帧的地址&#xff0c;数据的传输开始有地址了。 局域网是工作…

3.JMeter高级使用-让你与众不同

概述 今日目标&#xff1a; 插件下载与安装Basic Graphs 主要点 Average Response Time 平均响应时间Active Threads 活动线程数Successful/Failed Transactions 成功/失败 事务数 Additional Graphs 主要点 Response Codes 响应码Bytes Throughput 吞吐量Connect Times 连接…

【C++】类与对象 第三篇(初始化列表,explicit,static,友元,内部类)

再谈构造函数 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数给对象各个成员变量一个合适的初始值 class Date{public:Date(int year, int month, int day){_year year;_month month;_day day;}​private:int _year;int _month;int _day;}; 虽然上述…

成语猜猜猜小程序源码系统 自带流量主功能帮你赚钱,带完整搭建教程

今天来给大家介绍一款成语猜猜猜小程序源码系统 。随着小程序生态的日益繁荣&#xff0c;越来越多的人开始关注小程序的开发和运营。成语猜猜猜作为一种具有趣味性和知识性的游戏形式&#xff0c;在小程序领域中备受欢迎。因此&#xff0c;开发一个成语猜猜猜小程序源码系统&am…

轻松理解 Transformers (3): Feed-Forward Layer部分

编者按&#xff1a;随着人工智能技术的不断发展Transformer架构已经成为了当今最为热门的话题之一。前馈层作为Transformer架构中的重要组成部分&#xff0c;其作用和特点备受关注。本文通过浅显易懂的语言和生活中的例子&#xff0c;帮助读者逐步理解Transformers中的前馈层。…

信息科技风险管理:合规管理、技术防控与数字化

信息科技对金融业务发展所起的作用是举足轻重的。近年来&#xff0c;金融机构在战略规划中相继引入科技引领的概念。作为金融机构信息科技从业人员&#xff0c;我们笃信信息科技是一个非常有用的工具&#xff0c;一个兼具产品思维和管理思维、拥有高质增效能力的工具。 这个工…

C语言 每日一题 PTA 11.6 day10

1.调和平均 N 个正数的算数平均是这些数的和除以 N&#xff0c;它们的调和平均是它们倒数的算数平均的倒数。 本题就请你计算给定的一系列正数的调和平均值。 输入格式&#xff1a; 每个输入包含 1 个测试用例。每个测试用例第 1 行给出正整数 N(≤1000)&#xff1b;第 2 行给…

c语言 结构体 简单实例

结构体 简单例子 要求&#xff1a; 结构体保存学生信息操作 代码 #include <stdio.h>//定义结构体 struct student{int ID;char name[20];char sex;char birthday[8];int grade; };int main(){int number;printf("请输入学生个数&#xff1a;");scanf(&quo…

SpringBoot内容协商(简单使用、源码解读、默认Converters、自定义Converters)

目录 1. 内容协商1.1 简单使用1.2 源码解读1.3 WebMvcAutoConfiguration提供几种默认HttpMessageConverters1.4 自定义HttpMessageConverter支持yaml格式输出 1. 内容协商 1.1 简单使用 一套系统适配多端数据返回 基于请求头内容协商&#xff1a;&#xff08;默认开启&#x…

学习笔记|秩相关分析|Spearman相关分析|Kendall相关分析|规范表达|《小白爱上SPSS》课程:SPSS第十九讲:秩相关分析怎么做?

目录 学习目的软件版本原始文档秩相关分析一、实战案例二、统计策略三、SPSS操作四、结果解读五、规范表达1、规范图表2、规范文字 六、划重点&#xff1a; 学习目的 SPSS第十九讲&#xff1a;秩相关分析怎么做&#xff1f; 软件版本 IBM SPSS Statistics 26。 原始文档 《…

DC电源模块隔离电路的影响

BOSHIDA DC电源模块隔离电路的影响 DC电源模块隔离电路是电子设备中常用的一种电路。它的作用是在设备中两个电路之间建立一定的隔离&#xff0c;以保证两个电路之间不会传递电流或信号。这种隔离电路的影响可以从以下几个方面来分析。 首先&#xff0c;隔离电路可以提高安全性…

人工智能:一种现代的方法 第二章 智能体

文章目录 前言人工智能&#xff1a;一种现代的方法 第二章 智能体2.1 环境与智能体2.2 理性概念2.3环境的性质2.3.1任务环境的规范描述&#xff1a;PEAS2.3.2环境的性质 2.4智能体结构 前言 本章属于本书的开篇&#xff0c;有两个不便于理解的地方一是讲述的概念过于抽象&…