YOLOv10改进 | Conv篇 | 利用FasterBlock二次创新C2f提出一种全新的结构(全网独家首发,参数量下降70W)

 一、本文介绍

本文给大家带来的改进机制是利用FasterNet的FasterBlock改进特征提取网络,将其用来改进ResNet网络,其旨在提高计算速度而不牺牲准确性,特别是在视觉任务中。它通过一种称为部分卷积(PConv)的新技术来减少冗余计算和内存访问。这种方法使得FasterNet在多种设备上运行速度比其他网络快得多,同时在各种视觉任务中保持高准确率,同时本文的内容为我独家创新,全网仅此一份,同时本文的改进机制参数量下降50W,V10n的计算量为6.9GFLOPs

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

   专栏回顾:YOLOv10改进系列专栏——本专栏持续复习各种顶会内容——科研必备 


目录

 一、本文介绍

二、FasterNet原理

2.1 FasterNet的基本原理

2.2 部分卷积

2.3 加速神经网络

三、FasterBlock的核心代码

四、 手把手教你添加FasterBlock机制 

4.1 修改一

4.2 修改二 

4.3 修改三 

4.4 修改四 

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

5.1 FasterBlock的yaml文件

5.2 训练代码 

5.3 FasterBlock的训练过程截图 

五、本文总结


二、FasterNet原理

 论文地址:官方论文地址

 代码地址:官方代码地址


2.1 FasterNet的基本原理

FasterNet是一种高效的神经网络架构,旨在提高计算速度而不牺牲准确性,特别是在视觉任务中。它通过一种称为部分卷积(PConv)的新技术来减少冗余计算和内存访问。这种方法使得FasterNet在多种设备上运行速度比其他网络快得多,同时在各种视觉任务中保持高准确率。例如,FasterNet在ImageNet-1k数据集上的表现超过了其他模型,如MobileViT-XXS,展现了其在速度和准确度方面的优势。

FasterNet的基本原理可以总结为以下几点:

1. 部分卷积(PConv): FasterNet引入了部分卷积(PConv),这是一种新型的卷积方法,它通过只处理输入通道的一部分来减少计算量和内存访问。

2. 加速神经网络: FasterNet利用PConv的优势,实现了在多种设备上比其他现有神经网络更快的运行速度,同时保持了较高的准确度。

下面为大家展示的是FasterNet的整体架构

它包括四个层次化的阶段,每个阶段由一系列FasterNet块组成,并由嵌入或合并层开头。最后三层用于特征分类。在每个FasterNet块中,PConv层之后是两个点状卷积(PWConv)层。为了保持特征多样性并实现更低的延迟,仅在中间层之后放置了归一化和激活层


2.2 部分卷积

部分卷积(PConv)是一种卷积神经网络中的操作,旨在提高计算效率。它通过只在输入特征图的一部分上执行卷积操作,而非传统卷积操作中的全面应用。这样,PConv可以减少不必要的计算和内存访问,因为它忽略了输入中认为是冗余的部分。这种方法特别适合在资源有限的设备上运行深度学习模型,因为它可以在不牺牲太多性能的情况下,显著降低计算需求。

下面我为大家展示了FasterNet中的部分卷积(PConv)与传统卷积和深度卷积/分组卷积的比较

PConv通过仅对输入通道的一小部分应用滤波器,同时保持其余通道不变,实现了快速和高效的特性提取。PConv的计算复杂度(FLOPs)低于常规卷积,但高于深度卷积/分组卷积,这样在减少计算资源的同时提高了运算性能。


2.3 加速神经网络

加速神经网络主要通过优化计算路径、减少模型大小和复杂性、提高操作效率,以及使用高效的硬件实现等方式来降低模型的推理时间。这些方法包括

简化网络层使用更快的激活函数采用量化技术浮点运算转换为整数运算,以及使用特殊的算法来减少内存访问次数等。通过这些策略,可以在不损害模型准确性的前提下,使神经网络能够更快地处理数据和做出预测。


三、FasterBlock的核心代码

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

import torch
import torch.nn as nn
from timm.models.layers import DropPath__all__ = ['C2f_FasterBlock']class Partial_conv3(nn.Module):def __init__(self, dim, n_div, forward):super().__init__()self.dim_conv3 = dim // n_divself.dim_untouched = dim - self.dim_conv3self.partial_conv3 = nn.Conv2d(self.dim_conv3, self.dim_conv3, 3, 1, 1, bias=False)if forward == 'slicing':self.forward = self.forward_slicingelif forward == 'split_cat':self.forward = self.forward_split_catelse:raise NotImplementedErrordef forward_slicing(self, x):# only for inferencex = x.clone()  # !!! Keep the original input intact for the residual connection laterx[:, :self.dim_conv3, :, :] = self.partial_conv3(x[:, :self.dim_conv3, :, :])return xdef forward_split_cat(self, x):# for training/inferencex1, x2 = torch.split(x, [self.dim_conv3, self.dim_untouched], dim=1)x1 = self.partial_conv3(x1)x = torch.cat((x1, x2), 1)return xdef 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 FasterBlock(nn.Module):def __init__(self,inc,dim,n_div=4,mlp_ratio=2,drop_path=0.1,layer_scale_init_value=0.0,act_layer='RELU',norm_layer='BN',pconv_fw_type='split_cat'):super().__init__()self.dim = dimself.inc = incself.mlp_ratio = mlp_ratioself.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()self.n_div = n_divmlp_hidden_dim = int(dim * mlp_ratio)mlp_layer = [nn.Conv2d(dim, mlp_hidden_dim, 1, bias=False),nn.BatchNorm2d(mlp_hidden_dim),nn.ReLU(),nn.Conv2d(mlp_hidden_dim, dim, 1, bias=False)]self.mlp = nn.Sequential(*mlp_layer)self.spatial_mixing = Partial_conv3(dim,n_div,pconv_fw_type)if inc != dim:  # 在输入和输出不等时添加额外处理一步self.firstConv = Conv(inc, dim, 1)if layer_scale_init_value > 0:self.layer_scale = nn.Parameter(layer_scale_init_value * torch.ones((dim)), requires_grad=True)self.forward = self.forward_layer_scaleelse:self.forward = self.forwarddef forward(self, x):if self.inc != self.dim:x = self.firstConv(x)shortcut = xx = self.spatial_mixing(x)x = shortcut + self.drop_path(self.mlp(x))return xdef forward_layer_scale(self, x):if self.inc != self.dim:x = self.firstConv(x)shortcut = xx = self.spatial_mixing(x)x = shortcut + self.drop_path(self.layer_scale.unsqueeze(-1).unsqueeze(-1) * self.mlp(x))return xclass C2f_FasterBlock(nn.Module):"""Faster Implementation of CSP Bottleneck with 2 convolutions."""def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):"""Initialize CSP bottleneck layer with two convolutions with arguments ch_in, ch_out, number, shortcut, groups,expansion."""super().__init__()self.c = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, 2 * self.c, 1, 1)self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)self.m = nn.ModuleList(FasterBlock(self.c, self.c) for _ in range(n))def forward(self, x):"""Forward pass through C2f layer."""x = self.cv1(x)x = x.chunk(2, 1)y = list(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):"""Forward pass using split() instead of chunk()."""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))if __name__ == "__main__":# Generating Sample imageimage_size = (1, 64, 240, 240)image = torch.rand(*image_size)# Modelmodel = C2f_FasterBlock(64, 64)out = model(image)print(out.size())

四、 手把手教你添加FasterBlock机制 

4.1 修改一

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


4.2 修改二 

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


4.3 修改三 

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

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


4.4 修改四 

按照我的添加在parse_model里添加即可。

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


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

5.1 FasterBlock的yaml文件

此版本的训练信息:YOLOv10n-C2f-FasterBlock summary: 404 layers, 2231750 parameters, 2231734 gradients, 6.9 GFLOPs

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv10 object detection model. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov10n.yaml' will call yolov10.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024]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_FasterBlock, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f_FasterBlock, [256, True]]- [-1, 1, SCDown, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f_FasterBlock, [512, True]]- [-1, 1, SCDown, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2f_FasterBlock, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9- [-1, 1, PSA, [1024]] # 10# YOLOv10.0n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f_FasterBlock, [512]] # 13- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f_FasterBlock, [256]] # 16 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 3, C2f_FasterBlock, [512]] # 19 (P4/16-medium)- [-1, 1, SCDown, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 3, C2fCIB, [1024, True, True]] # 22 (P5/32-large)- [[16, 19, 22], 1, v10Detect, [nc]] # Detect(P3, P4, P5)

5.2 训练代码 

大家可以创建一个py文件将我给的代码复制粘贴进去,配置好自己的文件路径即可运行。

import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLOif __name__ == '__main__':model = YOLO('ultralytics/cfg/models/v8/yolov8-C2f-FasterBlock.yaml')# model.load('yolov8n.pt') # loading pretrain weightsmodel.train(data=r'替换数据集yaml文件地址',# 如果大家任务是其它的'ultralytics/cfg/default.yaml'找到这里修改task可以改成detect, segment, classify, posecache=False,imgsz=640,epochs=150,single_cls=False,  # 是否是单类别检测batch=4,close_mosaic=10,workers=0,device='0',optimizer='SGD', # using SGD# resume='', # 如过想续训就设置last.pt的地址amp=False,  # 如果出现训练损失为Nan可以关闭ampproject='runs/train',name='exp',)


5.3 FasterBlock的训练过程截图 


五、本文总结

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

  专栏回顾:YOLOv10改进系列专栏——本专栏持续复习各种顶会内容——科研必备 

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

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

相关文章

NLP入门——词袋语言模型的搭建、训练与预测

卷积语言模型实际上是取了句子最后ctx_len个词作为上下文输入模型来预测之后的分词。但更好的选择是我们做一个词袋,将所有分词装在词袋中作为上下文,这样预测的分词不只根据最后ctx_len个分词,而是整个词袋中的所有分词。 例如我们的序列是&…

javaweb图书商城系统带万字文档网上书城java项目java课程设计java毕业设计

文章目录 图书商城系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档(9.9¥带走) 图书商城系统 一、项目演示 网上书城 二、项目介绍 语言:java 数据库:…

typora 两边太宽,设置宽度

步骤: 查看目前使用主题类型 文件 —> 偏好设置 —> 外观 —> 打开主题文件夹 修改对应的主题:max-width

MySQL 数据库支持存储emoji表情

当你通过node.js,往mysql存储emoji表情的时候,可能会遇到报错: code: ‘ER_TRUNCATED_WRONG_VALUE_FOR_FIELD’, errno: 1366, sqlMessage: “Incorrect string value: ‘\xF0\x9F\x8D\x94’ for column ‘nick_name’ at row 1”, sqlState…

MySQL数据库主从复制+mycat读写分离+MHA实操

目录 一、主从复制 1.1 主从复制简介 1.2 MySQL支持的复制类型 1.3 主从复制的工作过程 1.4 主从复制的同步模式 1.4.1 异步复制(Asynchronous replication) 1.4.2 全同步复制(Fully synchronous replication) 1.4.3 半同…

力扣2356.二维差分模板——子矩阵元素加1

力扣2356.二维差分模板——子矩阵元素加1 模板题 最后将n2*n2的矩阵删去周围一圈变成n*n矩阵的操作 class Solution {public:vector<vector<int>> rangeAddQueries(int n, vector<vector<int>>& queries) {vector<vector<int>> res…

【JavaWeb程序设计】Servlet(二)

目录 一、改进上一篇博客Servlet&#xff08;一&#xff09;的第一题 1. 运行截图 2. 建表 3. 实体类 4. JSP页面 4.1 login.jsp 4.2 loginSuccess.jsp 4.3 loginFail.jsp 5. mybatis-config.xml 6. 工具类&#xff1a;创建SqlSessionFactory实例&#xff0c;进行 My…

UI设计工具选择指南:Sketch、XD、Figma、即时设计

在数字产品设计产业链中&#xff0c;UI设计师往往起着连接前后的作用。产品经理从一个“需求”开始&#xff0c;制定一个抽象的产品概念原型。UI设计师通过视觉呈现将抽象概念具体化&#xff0c;完成线框图交互逻辑视觉用户体验&#xff0c;最终输出高保真原型&#xff0c;并将…

threadx netxduo stm32f407上实现http server

这次用的是CubeIDE CubeMX 要把NX_APP的mem分配的大一些&#xff0c;在app_azure_rtos.c中&#xff0c;我给的是40*1024&#xff0c;如果给的不够&#xff0c;会导致后面无法分配pool和thread等等 需要用到filex 要在CubeMX里面勾选上&#xff0c;还要用到http_server和dhcp …

1. InternLM - 入门岛

第1关 Linux 基础知识 1. 完成SSH连接与端口映射并运行hello_world.py SSH连接配置 # wsl2中生成密钥对&#xff08;~/.ssh/id_rsa, ~/.ssh/id_rsa.pub&#xff09; ssh-keygen -t rsa# 将id_rsa.pub在internStudio作为公钥导入SSH登录 $ ssh -p 38871 rootssh.intern-ai.o…

汽车免拆诊断案例 | 奥迪 Q7 e-tron无法通过插电式充电器充电

故障现象 车主反映&#xff0c;车辆无法使用自带的插电式充电器充电。&#xff08;这种充电方法是“Mode 2充电”&#xff0c;3针插头&#xff0c;10 A&#xff0c;2.2 kW&#xff09; 接车后验证故障&#xff0c;将Type 2充电插头连接到车辆时&#xff0c;充电口锁定销循环三…

3DSC(3D形状上下文特征)

形状上下文(shape context简写为SC)由Serge Belongie等人于2002年首次提出,是一种很流行的二维形状特征描述子,多用于目标识别和形状特征匹配。 2004年,Andrea Frome等人将形状上下文的工作从二维数据迁移到三维数据上提出了3D形状上下文(3DSC) 原理解析 2DSC的算法流程…

Git的基本知识点 + GitBash安装Pacman + Git命令含有中文,终端输出中文乱码

Git的基本知识点&#xff1a;整理自以下作者的文章繁华似锦Fighting的文章https://www.jianshu.com/nb/49854893另外还补充了git ls-file、.gitignore 等内容&#xff0c;涉及具体操作&#xff0c;还有命令总结。简略版可以看以上作者的文章&#xff0c;详细版可以看网盘里面的…

【STM32学习】stm32cubemx基础配置,点亮/闪烁一个LED灯

1、cubemx开始 打开cubemx&#xff0c;在help栏中&#xff0c;点击&#xff0c;选择安装你所需要的stm32芯片版本&#xff0c; 打开后&#xff0c;选择你所配置的芯片型号&#xff0c;如我配置的是stm32f4系列&#xff0c;勾选&#xff0c;点击Install。 安装好后&#xff0c;…

HybridCLR原理中的重点总结

序言 该文章以一个新手的身份&#xff0c;讲一下自己学习的经过&#xff0c;大家更快的学习HrbirdCLR。 我之前的两个Unity项目中&#xff0c;都使用到了热更新功能&#xff0c;而热更新的技术栈都是用的HybridCLR。 第一个项目本身虽然已经集成好了热更逻辑&#xff08;使用…

Java | Leetcode Java题解之第227题基本计算器II

题目&#xff1a; 题解&#xff1a; class Solution {public int calculate(String s) {Deque<Integer> stack new ArrayDeque<Integer>();char preSign ;int num 0;int n s.length();for (int i 0; i < n; i) {if (Character.isDigit(s.charAt(i))) {num…

Elasticseach学习

概念 是一个开源的分布式搜索引擎&#xff0c;可以应用于搜索、日志监控等 倒排索引 正向索引&#xff1a;基于文档id创建索引。查询词条时必须先找到文档&#xff0c;而后判断是否包含词条 倒排索引&#xff1a;对文档内容分词&#xff0c;对词条创建索引&#xff0c;并记录…

docker-compose mongodb 副本集

准备 cd /opt/mongos 把 3 个节点的数据目录创建好 mkdir -p ./mongos/{mongo1,mongo2,mongo3} mongodb 使用 keyFile 进行认证&#xff0c;副本集群中的每个节点的 mongodb 使用 keyFile 的内容作为认证其他成员的共享密码。mongodb 实例只有拥有正确的 keyFile 才可以加入副…

HCIP课堂笔记

第一章 1、数据转换---目标&#xff1a;抽象语言---二进制---电信号 2、应用程序---接收参数和指令&#xff08;编码&#xff1a;接收传递给计算机指令参数最终转换为二进制&#xff09; 3、二进制---电信号 4、对于整个互联网而言指定了统一的标准——OSI/RM参考模型 &…

GitLab和Git

GitLab保姆级教程 文章目录 GitLab保姆级教程一、GitLab安装二、添加组和用户三、新增项目四、Git上传项目说明五、命令行指引 根据以下说明从计算机中上传现有文件&#xff1a;六、创建与合并分支七、GitLab回滚到特定版本八、数据备份与恢复九、docker中创建gitlab GIT 常用命…