YOLO11改进|卷积篇|RFAConv创新空间注意力和标准卷积操作

在这里插入图片描述

目录

    • 一、RFAConv卷积
      • 1.1RFAConv卷积介绍
      • 1.2RFAConv核心代码
    • 五、添加RFAConv卷积
      • 5.1STEP1
      • 5.2STEP2
      • 5.3STEP3
      • 5.4STEP4
    • 六、yaml文件与运行
      • 6.1yaml文件
      • 6.2运行成功截图

一、RFAConv卷积

1.1RFAConv卷积介绍

在这里插入图片描述
RFAConv卷积操作提出了一种融合了空间注意力机制和标准卷积操作的新型卷积单元。它的设计旨在提升模型在捕捉空间上下文信息时的表现,同时保留传统卷积操作的高效性。
RFAConv 的工作原理

  1. 随机特征聚合(Random Feature Aggregation)
    RFAConv 在卷积操作中引入了随机特征聚合的概念。这意味着,卷积核在每次执行卷积操作时,不会像传统卷积那样固定地使用每个输入通道中的所有特征。相反,它会随机选择一部分输入特征图进行卷积,这种随机选择增强了模型对输入数据的多样性和随机变化的适应性。

  2. 空间注意力机制(Spatial Attention Mechanism)
    RFAConv 融合了空间注意力机制,旨在增强网络对空间位置的关注。传统的卷积操作是平等地处理所有输入特征位置,而 RFAConv 的空间注意力机制允许网络重点关注那些对当前任务(例如目标检测或分类)最为重要的位置。通过这种方式,RFAConv 能够有效过滤掉冗余信息,专注于更具信息量的特征区域。

  3. 标准卷积操作的改进
    RFAConv 依然保持了标准卷积操作的基本架构,但通过引入上述两种创新,提升了模型对空间关系的建模能力,同时不会大幅增加计算开销。这种结构既保持了传统卷积的效率,又增强了其在复杂场景下的表达能力。
    RFAConv卷积的结构图如下
    在这里插入图片描述

1.2RFAConv核心代码


import torch
from torch import nn
from einops import rearrangeclass RFAConv(nn.Module): # 基于Group Conv实现的RFAConvdef __init__(self,in_channel,out_channel,kernel_size=3,stride=1):super().__init__()self.kernel_size = kernel_sizeself.get_weight = nn.Sequential(nn.AvgPool2d(kernel_size=kernel_size, padding=kernel_size // 2, stride=stride),nn.Conv2d(in_channel, in_channel * (kernel_size ** 2), kernel_size=1, groups=in_channel,bias=False))self.generate_feature = nn.Sequential(nn.Conv2d(in_channel, in_channel * (kernel_size ** 2), kernel_size=kernel_size,padding=kernel_size//2,stride=stride, groups=in_channel, bias=False),nn.BatchNorm2d(in_channel * (kernel_size ** 2)),nn.ReLU())self.conv = nn.Sequential(nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, stride=kernel_size),nn.BatchNorm2d(out_channel),nn.ReLU())def forward(self,x):b,c = x.shape[0:2]weight =  self.get_weight(x)h,w = weight.shape[2:]weighted = weight.view(b, c, self.kernel_size ** 2, h, w).softmax(2)  # b c*kernel**2,h,w ->  b c k**2 h w feature = self.generate_feature(x).view(b, c, self.kernel_size ** 2, h, w)  #b c*kernel**2,h,w ->  b c k**2 h w   获得感受野空间特征weighted_data = feature * weightedconv_data = rearrange(weighted_data, 'b c (n1 n2) h w -> b c (h n1) (w n2)', n1=self.kernel_size, # b c k**2 h w ->  b c h*k w*kn2=self.kernel_size)return self.conv(conv_data)class RFAConv_U(nn.Module): # 基于Unfold实现的RFAConvdef __init__(self, in_channel, out_channel, kernel_size=3):super().__init__()self.kernel_size = kernel_sizeself.unfold = nn.Unfold(kernel_size=(kernel_size, kernel_size), padding=kernel_size // 2)self.get_weights = nn.Sequential(nn.Conv2d(in_channel * (kernel_size ** 2), in_channel * (kernel_size ** 2), kernel_size=1,groups=in_channel),nn.BatchNorm2d(in_channel * (kernel_size ** 2)))self.conv = nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, padding=0, stride=kernel_size)self.bn = nn.BatchNorm2d(out_channel)self.act = nn.ReLU()def forward(self, x):b, c, h, w = x.shapeunfold_feature = self.unfold(x)  # 获得感受野空间特征  b c*kernel**2,h*wx = unfold_featuredata = unfold_feature.unsqueeze(-1)weight = self.get_weights(data).view(b, c, self.kernel_size ** 2, h, w).permute(0, 1, 3, 4, 2).softmax(-1)weight_out = rearrange(weight, 'b c h w (n1 n2) -> b c (h n1) (w n2)', n1=self.kernel_size, n2=self.kernel_size) # b c h w k**2 -> b c h*k w*kreceptive_field_data = rearrange(x, 'b (c n1) l -> b c n1 l', n1=self.kernel_size ** 2).permute(0, 1, 3, 2).reshape(b, c, h, w, self.kernel_size ** 2) # b c*kernel**2,h*w ->  b c h w k**2data_out = rearrange(receptive_field_data, 'b c h w (n1 n2) -> b c (h n1) (w n2)', n1=self.kernel_size,n2=self.kernel_size) # b c h w k**2 -> b c h*k w*kconv_data = data_out * weight_outconv_out = self.conv(conv_data)return self.act(self.bn(conv_out))class SE(nn.Module):def __init__(self, in_channel, ratio=16):super(SE, self).__init__()self.gap = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Sequential(nn.Linear(in_channel, ratio, bias=False),  # 从 c -> c/rnn.ReLU(),nn.Linear(ratio, in_channel, bias=False),  # 从 c/r -> cnn.Sigmoid())def forward(self, x):b, c= x.shape[0:2]y = self.gap(x).view(b, c)y = self.fc(y).view(b, c,1, 1)return yclass RFCBAMConv(nn.Module):def __init__(self,in_channel,out_channel,kernel_size=3,stride=1,dilation=1):super().__init__()if kernel_size % 2 == 0:assert("the kernel_size must be  odd.")self.kernel_size = kernel_sizeself.generate = nn.Sequential(nn.Conv2d(in_channel,in_channel * (kernel_size**2),kernel_size,padding=kernel_size//2,stride=stride,groups=in_channel,bias =False),nn.BatchNorm2d(in_channel * (kernel_size**2)),nn.ReLU())self. get_weight = nn.Sequential(nn.Conv2d(2,1,kernel_size=3,padding=1,bias=False),nn.Sigmoid())self.se =  SE(in_channel)self.conv = nn.Sequential(nn.Conv2d(in_channel,out_channel,kernel_size,stride=kernel_size),nn.BatchNorm2d(out_channel),nn.ReLU())def forward(self,x):b,c = x.shape[0:2]channel_attention =  self.se(x)generate_feature = self.generate(x)h,w = generate_feature.shape[2:]generate_feature = generate_feature.view(b,c,self.kernel_size**2,h,w)generate_feature = rearrange(generate_feature, 'b c (n1 n2) h w -> b c (h n1) (w n2)', n1=self.kernel_size,n2=self.kernel_size)unfold_feature = generate_feature * channel_attentionmax_feature,_ = torch.max(generate_feature,dim=1,keepdim=True)mean_feature = torch.mean(generate_feature,dim=1,keepdim=True)receptive_field_attention = self.get_weight(torch.cat((max_feature,mean_feature),dim=1))conv_data = unfold_feature  * receptive_field_attentionreturn self.conv(conv_data)class h_sigmoid(nn.Module):def __init__(self, inplace=True):super(h_sigmoid, self).__init__()self.relu = nn.ReLU6(inplace=inplace)def forward(self, x):return self.relu(x + 3) / 6class h_swish(nn.Module):def __init__(self, inplace=True):super(h_swish, self).__init__()self.sigmoid = h_sigmoid(inplace=inplace)def forward(self, x):return x * self.sigmoid(x)class RFCAConv(nn.Module):def __init__(self, inp, oup,kernel_size,stride, reduction=32):super(RFCAConv, self).__init__()self.kernel_size = kernel_sizeself.generate = nn.Sequential(nn.Conv2d(inp,inp * (kernel_size**2),kernel_size,padding=kernel_size//2,stride=stride,groups=inp,bias =False),nn.BatchNorm2d(inp * (kernel_size**2)),nn.ReLU())self.pool_h = nn.AdaptiveAvgPool2d((None, 1))self.pool_w = nn.AdaptiveAvgPool2d((1, None))mip = max(8, inp // reduction)self.conv1 = nn.Conv2d(inp, mip, kernel_size=1, stride=1, padding=0)self.bn1 = nn.BatchNorm2d(mip)self.act = h_swish()self.conv_h = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)self.conv_w = nn.Conv2d(mip, inp, kernel_size=1, stride=1, padding=0)self.conv = nn.Sequential(nn.Conv2d(inp,oup,kernel_size,stride=kernel_size))def forward(self, x):b,c = x.shape[0:2]generate_feature = self.generate(x)h,w = generate_feature.shape[2:]generate_feature = generate_feature.view(b,c,self.kernel_size**2,h,w)generate_feature = rearrange(generate_feature, 'b c (n1 n2) h w -> b c (h n1) (w n2)', n1=self.kernel_size,n2=self.kernel_size)x_h = self.pool_h(generate_feature)x_w = self.pool_w(generate_feature).permute(0, 1, 3, 2)y = torch.cat([x_h, x_w], dim=2)y = self.conv1(y)y = self.bn1(y)y = self.act(y) h,w = generate_feature.shape[2:]x_h, x_w = torch.split(y, [h, w], dim=2)x_w = x_w.permute(0, 1, 3, 2)a_h = self.conv_h(x_h).sigmoid()a_w = self.conv_w(x_w).sigmoid()return self.conv(generate_feature * a_w * a_h)

五、添加RFAConv卷积

5.1STEP1

首先找到ultralytics/nn文件路径下新建一个Add-module的python文件包【这里注意一定是python文件包,新建后会自动生成_init_.py】,如果已经跟着我的教程建立过一次了可以省略此步骤,随后新建一个MLCA.py文件并将上文中提到的注意力机制的代码全部粘贴到此文件中,如下图所示
在这里插入图片描述

5.2STEP2

在STEP1中新建的_init_.py文件中导入增加改进模块的代码包如下图所示
在这里插入图片描述

5.3STEP3

找到ultralytics/nn文件夹中的task.py文件,在其中按照下图添加在这里插入图片描述

5.4STEP4

定位到ultralytics/nn文件夹中的task.py文件中的def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)函数添加如图代码,【如果不好定位可以直接ctrl+f搜索定位】

在这里插入图片描述

六、yaml文件与运行

6.1yaml文件

在这里RFAConv其实相当于一个注意力机制,由于YOLO11主要创新点就是C3k2注意力机制,因此不建议使用RFAConv替换,主要使用RFCAConv和RFVBAMConv两个卷积来进行改进
yaml文件1

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLO11 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolo11n.yaml' will call yolo11.yaml with scale 'n'# [depth, width, max_channels]n: [0.50, 0.25, 1024] # summary: 319 layers, 2624080 parameters, 2624064 gradients, 6.6 GFLOPss: [0.50, 0.50, 1024] # summary: 319 layers, 9458752 parameters, 9458736 gradients, 21.7 GFLOPsm: [0.50, 1.00, 512] # summary: 409 layers, 20114688 parameters, 20114672 gradients, 68.5 GFLOPsl: [1.00, 1.00, 512] # summary: 631 layers, 25372160 parameters, 25372144 gradients, 87.6 GFLOPsx: [1.00, 1.50, 512] # summary: 631 layers, 56966176 parameters, 56966160 gradients, 196.0 GFLOPs# YOLO11n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, RFCAConv, [128, 3, 2]] # 1-P2/4- [-1, 2, C3k2, [256, False, 0.25]]- [-1, 1, RFCAConv, [256, 3, 2]] # 3-P3/8- [-1, 2, C3k2, [512, False, 0.25]]- [-1, 1, RFCAConv, [512, 3, 2]] # 5-P4/16- [-1, 2, C3k2, [512, True]]- [-1, 1, RFCAConv, [1024, 3, 2]] # 7-P5/32- [-1, 2, C3k2, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9- [-1, 2, C2PSA, [1024]] # 10# YOLO11n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 2, C3k2, [512, False]] # 13- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 2, C3k2, [256, False]] # 16 (P3/8-small)- [-1, 1, RFCAConv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 2, C3k2, [512, False]] # 19 (P4/16-medium)- [-1, 1, RFCAConv, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 2, C3k2, [1024, True]] # 22 (P5/32-large)- [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)

yaml文件2

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLO11 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolo11n.yaml' will call yolo11.yaml with scale 'n'# [depth, width, max_channels]n: [0.50, 0.25, 1024] # summary: 319 layers, 2624080 parameters, 2624064 gradients, 6.6 GFLOPss: [0.50, 0.50, 1024] # summary: 319 layers, 9458752 parameters, 9458736 gradients, 21.7 GFLOPsm: [0.50, 1.00, 512] # summary: 409 layers, 20114688 parameters, 20114672 gradients, 68.5 GFLOPsl: [1.00, 1.00, 512] # summary: 631 layers, 25372160 parameters, 25372144 gradients, 87.6 GFLOPsx: [1.00, 1.50, 512] # summary: 631 layers, 56966176 parameters, 56966160 gradients, 196.0 GFLOPs# YOLO11n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, RFCBAMConv, [128, 3, 2]] # 1-P2/4- [-1, 2, C3k2, [256, False, 0.25]]- [-1, 1, RFCBAMConv, [256, 3, 2]] # 3-P3/8- [-1, 2, C3k2, [512, False, 0.25]]- [-1, 1, RFCBAMConv, [512, 3, 2]] # 5-P4/16- [-1, 2, C3k2, [512, True]]- [-1, 1, RFCBAMConv, [1024, 3, 2]] # 7-P5/32- [-1, 2, C3k2, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9- [-1, 2, C2PSA, [1024]] # 10# YOLO11n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 2, C3k2, [512, False]] # 13- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 2, C3k2, [256, False]] # 16 (P3/8-small)- [-1, 1, RFCBAMConv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 2, C3k2, [512, False]] # 19 (P4/16-medium)- [-1, 1, RFCBAMConv, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 2, C3k2, [1024, True]] # 22 (P5/32-large)- [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)

6.2运行成功截图

在这里插入图片描述
以上添加位置仅供参考,具体添加位置与效果以自己的数据集结果为准

OK 以上就是添加RFAConv卷积的全部过程了,后续将持续更新尽情期待

在这里插入图片描述

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

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

相关文章

使用WPF实现一个快速切换JDK版本的客户端工具

发现网上一键切换JDK环境的方法都是在mac或Linux下的,本人主力电脑是Windows,于是看了一下WPF的文档,自己开发了一个客户端。 直接上代码吧: using JavaSwitch.Properties; using Newtonsoft.Json; using System; using System.…

【软件测试】详解软件测试中的测试级别

目录 一、测试级别二、组件测试三、开发者测试3.1测试与调试3.2 组件测试目标3.3 测试功能 四、稳健性测试4.1 效率的测试4.2 测试可维护性4.3 测试策略4.4 白盒测试 一、测试级别 软件系统通常是由许多子系统组成的,而这些子系统又是由多个组件组成的,…

从入门到入土:计算机视觉CV学习路线图

在当今这个被数据和图像淹没的世界,计算机视觉(CV)正如一位聪明绝顶的魔术师,能够从无数的图像中提取出有意义的信息。对于那些初入这个领域的新人,学习计算机视觉既是一场冒险,也是一场盛宴。让我作为一位…

修复OpenSSH远程代码执行漏洞:版本升级到9.9p1

目录 前言1. 备份配置文件2. 下载 OpenSSH 最新版本3. 编译安装 OpenSSH4. 替换旧版 OpenSSH 并创建符号链接5. 重启 SSH 服务6. 验证安装结果结语参考文章 前言 OpenSSH 是一种广泛使用的远程登录协议,它确保了服务器和客户端之间的安全通信。然而,随着…

详解调用钉钉AI助理消息API发送钉钉消息卡片给指定单聊用户

文章目录 前言准备工作1、在钉钉开发者后台创建一个钉钉企业内部应用;2、创建并保存好应用的appKey和appSecret,后面用于获取调用API的请求token;3、了解AI助理主动发送消息API:4、应用中配置好所需权限:4.1、权限点4.…

期权卖方如何提高期权策略的胜率——选择卖出虚值期权更稳健

期权卖方如何提高盈利的胜率? 影响期权卖方最重要的因素是权利金(期权报价)​。权利金越贵,期权卖方的盈亏平衡点越大,就容易盈利。 影响权利金的因素 行权价(虚值期权权利金便宜,实值期权权利…

springboot的调度服务与异步服务实操

1.调度服务 1.1.JDK之ScheduledExecutorService 讲到调度任务,我们脑海里马上会想到ScheduledExecutorService。 ScheduledExecutorService是 Java java.util.concurrent 包中的一个接口,它继承自 ExecutorService 接口。它主要用于在给定的延迟后运行…

LeetCode[中等] 763. 划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 思路 贪心…

使用默认不可变的Rust变量会踩什么坑

讲动人的故事,写懂人的代码 Rust的变量真的是名不副实。名字中明明有个“变”字,却默认不可变。还美其名曰“不可变变量”。要想让变量名副其实,还必须费心额外加个mut关键字,并必须称其为“可变变量”,才能与前者区分…

使用kaggle命令下载数据集和模型

1、点击用户头像,点击Settings: 2、找到API,点击create new token,将自动下载kaggle.json: 3、在用户目录下创建.kaggle文件夹,并将下载的kaggle.json文件移动到该文件夹: cd ~ mv Downloads…

负载均衡--相关面试题(六)

在负载均衡的面试中,可能会遇到一系列涉及概念、原理、实践应用以及技术细节的问题。以下是一些常见的负载均衡面试题及其详细解答: 一、什么是负载均衡? 回答:负载均衡是一种将网络请求或数据传输工作分配给多个服务器或网络资源…

编码能力提升计划 - 华为OD统一考试(E卷)

2024华为OD机试(E卷+D卷+C卷)最新题库【超值优惠】Java/Python/C++合集 题目描述 为了提升软件编码能力,小王制定了刷题计划,他选了题库中的n道题,编号从0到n-1,并计划在m天内按照题目编号顺序刷完所有的题目(注意,小王不能用多天完成同一题)。 在小王刷题计划中,小王…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01目录1. Beyond Text-to-Text: An Overview of Multimodal and Generative Artificial Intelligence for Education Using Topi…

QT-MySQL QSqlDatabase: QMYSQL driver not loaded

文章目录 问题解决操作:自己尝试编译,各种错误层出不穷: 解决问题检查总结: 问题 使用Qt连接mysql数据库,遇到了一个问题,就是QT5.14.1版本在连接MySQL数据库时候,提示驱动加载失败&#xff0c…

el-table添加fixed后错位问题

1 方案1 return {isShow:false, }mounted() {this.isShowtrue},watch: {$route(newRoute) {this.monitoredRoute newRoute; // 将新的路由信息保存到组件的monitoredRoute属性中// 执行其他操作或调用其他方法},//或$route(newRoute) {this.monitoredRoute newRoute; // 将新…

AI 对话工具汇总

🐣个人主页 可惜已不在 🐤这篇在这个专栏AI_可惜已不在的博客-CSDN博客 🐥有用的话就留下一个三连吧😼 目录 前言: 正文: 前言: 在科技飞速发展的时代,AI 对话正逐渐成为我们获取信息、交流思想的新方式。它以强…

【系统代码】招投标采购一体化管理系统,JAVA+vue

前言: 随着互联网和数字技术的不断发展,企业采购管理逐渐走向数字化和智能化。数字化采购平台作为企业采购管理的新模式,能够提高采购效率、降低采购成本、优化供应商合作效率,已成为企业实现效益提升的关键手段。系统获取在文末…

MES(软件)系统是什么?MES系统为何如此重要呢?

一、MES系统的定义与功能 MES系统是一套面向制造企业车间执行层的生产信息化管理系统,它涵盖了多种功能模块,包括但不限于: 订单管理:处理客户订单,确保生产需求与市场需求相匹配。生产调度:根据订单和生…

1.5 测试用例

欢迎大家订阅【软件测试】 专栏,开启你的软件测试学习之旅! 文章目录 前言1 测试用例介绍2 测试用例编写3 案例分析4 执行测试用例 前言 测试用例的设计和编制是软件活动中最重要的工作。本文详细讲解了测试用例的基本概念以及如何编写测试用例。 本篇文…

React 解释常见的 hooks: useState / useRef / useContext / useReducer

前言 如果对 re-render 概念还不清楚,建议先看 React & 理解 re-render 的作用、概念,并提供详细的例子解释 再回头看本文。 如果对 React 基础语法还不熟练,建议先看 React & JSX 日常用法与基本原则 再回头看本文。 useState useS…