YOLOv10(2):网络结构及其检测模型代码部分阅读

YOLOv10(1):初探,训练自己的数据-CSDN博客


 

目录

1. 写在前面

2. 局部模块

(1)SCDown

(2)C2fCIB

(3)PSA(partial self-attention)

3. 代码解读

(1)BaseModel(nn.Module)

(2)DetectionModel(BaseModel)

(3)YOLOv10DetectionModel(DetectionModel)

(4)拓展讲解:parse_model


1. 写在前面

        YOLOv10的代码结构和YOLOv8很相似,说是基于YOLOv8魔改的也不为过。话说回来,也算是魔改的非常成功的了。从代码工程上看,也是通过类一层层继承,获得一个完整的模型网络。

2. 局部模块

        YOLOv10使用了YOLOv8同样的C2f结构,在此就不多做解释了,在我的其他文章中均有讲解。

        本次着重在两个模块上做一下讲解,分别是SCDown、C2fCIB以及PSA。

        相关的代码在./ultralytics/nn/modules/block.py文件中。

(1)SCDown

        SCDown理解起来相对简单,只由两个卷积操作组成。第一个卷积操作主要实现了通道的转换,在YOLOv10中,第二个卷积操作测试通过k=3,s=2,p=1来实现两倍下采样。

(2)C2fCIB

        在讲C2fCIB之前,有必要带大家回顾一下C2f(还是简单回顾一下吧)。

        C2f一般被认为是C2 faster,即更快的C2操作。如下为C2f的网络结构示意图。

        C2fCIB就是将原来的Bottleneck换成了CIB模块,获得如下的结构。

        CIB是一个标准的Bottleneck结构,其结构示意图如下。需要说明的是,如下是一个典型图,采取了shortcut为True,lk为False作为前提。

(3)PSA(partial self-attention)

        YOLOv10引进了注意力机制,在PSA中,就集成了MHSA和FFN模块。

3. 代码解读

        要想了解代码工程是如何创建模型的,还得是多关注task.py文件。

        在此我们主要追随YOLOv10DetectionModel的脉络进行讲解,其他的网络构建过程基本类似。

(1)BaseModel(nn.Module)

        BaseModel,从名字上就能够理解,这是一个基类。BaseModel实际上是抽象出了一些共有成员,如forward,predict,loss等,这样在后面的派生类中,只需要将更细力度的功能进行完善,就可以调用这些共有的成员进行训练。

        多说一句,在面向对象编程中,不管是PyThon还是C++,都可以在基类中构造统一接口,之后通过在派生类中继承或重写,就可以实现统一的接口调用。

        在BaseModel中,我们着重关注_predict_once和fuse函数。

_predict_once

        _predict_once用于一次预测任务。

        第128行可以看出,是将输入x依次通过self.model中的module(m)进行运算(133行)。

        131行控制是否打印运行中的过程信息。

        135行控制可视化。

        137行控制返回嵌入特征数据。

fuse

        fuse操作主要是控制一些OP的融合,以128行为例,如果m为Conv,且m中含有BN层,那么就可以按照如下进行融合,以提升计算效率。

        以Conv+BN为例,我们都了解,卷积层(Conv)实际上是一个y = ax+b的过程。

        训练阶段,基本的操作包含两个部分。

        Conv: x=conv.weight*x+conv.bias

        BN: x=bn.\gamma *\frac{x_{i}-bn.mean}{\sqrt{bn.var+bn.\xi }}+bn.\beta

        其中,bn.mean为均值(对应nn.BatchNorm2d中的running_mean),bn.var为方差(对应nn.BatchNorm2d中的running_var),bn.\gammabn.\beta分别对应nn.BatchNorm2d中的weight和bias,bn.\varepsilon对应nn.BatchNorm2d中的eps。

        推理阶段,可将Conv和BN进行相应的合并计算,同时需要将参数进行重新的映射。具体如下。

        x=\frac{bn.\gamma*conv.weight}{\sqrt{bn.var+bn.\varepsilon }}*x+\frac{bn.\gamma *conv.bias}{\sqrt{bn.var+bn.\epsilon }}+bn.\beta

        如上,其中\frac{bn.\gamma*conv.weight}{\sqrt{bn.var+bn.\varepsilon}}组成了新的weight,\frac{bn.\gamma *conv.bias}{\sqrt{bn.var+bn.\epsilon }}+bn.\beta组成了新的bias。

(2)DetectionModel(BaseModel)

        DetectionModel继承自BaseModel。

        DetectionModel在初始化阶段主要执行三个操作,分别是定义模型,预计算参数以及初始化网络模型权重。

        290行到297行主要的工作就是定义模型。其中关键的是parse_model函数,一路走来研究YOLO算法的同学们一定不陌生,后续再和大家一起回顾一下。

        300行到311行则是计算stride信息,在执行模型输出解算的时候会用到。这其中实际上是构建了一组全0的数据,shape为(1, 3, 256, 256),通过调用forward接口,进而通过网络输出来计算不同支路的stride信息。

        314是进行参数的初始化。其中initialize_weights在torch_utils.py中定义。此处实际上仅仅是对BN层参数和激活层做简单的设置。其中作者还隐藏了使用nn.init.kaiming_normal_对卷积参数进行初始化。

(3)YOLOv10DetectionModel(DetectionModel)

        YOLOv10DetectionModel继承自DetectionModel,仅设置了Loss计算方式,此外啥也没做,啥都用DetectionModel的。

(4)拓展讲解:parse_model

        拓展重点放在模型的构建上。

        前面讲到,大家对parse_model应该是不陌生的。parse_model主要是读取网络配置文件,如yolov10m.yaml,来构建生成nn.Module类型的网络。

        以yolov10m.yaml为例,如下所示为文件内容。

        其中,nc表示类别数,这一参数会被数据定义中的相关类别数进行覆盖。具体是在./ultralytics/models/yolov10/train.py中的YOLOv10DetectionTrainer构件时,重载get_model接口时,nc使用了self.data[“nc”]。而self.data是在./ultralytics/engine/trainer.py中的BaseTrainer中,在初始化阶段调用check_det_dataset接口获得,具体操作室读取如VOC.yaml文件获得。

        scales则是模型大小的缩放。在以往的YOLO算法,如YOLOv5等,就开始提供不同尺度的网络模型,以适应不同的部署情况。因此scales就是用于将模型进行相应的缩放处理。

        以第一行的Conv为例,其中第一行内容为“-1, 1, Conv, [64, 3, 2]”四个参数。从如下的parse_model局部代码截图的851行可以看到,这四个参数实际上是代表了from, number, module和args。

        from表示输入来自哪一层,-1表示相邻的上一层。

        number表示模块的重复个数,如CSP结构中Bottleneck的数量。

        module表示模块类型,此处为Conv,卷积层。

        args则是表明了当前模型的输入参数。此处为输出channel为64,使用3*3的卷积核,stride为2。

        之后在如下代码段的889行计算输入、输出通道数。在898行组合完整的Conv层输入参数。

        最后在如下代码段的931构建nn.Module类型的模块,并在942行构建网络。

        好了,关于模型的相关知识就简单讲到这里,有什么问题大家私信我吧。

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

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

相关文章

手把手教大家如何使用Kaggle平台的免费GPU资源跑深度学习模型

如果手头没有GPU资源是没法很好进行学习和实操各种深度学习模型的,所幸有一些平台提供了GPU资源供广大兴趣爱好者进行免费使用。 一、免费GPU资源的平台 1. Google Colab 地址:https://colab.research.google.com/ 简介:Google Colab&…

ssm_mysql_高校自习室预约系统(源码)

博主介绍:✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

IDEA中,MybatisPlus整合Spring项目的基础用法

一、本文涉及的知识点【重点】 IDEA中使用MybatisPlus生成代码,并使用。 Spring整合了Mybatis框架后,开发变得方便了很多,然而,Mapper、Service和XML文件,在Spring开发中常常会重复地使用,每一次的创建、修…

权限修饰符和代码块

一.权限修饰符 1.权限修饰符:是用来控制一个成员能够被访问的范围的。 2.可以修饰成员变量,方法,构造方法,内部类。 3.例子: public class Student {priviate String name;prviate int age;} 二.权限修饰符的分类 有四种作用范围大小…

详解寄存器模型reg_model的auto_predict

什么是reg_model镜像值? DUT的配置寄存器的值是实际值,reg_model有镜像值、期望值的概念。 镜像值:存放我们认为此时DUT里寄存器的实际值。 期望值:存放我们期望DUT寄存器被赋予的值。 什么是auto predict? 那么怎么更新reg…

安卓ANR检测、分析、优化面面谈

前言 一个引发讨论的楔子,以下三种现象有什么区别: App停止运行App暂无响应App闪退 答案: 产生原因不同:停止运行是UNCheckExceptionError暂无响应是ANRDialog闪退是CheckExceptionError 本文讨论的主题是ANR的定义、分类、复现…

内核注入DLL,支持注入PPL

这是我的个人项目,目前功能: 内核注入DLL到进程,支持注入PPL进程,可绕过任意代码卫士保护,签名校验。内核调用应用层任意函数,支持常见的调用约定。 后续可能会增加: 代码注入 Rookit和Anti-…

E. 矩阵第k大

看到这句话,其中任意两个数都不能在同一行或者同一列 经典的网络流/匈牙利 由于小白看不懂网络流 (其实是我不会) ,不妨就讲讲匈牙利 匈牙利算法 前置知识: 二分图 匈牙利(是个人)算法是二分…

纵向导航栏使用navbar-nav-scroll溢出截断问题

项目场景: 组件:Bootstrap-4.6.2、JQuery 3.7.1 测试浏览器:Firefox126.0.1、Microsoft Edge125.0.2535.67 IDE:eclipes2024-03.R 在编写CRM的工作台主页面时,由于该页面使用的是较旧的技术,所以打算使用…

ChatGPT-4o 有何特别之处?

文章目录 多模态输入,多模态输出之前的模型和现在模型对比 大家已经知道,OpenAI 在 GPT-4 发布一年多后终于推出了一个新模型。它仍然是 GPT-4 的一个变体,但具有前所未见的多模态功能。 有趣的是,它包括实时视频处理等强大功能&…

基础9 探索图形化编程的奥秘:从物联网到工业自动化

办公室内,明媚的阳光透过窗户洒落,为每张办公桌披上了一层金色的光辉。同事们各自忙碌着,键盘敲击声、文件翻页声和低声讨论交织在一起,营造出一种忙碌而有序的氛围。空气中氤氲着淡淡的咖啡香气和纸张的清新味道,令人…

fastjson 泛型转换问题(详解)

系列文章目录 附属文章一:fastjson TypeReference 泛型类型(详解) 文章目录 系列文章目录前言一、代码演示1. 不存在泛型转换2. 存在泛型转换3. 存在泛型集合转换 二、原因分析三、解决方案1. 方案1:重新执行泛型的 json 转换2. …

数据可视化每周挑战——中国高校数据分析

最近要高考了,这里祝大家金榜题名,旗开得胜。 这是数据集,如果有需要的,可以私信我。 import pandas as pd import numpy as np import matplotlib.pyplot as plt from pyecharts.charts import Line from pyecharts.charts impo…

图像处理ASIC设计方法 笔记26 非均匀性校正SOC如何设计

在红外成像技术领域,非均匀性校正是一个至关重要的环节,它直接影响到成像系统的性能和目标检测识别的准确性。非均匀性是指红外焦平面阵列(IRFPA)中各个像元对同一辐射强度的响应不一致的现象,这种不一致性可能是由于制造过程中的缺陷、材料的不均匀性或者像元间的热电特性…

simCSE句子向量表示(1)-使用transformers API

SimCSE SimCSE: Simple Contrastive Learning of Sentence Embeddings. Gao, T., Yao, X., & Chen, D. (2021). SimCSE: Simple Contrastive Learning of Sentence Embeddings. arXiv preprint arXiv:2104.08821. 1、huggingface官网下载模型 官网手动下载:pri…

集合操作进阶:关于移除列表元素的那点事

介绍 日常开发中,难免会对集合中的元素进行移除操作,如果对这方面不熟悉的话,就可能遇到 ConcurrentModificationException,那么,如何优雅地进行元素删除?以及其它方式为什么不行? 数据初始化…

国内类似ChatGPT的大模型应用有哪些?发展情况如何了

第一部分:几个容易混淆的概念 很多人,包括很多粉丝的科技博主,经常把ChatGPT和预训练大模型混为一谈,因此有必要先做一个澄清。预训练大语言模型属于预训练大模型的一类,而ChatGPT、文心一言又是预训练大语言模型的一个…

node基础-持续更新

node基础 1.node模块2.node环境搭建3.fs模块4.ES模块和CommonJS模块4.1 更改后缀名4.2 package.json配置支持es模块4.3 变量别名4.4 CommonJS模块 5.打造自己的脚手架工具5.1创建自定义全局指令5.2 使用commander处理--help参数5.3 处理自定义指令5.4 逻辑代码模块化拆分5.5 命…

iPad里的图片如何导出 iPad的照片如何管理

我们的设备中充满了各种重要的照片和视频,特别是iPad,作为苹果公司的一款强大的平板电脑,它不仅能够捕捉生活中的精彩瞬间,还可以存储和展示我们珍贵的回忆。然而,随着照片数量的不断增加,有效地管理和导出…

对boot项目拆分成cloud项目的笔记

引言:这里我用的是新版本的技术栈 spring-boot-starter-parent >3.2.5 mybatis-spring-boot-starter >3.0.3 mybatis-plus-boot-starter >3.5.5 spring-cloud-dependencies …