【系列目录】本系列所有文件分章节内容的目录文章请参考:【源码研读系列】目录
【实验代码】本系列所有实验设计的源码都以上传 Gitee码云和GitCode 平台。GitCode代码项目地址:GitCode;在Gitee主页搜索“机器白学”,所有项目中的“YOLO源码实验”就是本系列所有实验代码。Gitee代码项目地址:Gitee
【前情回顾】在上一篇文章记录了YOLO源码data目录下的dataset.py 文件中定义的YOLO数据集类——Class YOLODataset,其基于了数据集基类BaseDataset,并重写了关键的数据预处理函数方法。
YOLODataset数据集类博文地址:Data.dataset.py:模型训练数据预处理/YOLO官方数据集类——YOLODataset
【本节预告】在上一篇文章的预告中,解释了为什么没有先解读build.py的原因,现在,有了上一篇文章对于YOLO数据集类YOLODataset的解析基础,可以进一步解读 build.py 文件下的数据加载搭建迭代器的代码逻辑了。
有了上一篇文章的铺垫,本部分内容变得比较容易了,只需分析关键逻辑,比如数据采样和迭代器搭建,而不用赘述数据集是如何构建的。
目录
一、build._RepeatSampler类:重复迭代采样器
二、build.InfiniteDataLoader类:无限循环和动态重置的数据加载器
2.__len__() / __iter__() / reset() :其他方法
三、build.build_dataloader方法:构建YOLO数据集加载器
一、build._RepeatSampler类:重复迭代采样器
_RepeatSampler 是一个自定义的采样器类,通常用于Pytorch机器学习框架中。它的作用是对给定的采样器 sampler 进行无限次重复,以便在训练过程中永不停止地生成样本。
该类通过 __iter__ 方法实现了一个无限循环迭代器,使用 yield from 来生成采样器的样本。
二、build.InfiniteDataLoader类:无限循环和动态重置的数据加载器
在定义好了上述 _RepeatSampler 重复采样类后,YOLO在此基础上扩展 PyTorch 官方的数据加载器 torch.utils.data.dataloader,目的是实现一种可以无限循环工作并且可以自由重置的DataLoader——InfiniteDataLoader。具体代码解析如下。
1.__init__():初始化方法
首先查看其类初始化。一开始通过调用父类构造函数 super().__init__() 的方式传递参数调用DataLoader的初始化方式完成基础的初始化,这和之前使用基类的方法一样没什么多说的了。
继续,特别的,这里使用了Python内置的一个底层方法——object.__setattr__来直接设置对象的属性值,允许特殊情况绕过对属性设置的默认行为。
为什么要使用这种方式将 dataloader.DataLoader 的batch_sampler替换为_RepeatSampler,下面先详细记录一下。
在DataLoader类内有定义batch_sampler相关内容的修改函数——DataLoader.__setattr__,如下图所示。但batch_sampler等类属性值是受保护的,即必须是类没有初始化的情况下才允许修改(self.__initialized 限制参数)
因此在 InfiniteDataLoader 中使用底层方法 object.__setattr__ , 直接设置属性值,避免了触发DataLoader.__setattr__中的 ValueError 保护机制。
最后初始化直接调用DataLoader的方法初始化了一个用来迭代数据的迭代器 self.iterator 。DataLoader基类方法也记录在下图,可做参考。
2.__len__() / __iter__() / reset() :其他方法
由于其他方法定义都较为简单,统一记录在下。
三、build.build_dataloader方法:构建YOLO数据集加载器
有了上述类的准备后,就可以创建YOLO的数据加载器了,下面逐行记录了其对应代码含义和作用。可做参考。
下面整体实验一下上述代码。尝试自己搭建一个YOLO进行训练或验证的无限数据集加载器。测试代码和效果如下。
from ultralytics.cfg import cfg2dict
from ultralytics.data.dataset import YOLODataset
from ultralytics.data.build import build_dataloader
# 数据集生成
cocoyaml = './coco8/coco8.yaml'
cfg = cfg2dict(cocoyaml)
imgpath = './coco8/images'
dataset = YOLODataset(imgpath, data=cfg, task='detect', augment=False)
# 无限数据加载器
dataloader = build_dataloader(dataset=dataset, batch=4, workers=0, shuffle=False)
print(dataloader.sampler)
for batch in dataloader:
print(batch['im_file'])
break # 人为模拟中断
从下一篇文章开始,进入ultralytics的核心代码之一engine文件夹。该部分是实现模型训练、验证、预测、导出、超参数调优等等功能的基类定义区。首先来分析一个统一所有这些模型操作功能和不同任务的基类——Model类:
从壹开始解读Yolov11【源码研读系列】——核心源码部分:Engine.model.py——Model类:统一模型加载和功能(训练、验证、预测...)的基类-优快云博客