YOLOV8逐步分解(2)_DetectionTrainer类初始化过程
接上篇文章yolov8逐步分解(1)--默认参数&超参配置文件加载继续讲解。
1. 默认配置文件加载完成后,创建对象trainer时,需要从默认配置中获取类DetectionTrainer初始化所需的参数args,如下所示
def train(cfg=DEFAULT_CFG, use_python=False):"""Train and optimize YOLO model given training data and device."""model = cfg.model or 'yolov8n.pt'data = cfg.data or 'coco128.yaml' # or yolo.ClassificationDataset("mnist")device = cfg.device if cfg.device is not None else ''args = dict(model=model, data=data, device=device)if use_python:from ultralytics import YOLOYOLO(model).train(**args)else:trainer = DetectionTrainer(overrides=args) #初始化训练器trainer.train()
通过debug可以看到,如下所示,args值为指定模型和数据集
2. 使用上一步中获取的参数args,创建并初始化一个目标检测训练器trainer
trainer = DetectionTrainer(overrides=args)
3. DetectionTrainer类的初始化代码如下,下面我们将逐步讲解。
def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None):"""Initializes the BaseTrainer class.Args:cfg (str, optional): Path to a configuration file. Defaults to DEFAULT_CFG.overrides (dict, optional): Configuration overrides. Defaults to None.对配置文件/训练数据文件参数进行加载,关键信息判断处理解析,保证文件存在,不存在则下载等合法性检测,及值的初始化化操作"""self.args = get_cfg(cfg, overrides) #将overrides中的配置与cfg中的配置融合,返回SimpleNameSpace类型self.device = select_device(self.args.device, self.args.batch) #选择运行在CPU/GPU还是苹果推出的MPS库上self.check_resume() #判断是否基于之前的断点继续训练,如果是,则加载之前保存的数据参数self.validator = Noneself.model = Noneself.metrics = Noneself.plots = {}init_seeds(self.args.seed + 1 + RANK, deterministic=self.args.deterministic) #初始化随机数# Dirs 创建运行结果保存额目录及文件:创建本次训练的目录/ weights保存目录 /保存运行参数project = self.args.project or Path(SETTINGS['runs_dir']) / self.args.task #project: runs/detectname = self.args.name or f'{self.args.mode}' #name: 'train'if hasattr(self.args, 'save_dir'): #判断是否设置保存路径 ,如果没有则根据项目和任务名穿件保存目录self.save_dir = Path(self.args.save_dir)else:self.save_dir = Path(increment_path(Path(project) / name, exist_ok=self.args.exist_ok if RANK in (-1, 0) else True))self.wdir = self.save_dir / 'weights' # weights dir #runs/detect/train72/weighhtsif RANK in (-1, 0):self.wdir.mkdir(parents=True, exist_ok=True) # make dirself.args.save_dir = str(self.save_dir)yaml_save(self.save_dir / 'args.yaml', vars(self.args)) # save run args #保存运行参数self.last, self.best = self.wdir / 'last.pt', self.wdir / 'best.pt' # checkpoint pathsself.save_period = self.args.save_period #保存周期#设置 epoch次数 和 batch的大小self.batch_size = self.args.batchself.epochs = self.args.epochsself.start_epoch = 0if RANK == -1:print_args(vars(self.args))# Deviceif self.device.type == 'cpu':self.args.workers = 0 # faster CPU training as time dominated by inference, not dataloading# Model and Dataset 初始化模型文件 和数据集self.model = self.args.model #yolov8n.pttry:if self.args.task == 'classify': #分类任务self.data = check_cls_dataset(self.args.data)elif self.args.data.endswith('.yaml') or self.args.task in ('detect', 'segment'): #检测和分割任务self.data = check_det_dataset(self.args.data) #加载数据yaml文件,进行关键属性值检测,并进行路径转换,确保数据集文件存在,不存在则下载if 'yaml_file' in self.data:self.args.data = self.data['yaml_file'] # for validating 'yolo train data=url.zip' usageexcept Exception as e:raise RuntimeError(emojis(f"Dataset '{clean_url(self.args.data)}' error ❌ {e}")) from eself.trainset, self.testset = self.get_dataset(self.data) #初始化训练集测试集参数 获取路径self.ema = None# Optimization utils initself.lf = None #损失函数self.scheduler = None #学习率调整策略# Epoch level metrics 指标self.best_fitness = Noneself.fitness = Noneself.loss = None #当前损失值self.tloss = None #总损失值self.loss_names = ['Loss']self.csv = self.save_dir / 'results.csv'self.plot_idx = [0, 1, 2]# Callbacksself.callbacks = _callbacks or callbacks.get_default_callbacks()if RANK in (-1, 0):callbacks.add_integration_callbacks(self)
3.1 self.args = get_cfg(cfg, overrides) 该行主要实现功能为:
将默认配置参数从Simplenamespace转为字典后与overrides中的参数合并更新,进行一些参数的合法性检测后,再转换为Simplenamespace格式输出。
overrides该参数主要是用于更新默认加载的配置文件中model和data的值,默认配置中上述值均为None,如下图所示:
更新后的配置如下图所示:
3.2 self.device = select_device(self.args.device, self.args.batch) 功能为:
选择算法运行在CPU还是GPU上,参数batch用于检测设置的batch数值是否是GPU个数的整数倍,若不是整数倍则报错。
3.3 self.check_resume() :判断是否基于之前的断点继续训练,如果是,则加载之前保存的数据参数,本次默认配置参数该值为False.
3.4 接下来创建运行时的文件保存目录,包括本次训练的权重文件保存目录,并保存训练使用的参数以及checkPoint路径等。
# Dirs 创建运行结果保存目录及文件:创建本次训练的目录/ weights保存目录 /保存运行参数project = self.args.project or Path(SETTINGS['runs_dir']) / self.args.task #project: runs/detectname = self.args.name or f'{self.args.mode}' #name: 'train'if hasattr(self.args, 'save_dir'): #判断是否设置保存路径 ,如果没有则根据项目和任务名创建保存目录self.save_dir = Path(self.args.save_dir)else:self.save_dir = Path(increment_path(Path(project) / name, exist_ok=self.args.exist_ok if RANK in (-1, 0) else True))self.wdir = self.save_dir / 'weights' # weights dir #runs/detect/train72/weighhtsif RANK in (-1, 0):self.wdir.mkdir(parents=True, exist_ok=True) # make dirself.args.save_dir = str(self.save_dir)yaml_save(self.save_dir / 'args.yaml', vars(self.args)) # save run args #保存运行参数self.last, self.best = self.wdir / 'last.pt', self.wdir / 'best.pt' # checkpoint pathsself.save_period = self.args.save_period #保存周期
3.5 初始化batch/epoch等参数,这个一目了然,不在解释
3.6 初始化数据集(coco128.yaml),步骤如下:
3.6.1 检测传入的数据集参数’dataset’是否是yaml结尾文件
3.6.2 若是路径并且是压缩格式,则下载数据集配置文件
3.6.3 加载coco128.yaml,通过函数yaml_load()加载
def check_det_dataset(dataset, autodownload=True):"""Download, check and/or unzip dataset if not found locally."""data = check_file(dataset) #dataset: coco128.yaml #判断文件是否合法,如果不存在在下载,或者从本地搜索# Download (optional)extract_dir = ''if isinstance(data, (str, Path)) and (zipfile.is_zipfile(data) or is_tarfile(data)): #判断数据集是否时zip or tar压缩格式 #new_dir = safe_download(data, dir=DATASETS_DIR, unzip=True, delete=False, curl=False)data = next((DATASETS_DIR / new_dir).rglob('*.yaml'))extract_dir, autodownload = data.parent, False# Read yaml (optional)if isinstance(data, (str, Path)):data = yaml_load(data, append_filename=True) # dictionary #读取数据集yam文件 simplenamespace格式# Checks 必要参数检测for k in 'train', 'val':if k not in data: #如果数据中既不包含 train也不包含 val,则报错raise SyntaxError(emojis(f"{dataset} '{k}:' key missing ❌.\n'train' and 'val' are required in all data YAMLs."))if 'names' not in data and 'nc' not in data:raise SyntaxError(emojis(f"{dataset} key missing ❌.\n either 'names' or 'nc' are required in all data YAMLs."))if 'names' in data and 'nc' in data and len(data['names']) != data['nc']:raise SyntaxError(emojis(f"{dataset} 'names' length {len(data['names'])} and 'nc: {data['nc']}' must match."))if 'names' not in data: #如果没有names则,用数字代替data['names'] = [f'class_{i}' for i in range(data['nc'])]else:data['nc'] = len(data['names'])data['names'] = check_class_names(data['names']) #检测data['names']是否是dict,以及将key转换为数字# Resolve pathspath = Path(extract_dir or data.get('path') or Path(data.get('yaml_file', '')).parent) # dataset rootif not path.is_absolute():path = (DATASETS_DIR / path).resolve() #转化为绝对路径data['path'] = path # download scriptsfor k in 'train', 'val', 'test': #全部转换为绝对路径if data.get(k): # prepend pathif isinstance(data[k], str):x = (path / data[k]).resolve()if not x.exists() and data[k].startswith('../'):x = (path / data[k][3:]).resolve()data[k] = str(x)else:data[k] = [str((path / x).resolve()) for x in data[k]]# Parse yamltrain, val, test, s = (data.get(x) for x in ('train', 'val', 'test', 'download'))if val:val = [Path(x).resolve() for x in (val if isinstance(val, list) else [val])] # val pathif not all(x.exists() for x in val): #不存在则下载name = clean_url(dataset) # dataset name with URL auth strippedm = f"\nDataset '{name}' images not found ⚠️, missing paths %s" % [str(x) for x in val if not x.exists()]if s and autodownload:LOGGER.warning(m)else:m += f"\nNote dataset download directory is '{DATASETS_DIR}'. You can update this in '{SETTINGS_YAML}'"raise FileNotFoundError(m)t = time.time()if s.startswith('http') and s.endswith('.zip'): # URLsafe_download(url=s, dir=DATASETS_DIR, delete=True)r = None # successelif s.startswith('bash '): # bash scriptLOGGER.info(f'Running {s} ...')r = os.system(s)else: # python scriptr = exec(s, {'yaml': data}) # return Nonedt = f'({round(time.time() - t, 1)}s)'s = f"success ✅ {dt}, saved to {colorstr('bold', DATASETS_DIR)}" if r in (0, None) else f'failure {dt} ❌'LOGGER.info(f'Dataset download {s}\n')check_font('Arial.ttf' if is_ascii(data['names']) else 'Arial.Unicode.ttf') # download fontsreturn data # dictionary
其中,data = yaml_load(data, append_filename=True)加载完成后,data内容如下:
注意:’nc’:80 是通过 data['nc'] = len(data['names']) 后添加的。
3.6.4 将data中的路径全部转换为绝对路径
for k in 'train', 'val', 'test': #全部转换为绝对路径if data.get(k): # prepend pathif isinstance(data[k], str):x = (path / data[k]).resolve()if not x.exists() and data[k].startswith('../'):x = (path / data[k][3:]).resolve()data[k] = str(x)else:data[k] = [str((path / x).resolve()) for x in data[k]]
转换完成并更新data后,data的内容如下,其中train,val,test等键的值变为了绝对路径:
3.6.5 获取训练集、测试集、验证集、以及下载路径
train, val, test, s = (data.get(x) for x in ('train', 'val', 'test', 'download'))
3.6.6 最終返回data,数据类型为字典,完成对coco128.yaml文件的加载解析及校验工作。
3.7 获取训练集和验证集的路径
self.trainset, self.testset = self.get_dataset(self.data) #初始化训练集测试集参数 获取路径
其中,获取路径方法函数实现过程如下:
def get_dataset(data):"""Get train, val path from data dict if it exists. Returns None if data format is not recognized."""return data['train'], data.get('val') or data.get('test')
3.8 其他学习率、损失函数等都设置为None
self.ema = None# Optimization utils initself.lf = None #损失函数self.scheduler = None #学习率调整策略# Epoch level metrics 指标self.best_fitness = Noneself.fitness = Noneself.loss = None #当前损失值self.tloss = None #总损失值self.loss_names = ['Loss']self.csv = self.save_dir / 'results.csv'self.plot_idx = [0, 1, 2]
3.9 设置用于结果展示获取的一些回调函数
# Callbacksself.callbacks = _callbacks or callbacks.get_default_callbacks()if RANK in (-1, 0):callbacks.add_integration_callbacks(self)
至此,trainer的初始化过程解析完成。
总结,本章详细介绍了yolov8训练器trainer的初始化过程,讲解参数的加载替换过程,着重讲解了coco128数据集的加载解析及校验,最后介绍了损失函数学习率的初始化。
相关文章:
YOLOV8逐步分解(2)_DetectionTrainer类初始化过程
接上篇文章yolov8逐步分解(1)--默认参数&超参配置文件加载继续讲解。 1. 默认配置文件加载完成后,创建对象trainer时,需要从默认配置中获取类DetectionTrainer初始化所需的参数args,如下所示 def train(cfgDEFAULT_CFG, use_pythonFalse…...
Java是用什么语言写的?PHP呢?
Java底层是C语言。 Sun公司研发人员根据嵌入式软件的要求,对C进行了改造,去除了留在C的一些不太实用及影响安全的成分,并结合嵌入式系统的实时性要求,开发了一种称为Oak的面向对象语言。而后,经过迭代更新,…...
SpringBoot Redis的使用
官方文档: 官方文档:Spring Data Redis :: Spring Data Redis 和jedis一样,SpringBoot Redis 也可以让我在Java代码中使用redis,同样也是通过引入maven依赖的形式。 加速访问github: 使用steam可以免费加速访问github Spring…...
数据仓库——维度表特性
企业信息化工厂 数据集市中的一致性,由于企业信息化工厂的数据集市是从集成仓库中获得信息的,因此至少从维度建模的角度来看,一致性维护的问题减少了。尽管合并不同数据源的问题依然在,但是负担主要在设计者身上。尽管压力降低了…...
从电荷角度理解开关电容中的电荷守恒
目录 一些铺垫电容的电荷量的解释电荷流入流出对节点电压的影响 从电荷角度理解开关电容加法器中的电荷守恒以开关电容积分器为例说明什么样的节点是电荷守恒 一些铺垫 电容的电荷量的解释 对于一个1F的电容,当它的压差为1V时,它所携带的电荷量是QCU1库…...
1.7.1 python 作业 15道
1、求出1 / 1 1 / 3 1 / 5……1 / 99的和 (1分之一1分之三1分支5....) sum0 for i in range(1,100,2): sum 1/i sum; print(sum) 2、用循环语句,计算2 - 10之间整数的循环相乘的值 (2*3*4*5....10) sum 1 for i in range(2,11): sum sum *…...
synchronized 和 ReentrantLock 的区别是什么
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:synchronized 和 ReentrantLock 的区别是什么 1. 获取锁的方式 synchronized:synchronized的锁获取是隐式的。当线程进入synchronized修饰的代码…...
大话设计模式之迪米特法则
迪米特法则,也称为最少知识原则(Law of Demeter),是面向对象设计中的一个重要原则,其核心思想是降低耦合度、减少对象之间的依赖关系,从而使系统更加灵活、易于维护和扩展。 根据迪米特法则,一…...
KSD测试系统使用方法和注意事项
①下载链接在最顶部; ②安装方法:应该先将测试设备绑定在假人身上,测试设备不能过度往下拉,传感器绑在脖子上,切记最后才开传感器开关!!!开传感器后3秒内不要碰测试设备衣服&#x…...
IT服务营销管理案例分析题
习题一 企业随着业务的蓬勃发展,所投入的基础设施资源不断增加。企业员工数倍数增长,办公场地、办公环境等要求也越来越高。 可是该企业的IT部门人员短缺,对IT管理还处于被动的“救火”阶段,每天至少15个突发故障,故障…...
NRF52832修改OTA升级时的bootloader蓝牙MAC
NRF52832在OTA升级时,修改了APP的蓝牙MAC会导致无法升级,原因是OTA程序的蓝牙MAC没有被修改所以手机扫描蓝牙时无法连接 解决办法 在bootloader的程序里面加入修改蓝牙mac地址的代码实现原理: 在bootloader蓝牙广播开启之前修改蓝牙mac 通…...
# Python 编程入门教程
欢迎来到 Python 编程入门教程!Python 是一种简单易学、功能强大的编程语言,适用于各种应用场景,从简单的脚本到大型软件开发项目。无论你是初学者还是有一定编程经验的开发者,本教程都将为你提供全面的学习路径,帮助你掌握 Python 编程的基础知识和技能。 ## 目录 1. 简…...
Sqoop【实践 02】Sqoop1最新版 全库导入 + 数据过滤 + 字段类型支持 说明及举例代码(query参数及字段类型强制转换)
Sqoop1最新版举例 1.环境说明2.import-all-tables3.query4.字段类型支持 1.环境说明 还是之前的环境: # 不必要信息不再贴出 # JDK [roottcloud ~]# java -version java version "1.8.0_251" # MySQL [roottcloud ~]# mysql -V mysql Ver 14.14 Distrib…...
第十四届蓝桥杯JavaA组省赛真题 - 特殊日期
解题思路: 暴力秒了 public class Main {public static void main(String[] args) {int cnt 0;for (int i 1900; i < 9999; i) {for (int j 1; j < 12; j) {for (int k 1; k < days(i, j); k) {if (sum(i) sum(j) sum(k)) cnt;}}}System.out.print…...
《VulnHub》Lampião:1
title: 《VulnHub》Lampio:1 date: 2024-03-28 21:37:49 updated: 2024-03-28 21:37:50 categories: WriteUp:Cyber-Range excerpt: 关键技术:主机发现,端口扫描、服务探测、操作系统探测,对开放的端口探测漏洞&#x…...
RabbitMq高可用
消息队列高级 服务异步通信-高级篇1.消息可靠性1.1.生产者消息确认1.2.消息持久化1.3.消费者消息确认1.4.消费失败重试机制1.5.总结 2.死信交换机2.1.初识死信交换机2.2.TTL2.3.延迟队列 3.惰性队列3.1.消息堆积问题3.2.惰性队列 4.MQ集群4.1.集群分类4.2.普通集群4.3.镜像集群…...
降本增效的车间管理大屏,车间主任看了拍手称快,速来领取。
我们老板觉得车间生产效率太低了,还想让我整一套车间管理的! 制造业管理的核心在于降本增效,车间管理可以通过【大数据可视化】来提高管理效率,大屏就可以做到生产管理一「屏」了然,这是【车间管理大屏方案】。 一、…...
Open AI要给GPT应用开发者“发钱” 黄金的宏观关系被打破了吗?
内容摘要 为避免GPTs彻底凉凉,Open AI紧急启动了一项“货币化”计划,直接给那些在GPT Store上的应用开发人员发钱。 正文部分 当地时间周四凌晨,OpenAI在社交媒体上发帖称,正在与小部分美国开发者合作,基于用户使用…...
【Docker】Docker安全与最佳实践:保护你的容器化应用程序
欢迎来到英杰社区: https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区: https://bbs.csdn.net/topics/617897397 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步ÿ…...
QT 信号(Signal)与槽(Slot)机制
上学后,人们问我长大了要做什么,我写下“快乐”。他们告诉我,我理解错了题目,我告诉他们,他们理解错了人生。 ——约翰列侬 一、信号(signal)与槽(slot) 在QT中,信号(signal)与槽(slot)机制是一种用于对象间通信的重要机制。它允许一个对象发出信号,而其他对象…...
音频干扰检测(频域方法)
测试音响系统的通路上是否有外部干扰时,可以通过播放1000赫兹的正弦波信号,在输出端采集数字信号(I2S,TDD,A2B)并保存为.wav文件。 然后通过以下Python代码检测。 import numpy as np import librosa im…...
Rust引用借用 vs 原始指针
let v: i32 10; let v1 &v; let a: *const i32 &v; println!("a{:p}", a); let b a as *mut i32; //无法从&v直接转换成*mut i32,需要从*const i32过度 println!("b{:p}", b); unsafe {*b1; } println!("v{} v1{}"…...
抖音视频关键词无水印下载软件|手机网页视频批量提取工具
全新视频关键词无水印下载软件,助您快速获取所需视频! 随着时代的发展,视频内容已成为人们获取信息和娱乐的重要途径。为了方便用户获取所需视频,推出了一款功能强大的视频关键词无水印下载软件。该软件主要功能包括关键词批量提取…...
关于Devc++调试的问题以及解决STL变量无法查看
目前Devc的调试主要有以下几点: 1.调试不能直接查看stl变量,会卡死不动 2.目前单步进入只能用鼠标键按 3.若想按下一步进入函数体内,要在函数体内打上断点才行 4.调试到return 0 ;上一句就停了,不会结束程序 5.目前F2跳至断点…...
MATLAB:优化与规划问题
一、线性规划 % 线性规划(Linear programming, 简称LP) fcoff -[75 120 90 105]; % 目标函数系数向量 A [9 4 7 54 5 6 105 10 8 53 8 9 77 6 4 8]; % 约束不等式系数矩阵 b [3600 2900 3000 2800 2200]; % 约束不等式右端向量 Aeq []; % 约束等式系…...
Oracal执行计划解析
概述 | Id | Operation | Name | Rows | Bytes | TempSpc | Cost (%CPU) | Time | ----------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1…...
对form表单对象中数组中的字段进行校验的方法
当对form表单中,数组readings中的字段进行校验时,prop和rules绑定要写成动态的,如下代码 <div v-for"(item,index) in form.readings"><el-form-item label"上次读数" > <!--prop"scds"-->…...
一、JAVA集成海康SDK
JAVA集成海康SDK 文章目录 JAVA集成海康SDK前言一、项目依赖 jar1. examples.jar2. 项目依赖 jna.jar,可以通过 maven依赖到。二、集成SDK1.HcNetSdkUtil 海康 SDK封装类2.HCNetSDK3.Linux系统集成SDK三、总结前言 提示:首先去海康官网下载 https://open.hikvision.com/dow…...
PAT 乙级 1031 查验身份证 c语言实现
一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1&am…...
LeetCode 345. 反转字符串中的元音字母
给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。 元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现不止一次。 示例 1: 输入:s “hello” 输出:“holl…...
主题之家wordpress/百度点击器找名风
前几天有朋友问到歌词滚动应该怎么做,针对歌词滚动这个功能做了一个简单的案例,仅供参考,大家如果有更好的做法记得call我们一下!按照惯例,我们先看一下这个效果是怎样的点这里预览:https://o0piel.axshare…...
萍乡网站推广/手机seo关键词优化
{*rule !important}这个css规则当今在网页制作的时候的普及已经非常流行了,以前我对它的理解就停留在‘浏览器是否识别阶段’ 而没有真正去研究过,可是现在发生了变化。众所周知,!important这个规则对Ie6.0,Ie7.0和Firefox能写hack࿰…...
做个商城网站要多少钱/杭州推广系统
问题截图: 添加#include<sys/mman.h>头文件可解决’PROT_WRITE’、‘MAP_SHARED’、未定义的问题。 现在还剩O_RDRW未定义的问题。 我再想想吧 先(~ ~) 这问题出现的原因是对应库文件的缺失,添加相应的库文件即可,但是我查了查资料后…...
网站建设商标在哪个类别/西安关键词快速排名
Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的,也就是说实体类都要自己写。可以实现数据到对象的ORM操作,体积小速度快(性能不错),…...
zblog好还是wordpress/品牌营销策划有限公司
最后一步MAPPING 是指向本地代码的存放路径...
福州seo建站/优化关键词排名公司
2019独角兽企业重金招聘Python工程师标准>>> 摘要:本文要用Maven来构建一个多模块的web项目 项目结构如下: system-parent |----pom.xml |----system-domain |----pom.xml |---…...