从壹开始解读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源码中数据集加载器部分的源码。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HFSS 3D Layout中Design setting各个选项的解释

从HFSS 3D LAYOUT菜单中,选择Design Settings打开窗口,会有六个选项:DC Extrapolation, Nexxim Options, Export S Parameters, Lossy Dielectrics, HFSS Meshing Method, and HFSS Adaptive Mesh. DC Extrapolation 直流外推 直流外推分为标…

【板栗糖GIS】——如果安装的vscode版本落后了,如何无障碍更新

【板栗糖GIS】——如果安装的vscode版本落后了,如何无障碍更新 今天想安装新扩展插件时发现vscode版本有点旧,于是在不影响插件的情况下更新。 打开vscode软件,点击设置检查更新,如果有需要更新的直接安装到原目录,如…

数字化转型必看!华为数字化最全合集(192页PDF限免下载 )

今天给大家整理了6份关于华为数字化的资料,共计192页,干货满满! 资料已经全部打包,划到文末添加大师兄即可免费下载👇👇👇 一、华为实施数字化转型方法论与实践的业务解读 这份报告是华为实施数…

【数据集】【YOLO】【目标检测】道路结冰数据集 1527 张,YOLO目标检测实战训练教程!

数据集介绍 【数据集】道路结冰数据集 1527 张,目标检测,包含YOLO/VOC格式标注。数据集中包含2种分类:“clear_road, ice_road”。数据集来自国内外图片网站和视频截图,部分数据经过数据增强处理。检测范围监控视角检测、无人机视…

创建线程时传递参数给线程

在C中,可以使用 std::thread 来创建和管理线程,同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…

集智书童 | DuoDiff: 提升浅层 Transformer 性能的扩散模型, 双 Backbone 件扩散模型在图像处理中的应用 !

本文来源公众号“集智书童”,仅用于学术分享,侵权删,干货满满。 原文链接:DuoDiff: 提升浅层 Transformer 性能的扩散模型, 双 Backbone 件扩散模型在图像处理中的应用 ! 扩散模型在图像生成方面取得了前所…

linux perf 环境部署和基本测试(基于Ubuntu20.04)

1,linux 安装perf sudo apt-ge install linux-tools-common sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y 2 补充安装 sudo apt-get install python3-q-text-as-data 3,perf常用命令 larkubuntu:~$ perf usage: perf [--version] [--hel…

PHP露营地管理平台小程序系统源码

⛺️【露营新风尚】露营地管理平台系统全攻略⛺️ 🏕️一、露营热潮下的管理难题:如何高效运营露营地?🤔 随着露营文化的兴起,越来越多的人选择在大自然中享受宁静与自由。然而,露营地的管理却面临着诸多…

信息安全工程师(83)Windows操作系统安全分析与防护

一、Windows操作系统安全分析 系统漏洞: Windows操作系统由于其复杂性和广泛使用,可能存在一些已知或未知的漏洞。这些漏洞可能会被黑客利用,进行恶意攻击。微软会定期发布系统更新和补丁,以修复这些漏洞,提高系统的安…

软件测试—功能测试详解

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 一、测试项目启动与研读需求文档 (一) 组建测试团队 1、测试团队中的角色 2、测试团队的基本责任 尽早地发现软件程序、系统或产…

【1个月速成Java】基于Android平台开发个人记账app学习日记——第7天,申请阿里云SMS短信服务SDK

系列专栏链接如下,方便跟进: https://blog.csdn.net/weixin_62588253/category_12821860.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12821860&sharereferPC&sharesourceweixin_62588253&sharefromfrom_link 同时篇幅…

安装和运行开发微信小程序

下载HBuilder uniapp官网 uni-app官网 微信开发者工具 安装 微信小程序 微信小程序 官网 微信小程序 配置 运行 注意:运行前需要开启服务端口 如果运行看不到效果,设置下基础库选别的版本 配置

如何用pycharm连接sagemath?

#世纪难题在我逃避刷CTF的这两天解决了# 1. 在本地linux上部署最新版的sagemath 推荐WSLdocker直接pull sagemath 2. pycharm中创建jupyter脚本,远程连接jupyter服务器 3. 运行cell并配置kernel 缺点:pycharm用自带的python编译器预处理代码&#xff0…

JNPF V5.1版本震撼上线,更多功能等你解锁!

亲爱的用户们: 随着季节的更迭,引迈也在不断进步和创新。经过数月的精心打磨和无数次的测试,我们非常兴奋地宣布,JNPF快速开发平台迎来了激动人心的V5.1版本更新!这次更新不仅带来了全新的功能和改进,还进…

Dependency: androidx.webkit:webkit:1.11.0-alpha02. 问题

android studio 打包后出现这个问题 1.步骤更新topOn sdk 添加 //Admob api “com.anythink.sdk:adapter-admob:6.4.18” api “com.google.android.gms:play-services-ads:23.4.0” api "com.google.android.gms:play-services-ads:23.4.0"sdk 中会出现打包编译报错…

express 使用JWT认证

1、JWT的理解 JWT 的组成部分: 分别是 Header(头部)、Payload(有效荷载)、Signature(签名) 三者之间使用英文的"."分隔, Pyload 部分才是真正的用户信息,他是用户信息经过加密之后生成的字符串 Header 和 Signature 是 安全性相关的部分,只是为了保证 Tok…

【数据结构】LRUCache和跳表{简单讲解+模拟实现}

文章目录 LRUCacheSkipList LRUCache LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的…

第一个纯血鸿蒙应用(Napi开发-ArtTS调用C/C++)

1.行业背景 纯血鸿蒙,即鸿蒙Next版已于2014年1月正式发版,鸿蒙生态设备数量已经突破10亿台,已经有超过15000个应用和元服务上架。鸿蒙生态不只是移动设备这么简单,他打造的是一个18n的全场景战略,真正做到了“万物互联…

【从零开始的LeetCode-算法】3255. 长度为 K 的子数组的能量值 II

给你一个长度为 n 的整数数组 nums 和一个正整数 k 。 一个数组的 能量值 定义为: 如果 所有 元素都是依次 连续 且 上升 的,那么能量值为 最大 的元素。否则为 -1 。 你需要求出 nums 中所有长度为 k 的 子数组 的能量值。 请你返回一个长度为 n - …

【Linux】进程创建/等待/替换相关知识详细梳理

1. 进程创建 1.1 fork函数 概念&#xff1a;fork函数为系统调用接口&#xff0c;用于从已存在的进程中&#xff0c;创建一个新的进程。新进程为子进程&#xff0c;原来的进程为父进程。 用法&#xff1a; #include <unistd.h> pid_t fork(void); // 返回值&…