从壹开始解读Yolov11【源码研读系列】——Data.dataset.py:模型训练数据预处理/YOLO官方数据集类——YOLODataset
【前情回顾】在上一篇文章记录了YOLO源码data目录下的 base.py 文件,其中定义了一个可灵活修改的数据加载处理基类——Class BaseDataset
灵活基类博文地址:https://blog.csdn.net/qq_58718853/article/details/143249295
【实验代码】所有实验代码上传至Gitee仓库。(会根据博文进度实时更新):
Gitee链接:https://gitee.com/machine-bai-xue/yolo-source-code-analysis
如果链接失效,访问404拒绝,可以直接在Gitee码云主页搜索——“机器白学”,所有项目中的YOLO源码实验就是本系列所有实验代码。
【本节预告】本文继续在 data 目录下,解析 dataset.py 文件内容。没有按顺序解析build.py文件的原因是在build.py实现的功能中需要先导入 dataset.py 定义的数据集类。
因此调整源码解析顺序,先对 dataset.py 文件中的类进行解读。
一、dataset.YOLODataset类
1.概述
YOLODataset 类是用于加载和处理 YOLO 格式的目标检测和分割数据集的 PyTorch 数据集类。该类提供了一个结构化的方式来加载、处理和增强 YOLO 格式的数据集。通过重用和扩展父类 base.py.BaseDataset 的逻辑,确保了代码的灵活性和可维护性。
下图展示了其类的方法函数总览,其中红色框里的方法是根据基类同名方法的重写。下面将先解读这些重写方法(因为其在初始化该类的时候,就隐含在其基类逻辑中运行了),而其他的方法需要在实例化本类后调用使用,因此在后面记录。
2.__init__:初始化传参入基类
首先来看该类的初始化方法。其最主要的逻辑就是通过 super()函数调用基类——BaseDataset的 init 初始化方法,将参数传递给基类,并运行初始化中的逻辑函数。(具体逻辑参考上一篇文章——Data.Base.py.BaseDataset:可灵活改写的数据集加载处理基类)
其中,*args 对应BaseDataset中的图片地址img_path(对应下图黄色框内参数),**kwargs 对应BaseDataset其他的已经“命名”的参数(对应下图蓝色框内多个参数)
在此特别记录一下 *args 和 **kwargs 的含义和区别。
*args:传入任意数量的位置参数——位置参数是指在函数中按顺序传入的变量。如果存在多个参数,则以元组的方式传入。下面的代码给出了一个抽象例子,这种写法本质上是简化了代码书写量。
# 定义一个功能函数 def func(*args):...# 等价定义 def func(v1, v2, v3):...# 传参使用这个功能函数 func(value1, value2, value3)
**kwargs:传入任意数量的关键字参数——关键字参数是指在函数中按命名好的参数名来传入的变量。如果存在多个命名参数,则以字典的方式传入。下方例子可以看出,关键字参数传参不一定要按顺序。
# 定义一个功能函数 def func(**kwargs):...# 等价定义 def func(value1=None, value2=None, value3=None):...# 传参使用这个功能函数 func(value3, value2, value1)
下面记录其初始化参数的表格。
*args | 根据基类BaseDataset设置,此处需要传入图片地址img_path(str) |
data | 传入数据集 .yaml 配置文件的字典格式(dict) |
task | 传入当前的数据集任务模式,如“detect”检测任务、“pose”姿态任务......等(str) |
**kwargs | 以关键字参数形式传入基类中的各种超参数(具体见BaseDataset类初始化关键字参数) |
3.get_labels:获取标签功能的基类方法重写
从上面YOLO数据加载类的初始化中可知,此类的逻辑是调用BaseDataset,而这个基类初始化的逻辑顺序是先运行获取标签的方法——get_labels(这个在对应BaseDataset文章中介绍)
在之前的灵活基类博文中,测试实验是自己定义了加载标签的函数。现在看YOLO官方加载训练数据时,是如何定义的。
官方获取标签的方式是从 .cache 缓存中加载——如果存在直接加载,如果如果不存在则调用self.cache_labels 创建。并且还会检查标签数据中是否存在错误或者缺失等不符合训练格式的数据,对检查结果可视化打印并警告报错。下图屏蔽一些不太重要的报错信息代码,总览此方法的代码逻辑。
所有的信息(检测信息、标签信息等)都在红框部分得到。蓝框部分对检测信息进行运用,黄框部分对标签数据进行运用。
在一开始构建好的YOLO数据集下没有缓存.cache格式的数据,因此最开始训练总要加载数据并缓存的(这样的好处是,对于相同数据集的重复训练,之后的训练读取数据会很快)
下面进入这个生成缓存并保存的函数——self.cache_labels ,查看其代码逻辑。
此函数输入一个保存缓存文件的地址,返回一个包含标签信息的字典,并且运行过程中会保存数据集的缓存文件到输入地址。
其最关键的作用功能是使用线程池 ThreadPool 并行处理验证图片和标签文件——这对于大型数据集十分有用。至于具体如何获取信息,这和上面图片中直接加载图片缓存文件一样,在源码的 utils 模块中编写,之后在具体分析。
可以看到黄框中保存的信息,和之前数据增强模块输入的数据格式相同,有图片地址、图片形状、各种模式的框信息等
同时还要注意其打印的信息模块含义,这对于检查数据集是否构建成功十分重要。
例如在下图例子中,一共有2250个找到的标签文件,其中缺失或为空的数量为零,但是存在1110个损坏的标签数量。
下面看看具体可能的损坏原因。因为YOLO训练数据是必须归一化的,因此坐标的取值范围必须在0,1直接,如果不在则可能报损坏标签的错误。因此在构建数据集时要特别注意这一点。
最后,会将信息保存到本地地址,具体实现同样在utils部分,并返回信息字典。
基于之前初始化类的参数记录,可以实际测试一下运行结果。可以看到第一次构建数据集类时,会在数据集目录下生成保存一个 label.cache 缓存文件。
4.build_transforms:数据预处理数据增强的基类方法重写
下面查看 YOLODataset 重写基类 BaseDataset 的第二个函数方法——build_transforms,图片数据预处理。
参考数据增强的文章,此处的逻辑并不复杂。分为两种情况,如果没有开启数据增强“开关”——augment=False,那么只会对图片和标签分别做标准化处理,并将其转为训练支持的torch格式(图片形状标准化——LetterBox,标签格式标准化——Format);如果开启数据增强——augment=True,则会根据超参数设定来进行数据增强(注意build_transforms这里会生成所有的数据增强transforms,如果某些数据增强模块不想使用,只需将其对应超参数“变化几率”设置为0)
因为这里使用了Compose流水线数据增强类来组织功能逻辑,因此可以使用Compose内置的方法打印数据增强功能的具体内容和顺序。
可以从下图看出,如果开启增强,则对图片的操作按先后顺序是:
Mosaic -> CopyPaste -> RandomPerspective -> Mixup -> Albumentations -> RandomHSV -> RandomFlip -> RandomFlip -> Format
下面不改变官方数据增强默认参数,将构建好的数据增强功能实际作用到图片上,看得到怎样的结果。
下面是几个实验结果,可见变化操作是随机的,并且是结果是一张多个变换叠加操作的图。(注意:从Format一章可知,图片是做过颜色翻转的,因此颜色都偏蓝不是RandomHSV色调增强的真实结果)
5.update_labels_info:数据格式的基类方法重写
在基类 BaseDataset 中 update_labels_info 方法被定义为修改标签到用户需要的格式,并且是在get_image_and_label 获取图片标签数据方法中运行的。也就是说是将模型torch读取的数据格式转为用户人为方便使用的格式。
该部分逻辑代码也不复杂,主要是使用自定义的数据类Instances,这将在其对应文件章节具体解读。
6.collate_fn:按批次组合训练Torch数据的类装饰器
最后是定义在YOLODataset中的一个装饰器——collate_fn:静态方法将输入的单样本类别合并为批次数据字典,用于模型训练。
@staticmethod:类中的装饰器解释
在类中定义方法前加了此内容,则代表下面定义的方法是一个装饰器,代码该方法有以下三种含义:
1.该方法参数输入没有self,不依赖类的实例,不访问修改类的属性
2.该方法可以从外部直接调用而不一定非要先初始化类的实例
3.该方法虽然不依赖类实例,但其具体的操作内容与类紧密相关,以一种“工具方法”的方式完成与类相关的任务,但不改变类的本身状态。
具体来讲,本部分方法主要是将多张批次的图片Torch数据合成一个完整的批次张量,如下图所示。
至此,关于YOLO源码中基本的数据集构建类分析完毕,该类最主要的功能就是读取数据的标签和图片将其转到模型熟悉的Torch格式,并且可选择在传入数据前进行数据增强操作。
在当前类同一文件下还有一些扩展类,处理诸如多数据格式怎么融合加载,其他任务数据集扩展等,这些在之后遇到需要时再进行分析解读。
在下一部分,紧接数据集的构建,分析YOLO源码中数据集加载器部分的源码。
相关文章:

从壹开始解读Yolov11【源码研读系列】——Data.dataset.py:模型训练数据预处理/YOLO官方数据集类——YOLODataset
【前情回顾】在上一篇文章记录了YOLO源码data目录下的 base.py 文件,其中定义了一个可灵活修改的数据加载处理基类——Class BaseDataset 灵活基类博文地址:https://blog.csdn.net/qq_58718853/article/details/143249295 【实验代码】所有实验代码上传至…...

C语言初阶必会的练习题(3)之位操作符(^ 、、>>等)的应用
C语言初阶必会的练习题(3) 放在最前面的1、不允许创建临时变量,交换两个整数的内容1.1、分析:见代码注释(a)方法 1(b)方法 2 1.2、结果展示方法 1 的 结果:方法 2 的 结果…...

MongoDB面试专题33道解析
大家好,我是 V 哥。今天给大家分享 MongoDB的道 V 哥原创的面试题,收藏起来,一定会对你有帮助。 V 哥推荐:2024 最适合入门的 JAVA 课程 1. 你说的 NoSQL 数据库是什么意思?NoSQL 与 RDBMS 直接有什么区别?…...

Laravel 安全实践:如何防止 XSS 攻击
在当今的网络环境中,应用程序的安全性越来越受到开发者和企业的重视。跨站脚本攻击(XSS)是常见的网络安全威胁之一,它通过在目标网站上注入恶意脚本,窃取用户信息或执行恶意操作。作为流行的 PHP 框架,Lara…...

《Java Web 开发》
一、引言 在当今数字化时代,Web 应用程序已经成为人们生活和工作中不可或缺的一部分。Java Web 开发作为一种广泛应用的技术,以其强大的功能、稳定性和可扩展性,在企业级应用开发中占据着重要地位。本文将深入探讨 Java Web 开发的各个方面&a…...

Vector和ArrayList
Vector和ArrayList都是Java集合框架中的动态数组实现类,它们之间存在一些显著的区别。以下是对Vector和ArrayList的详细比较: 一、线程安全性 Vector:是线程安全的,即多线程情况下,Vector可以保证容器的同步性。Vect…...

关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
文章目录 1. sizeof 和 strlen1.1 sizeof1.2 strlen 2. 数组和指针结合的试题深入解析2.1 一维数组2.2 字符数组代码1代码2代码3代码4代码5代码6 2.3 二维数组 3.指针运算的试题深入解析题1题2题3题4题5题6题7 希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力…...

开发更便利!迅为RK3568/RK3588 定制分区镜像发布
目前迅为所维护的Linux SDK一直延续RK官方默认分区结构,而迅为另维护了的一套定制分区结构的SDK,两种不同的分区结构都有着各自的特性,RK默认分区镜像和定制分区镜像对比如下所示: rk传统分区适合启动速度要求高且硬件配置固定的系…...

基于Springboot的学生宿舍管理系统的设计与实现-计算机毕设 附源码 26991
基于Springboot的学生宿舍管理系统的设计与实现 摘 要 学生宿舍管理系统在高校管理中具有重要的作用,为提高宿舍管理效率和服务质量,本文基于Springboot框架开发了一款学生宿舍管理系统。该系统主要分为管理员、学生用户和宿管用户三类角色,每…...

Spring Mvc中拦截器Interceptor详解
一、概述 拦截器常用于在请求处理的不同阶段插入自定义逻辑。Spring MVC的拦截器作用是在请求到达控制器之前或之后进行拦截,可以对请求和响应进行一些特定的处理。如: 登录验证:对于需要登录才能访问的网址,使用拦截器可以判断…...

【go从零单排】Strings and Runes 字符串和字符
Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 概念 在Go语言中,rune 是一个内置的数据类型,用于表示一个Unicode字符。它实际上是一个别名…...

django Forbidden (403)错误解决方法
存在问题: django提交请求时,报403错误; 解决方案: 在form表单中加{% csrf_token %} <h1>用户登录</h1><form me method"post" ac action"/login/">{% csrf_token %}<input type"t…...

pdmaner连接sqlexpress
别以为sqlserver默认的端口总是1433 案例 有台sqlserver2008 express服务器,刚安装,支持混合模式登录,其它什么配置也没改。 先看用ADO连接 这说明: 案例中sqlserver端口不是1433 !!!ADO连接…...

如果编译不通过,且感觉代码没有问题,大概率就是中文引起的问题
一、如果中文乱码:彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)_qt 中文乱码-CSDN博客 二、如果中文正常,编译还是有莫名其妙的问题 1、设置编码为 UTF-8(带BOM)。(如果下方没有出现“高级保存选项”,只需要修改一下代码&…...

java反序列化学习之CommonCollections3利用链的学习
一、前言 在前文中,我们学习了Java的类加载过程,类加载器以及Java中加载字节码的一些方法,其中介绍了TemplatesImpl,TemplatesImpl是一个可以加载字节码的类,通过调用其newTransformer()方法,即可执行这段字…...

超详细:Vue入门
Vue(发音为 /vjuː/,类似 view)是近些年比较流行的前端框架之一,和 React、Angular 并称为前端三大框架。其中 Vue 简单易学的特点成为国内主流,很多公司已经把它列为一 个前端开发人员必须要掌握的技术点了。 Vue 简介 Vue2.x官网 Vue3.x …...

基础网络安全知识
1.ctfhub技能树 1.1 Web-SQL注入 Web-SQL注入-整数型 && 字符型 && MySQL结构 参考:5.9.6MySql注入 Web-SQL注入-报错注入 step1: 查库名 ?id1 and extractvalue(1,concat(0x7e,database(),0x7e))-- step2: 查看表名 ?id1 and extractvalue(1…...

大语言模型工作原理笔记
大语言模型工作原理笔记 一、词向量:表示语言的方式 大语言模型使用词向量来表示单词,每个词向量是由一串数字组成的列表,代表词空间中的一个点。词空间中,含义相近的词位置更接近,例如"猫"的词向量会靠近…...

安全工程师入侵加密货币交易所获罪
一名高级安全工程师被判犯有对去中心化加密货币交易所的多次攻击罪,在此过程中窃取了超过 1200 万美元的加密货币。 沙克布艾哈迈德(Shakeeb Ahmed)被判刑,美国检察官达米安威廉姆斯(Damian Williams)称其…...

使用Docker-Compose安装redis,rabbitmq,nacos,mysql,nginx,tomcat,portainer组件教程
因为开发经常会用到一些组件,又不想在本地启动,所以买了个服务器,然后将这些组件都安装到服务器上以便开发使用。下面就记录下使用docker-compose安装组件的教程以及一些需要注意的地方。 关于docker和docker-compose的安装在另一篇博客中有…...

lora训练模型 打造个人IP
准备工作 下载秋叶炼丹器整理自己的照片下载底膜 https://rentry.org/lycoris-experiments 实操步骤 解压整合包 lora-scripts,先点击“更新” 训练图片收集 比如要训练一个自己头像的模型,就可以拍一些自己的照片(20-50张,最少15张&…...

mybatis+postgresql,无感读写json字段
1.实体类中字段类型 import com.alibaba.fastjson.JSONObject;Data public class TestDto {private String name;//对应数据库的JSON字段private JSONObject page_detail;} 2.自定义实现typeHandler package base.utils;import com.alibaba.fastjson.JSONObject; import org…...

苍穹外卖学习记录
苍穹外卖学习 文章目录 苍穹外卖学习知识前提:**<font color"red">Nginx****<font color"red">Swagger** 1.管理员登录思路:详细步骤: 1.1新增员工问题1:在新增员工时,需要将当前登录…...

大数据成功应用商业解决方案的例子
大数据技术在商业领域的广泛应用已经成为现代商业决策和运营优化的关键驱动力。企业利用大数据分析获取洞察,从而提高运营效率、改善客户体验并实现更高的盈利。以下是几个典型的成功案例,这些企业通过大数据技术在各自领域中取得了显著的成果。 亚马逊…...

《Python使用sqlite3数据库》
《Python使用sqlite3数据库》 1、连接数据库2、创建游标3、执行SQL语句4、提交更改5、查询数据6、关闭连接 Python可以使用多种数据库,以下是一般步骤和示例: 1、连接数据库 首先要安装对应的数据库驱动。如使用MySQL数据库,要安装pymysql库…...

XHCI 1.2b 规范摘要(14)
系列文章目录 XHCI 1.2b 规范摘要(一) XHCI 1.2b 规范摘要(二) XHCI 1.2b 规范摘要(三) XHCI 1.2b 规范摘要(四) XHCI 1.2b 规范摘要(五) XHCI 1.2b 规范摘要…...
(蓝桥杯C/C++)——基础算法(下)
目录 一、时空复杂度 1.时间复杂度 2.空间复杂度 3.分析技巧 4.代码示例 二、递归 1.递归的介绍 2.递归如何实现 3.递归和循环的比较 4.代码示例 三、差分 1.差分的原理和特点 2.差分的实现 3.例题讲解 四、枚举 1.枚举算法介绍 2.解空间的类型 3. 循环枚举解…...

详解Rust标准库:VecDeque 队列
theme: github highlight: an-old-hope 查看本地官方文档 安装rust后运行 rustup doc查看The Standard Library即可获取标准库内容 std::connections::VecDeque定义 队列是遵循先入先出规则的线性数据结构,在内存中不一定连续 VecDeque定义:可增长…...

网络协议都有哪些?
网络协议是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。以下是一些常见的网络协议: TCP/IP协议:传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础。由网络层的…...

非公平锁和公平锁的区别
公平锁(Fair Lock): 公平锁遵循 FIFO(先进先出)原则。当多个线程在等待锁时,公平锁会确保等待时间最长的线程优先获得锁。 这种锁机制可以避免线程饥饿(starvation),即某…...