yolov8逐步分解(8)_训练过程之Epoch迭代前初始准备

yolov8逐步分解(1)--默认参数&超参配置文件加载

yolov8逐步分解(2)_DetectionTrainer类初始化过程

yolov8逐步分解(3)_trainer训练之模型加载

YOLOV8逐步分解(4)_模型的构建过程

YOLOV8逐步分解(5)_模型训练初始设置之混合精度训练AMP

YOLOV8逐步分解(6)_模型训练初始设置之image size检测batch预设及dataloder初始化

yolov8逐步分解(7)_模型训练初始设置之优化器Optimizer及学习率调度器Scheduler初始化

        本系列之前的文章1-7均为训练初始化过程,本章节将讲解训练过程的代码。

        这段代码是PyTorch训练循环实现的一部分。以下将对它进行逐步解释:

        _do_train函数负责主要的训练过程。它可以接受一个可选参数world_size,用于指定用于分布式数据并行(DDP)训练的GPU数量。

   def _do_train(self, world_size=1):"""Train completed, evaluate and plot if specified by arguments."""if world_size > 1: #当前world_size = 1,不采用多卡训练self._setup_ddp(world_size) #多卡训练配置self._setup_train(world_size)self.epoch_time = Noneself.epoch_time_start = time.time()self.train_time_start = time.time()nb = len(self.train_loader)  # number of batchesnw = max(round(self.args.warmup_epochs *nb), 100) if self.args.warmup_epochs > 0 else -1  # number of warmup iterations # 预热迭代次数last_opt_step = -1self.run_callbacks('on_train_start')#输出一些训练信息,如图像大小、数据加载器worker数量、日志保存路径等LOGGER.info(f'Image sizes {self.args.imgsz} train, {self.args.imgsz} val\n'f'Using {self.train_loader.num_workers * (world_size or 1)} dataloader workers\n'f"Logging results to {colorstr('bold', self.save_dir)}\n"f'Starting training for {self.epochs} epochs...')if self.args.close_mosaic:base_idx = (self.epochs - self.args.close_mosaic) * nbself.plot_idx.extend([base_idx, base_idx + 1, base_idx + 2])epoch = self.epochs  # predefine for resume fully trained model edge casesfor epoch in range(self.start_epoch, self.epochs):self.epoch = epochself.run_callbacks('on_train_epoch_start')self.model.train() #将模型设置为训练模式if RANK != -1:self.train_loader.sampler.set_epoch(epoch)pbar = enumerate(self.train_loader)# Update dataloader attributes (optional)if epoch == (self.epochs - self.args.close_mosaic): #最后10次训练关闭mosaic可以提升训练效果LOGGER.info('Closing dataloader mosaic')if hasattr(self.train_loader.dataset, 'mosaic'):self.train_loader.dataset.mosaic = Falseif hasattr(self.train_loader.dataset, 'close_mosaic'):self.train_loader.dataset.close_mosaic(hyp=self.args)self.train_loader.reset() #重置训练数据加载器的状态if RANK in (-1, 0):LOGGER.info(self.progress_string())pbar = tqdm(enumerate(self.train_loader), total=nb, bar_format=TQDM_BAR_FORMAT)self.tloss = Noneself.optimizer.zero_grad()#在反向传播过程中,梯度是累积的,而不是被替换掉。通过在每次迭代开始时将梯度清零,确保在当前迭代中计算梯度时是全新的,不会受到上一次迭代的梯度的影响。for i, batch in pbar:self.run_callbacks('on_train_batch_start')# Warmupni = i + nb * epoch #计算当前迭代的总步数if ni <= nw: #在训练的早期阶段逐渐调整学习率和动量参数,以帮助模型更好地收敛。这通常用于处理训练初期的不稳定性。xi = [0, nw]  # x interp 热身步数的起止范围self.accumulate = max(1, np.interp(ni, xi, [1, self.args.nbs / self.batch_size]).round()) # 控制梯度累积的步数,根据当前迭代步数 ni 在范围 xi 内进行插值计算,并将结果四舍五入。for j, x in enumerate(self.optimizer.param_groups):# Bias lr falls from 0.1 to lr0, all other lrs rise from 0.0 to lr0x['lr'] = np.interp(ni, xi, [self.args.warmup_bias_lr if j == 0 else 0.0, x['initial_lr'] * self.lf(epoch)])if 'momentum' in x:x['momentum'] = np.interp(ni, xi, [self.args.warmup_momentum, self.args.momentum])# Forwardwith torch.cuda.amp.autocast(self.amp):batch = self.preprocess_batch(batch)   #归一化 /255self.loss, self.loss_items = self.model(batch) #将预处理后的批次数据输入模型进行前向传播并获取损失值和其他损失项if RANK != -1:self.loss *= world_sizeself.tloss = (self.tloss * i + self.loss_items) / (i + 1) if self.tloss is not None \else self.loss_items# Backward#使用self.scaler对损失值进行缩放,并调用backward()方法进行反向传播。#这是自动混合精度(AMP)训练中的一步,用于计算梯度并将其传播回模型的参数self.scaler.scale(self.loss).backward()# Optimize - https://pytorch.org/docs/master/notes/amp_examples.htmlif ni - last_opt_step >= self.accumulate:self.optimizer_step()  #执行一步优化器的更新,根据之前计算得到的梯度来更新模型的参数。last_opt_step = ni# Logmem = f'{torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0:.3g}G'  # (GB) 计算cuda内存以GB为单位loss_len = self.tloss.shape[0] if len(self.tloss.size()) else 1losses = self.tloss if loss_len > 1 else torch.unsqueeze(self.tloss, 0)if RANK in (-1, 0): #使用格式化字符串将训练进度、GPU内存占用和损失值等信息展示在进度条中pbar.set_description(('%11s' * 2 + '%11.4g' * (2 + loss_len)) %(f'{epoch + 1}/{self.epochs}', mem, *losses, batch['cls'].shape[0], batch['img'].shape[-1]))self.run_callbacks('on_batch_end')if self.args.plots and ni in self.plot_idx:self.plot_training_samples(batch, ni)self.run_callbacks('on_train_batch_end')self.lr = {f'lr/pg{ir}': x['lr'] for ir, x in enumerate(self.optimizer.param_groups)}  # for loggersself.scheduler.step()self.run_callbacks('on_train_epoch_end')if RANK in (-1, 0):# Validationself.ema.update_attr(self.model, include=['yaml', 'nc', 'args', 'names', 'stride', 'class_weights'])final_epoch = (epoch + 1 == self.epochs) or self.stopper.possible_stop #判断是否为最后一个训练轮次或训练可能停止if self.args.val or final_epoch:self.metrics, self.fitness = self.validate()self.save_metrics(metrics={**self.label_loss_items(self.tloss), **self.metrics, **self.lr})self.stop = self.stopper(epoch + 1, self.fitness)# Save modelif self.args.save or (epoch + 1 == self.epochs): #判断是否需要保存模型self.save_model()self.run_callbacks('on_model_save')tnow = time.time()self.epoch_time = tnow - self.epoch_time_startself.epoch_time_start = tnowself.run_callbacks('on_fit_epoch_end')#清空GPU的显存。这个操作可以帮助释放GPU显存,以防止在训练过程中出现内存不足的错误。torch.cuda.empty_cache()  # clears GPU vRAM at end of epoch, can help with out of memory errors# Early Stoppingif RANK != -1:  # if DDP training 分布训练中广播停止给其他进程broadcast_list = [self.stop if RANK == 0 else None]dist.broadcast_object_list(broadcast_list, 0)  # broadcast 'stop' to all ranksif RANK != 0: #如果当前进程的RANK不为0,则将广播列表中的第一个对象(即进程0广播的self.stop)赋值self.stop = broadcast_list[0]if self.stop:break  # must break all DDP ranksif RANK in (-1, 0):# Do final val with best.ptLOGGER.info(f'\n{epoch - self.start_epoch + 1} epochs completed in 'f'{(time.time() - self.train_time_start) / 3600:.3f} hours.')self.final_eval() #2.执行最终的验证(final_eval())操作。if self.args.plots:self.plot_metrics()self.run_callbacks('on_train_end')torch.cuda.empty_cache()#清空GPU的显存self.run_callbacks('teardown')

1. 初始准备代码讲解

        """Train completed, evaluate and plot if specified by arguments."""if world_size > 1: #当前world_size = 1,不采用多卡训练self._setup_ddp(world_size) #多卡训练配置self._setup_train(world_size)self.epoch_time = Noneself.epoch_time_start = time.time()self.train_time_start = time.time()nb = len(self.train_loader)  # number of batchesnw = max(round(self.args.warmup_epochs *nb), 100) if self.args.warmup_epochs > 0 else -1  # number of warmup iterations # 预热迭代次数last_opt_step = -1self.run_callbacks('on_train_start')

1.1 首先检查world_size是否大于1,大于1表示正在使用DDP训练。如果是,它调用_setup_ddp方法来配置DDP设置。

1.2 调用_setup_train方法,该方法实现模型的加载初始化等过程,具体内容参考本系列文章《yolov8逐步分解(3)_trainer训练之模型加载》中的具体介绍。

1.3  接下来初始化一些与时间相关的变量:

        self.epoch_time: 将保存当前训练epoch的持续时间。

        self.epoch_time_start: 记录当前训练epoch的开始时间。

        self.train_time_start: 记录整个训练过程的开始时间。

1.4 训练加载器中的批次数量存储在nb变量中。

1.5 nw变量计算预热迭代的数量,它是以下三个值中的最大值:

        round(self.args.warmup_epochs * nb): 预热epoch数乘以每个epoch的批次数。

        100: 至少100个预热迭代。

        如果self.args.warmup_epochs是0或更小,nw被设置为-1,表示没有预热。

1.6 last_opt_step变量被初始化为-1。

1.7 最后,调用run_callbacks('on_train_start')方法,可能会触发训练开始时注册的任何回调函数。

总的来说,这段代码设置了训练循环的初始状态,为实际的训练迭代做好准备。

        LOGGER.info(f'Image sizes {self.args.imgsz} train, {self.args.imgsz} val\n'f'Using {self.train_loader.num_workers * (world_size or 1)} dataloader workers\n'f"Logging results to {colorstr('bold', self.save_dir)}\n"f'Starting training for {self.epochs} epochs...')if self.args.close_mosaic:base_idx = (self.epochs - self.args.close_mosaic) * nbself.plot_idx.extend([base_idx, base_idx + 1, base_idx + 2])epoch = self.epochs  # predefine for resume fully trained model edge cases

2.1 打印一些有关训练过程的信息:

        训练和验证时使用的图像尺寸

        用于数据加载的 worker 数量

        训练结果的保存路径

        训练将运行的 epoch 数

2.2 检查是否设置了 self.args.close_mosaic 参数。如果设置了,它会计算在最后 self.args.close_mosaic 个 epoch 中需要绘制的索引,并将它们添加到 self.plot_idx 列表中。这可能是为了在训练结束时绘制一些特定的图表或可视化效果。

2.3 将 epoch 变量设置为 self.epochs。这可能是为了处理在训练过程中恢复完全训练模型的边缘情况。

        这段代码旨在记录训练过程中的一些关键信息,以便更好地理解和监控模型的训练情况。它还可以为训练结束后的数据分析和可视化提供一些有用的信息。

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

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

相关文章

Flink系列六:Flink SQl 之常用的连接器(Connector)

一、动态表 & 连续查询(Continuous Query) 1、动态表&#xff08;Dynamic Tables&#xff09; 当流中有新数据到来&#xff0c;初始的表中会插入一行&#xff1b;而基于这个表定义的SQL查询&#xff0c;就应该在之前的基础上更新结果。这样得到的表就会不断地动态变化&…

SQL Developer 导入CSV数据

之前已经写过一篇文章&#xff1a;将文本文件导入Oracle数据库的简便方法&#xff1a;SQL Developer 本文是类似的&#xff0c;只不过使用的是官方提供的 CSV文件&#xff0c;确实是标准的CSV&#xff08;comma separated values&#xff09;。 COL1,COL2,COL3 "e40a9db…

2024年文艺文化与社会发展国际会议(ICLCSD 2024)

2024年文艺文化与社会发展国际会议 2024 International Conference on Literature, Culture and Social Development 【1】会议简介 2024年文艺文化与社会发展国际会议是一场汇集全球文艺文化和社会科学领域精英的盛会。本次会议以“文艺文化与社会发展”为主题&#xff0c;旨在…

新一代AI的崛起——GPT-4o深度评析

目录 引言 一、版本间的对比分析 1.1 GPT-4与GPT-4o 1.2 GPT-4o与GPT-3 二、GPT-4o的技术能力 2.1 多模态处理能力 2.2 强化学习与自监督学习 2.3 高效的推理能力 三、个人整体感受 3.1 使用体验 3.2 实际应用 四、未来展望 4.1 持续优化与创新 4.2 加强人机协作 …

[Java基础揉碎]坦克大战 java事件处理机制

目录 坦克大战游戏演示 ​编辑 为什么要写这个项目 java绘图坐标体系 java绘图技术 Graphics的常用方法 // 画直线 ​编辑 // 画矩形边框 // 画填充矩形 // 画填充椭圆 // 获取图片资源 // 写字 绘出坦克 新建一个tankgame包, 新建一个类Tank, 里面包含横…

01_初识微服务

文章目录 一、微服务概述1.1 什么是微服务1.2 对比微服务架构与单体架构1.3 微服务设计原则1.4 微服务开发框架1.5 简单理解分布式部署与集群部署 二、微服务的核心概念2.1 服务注册与发现2.2 微服调用&#xff08;通信&#xff09;2.3 服务网关2.4 服务容错2.5 链路追踪参考链…

前端科举八股文-VUE篇

前端科举八股文-VUE篇 Vue响应式的基本原理?computed和watch的区别computed和methods的区别Slot是什么 ? 作用域插槽是什么?组件缓冲keep-alive是什么&#xff1f; 讲讲原理v-if&#xff0c;v-show的区别v-modal如何实现双向绑定组件中的data属性为什么是一个函数而不是对象…

python SciPy 和 NumPy 版本冲突

UserWarning: A NumPy version >1.19.5 and <1.23.0 is required for this version of SciPy (detected version 1.17.2) warnings.warn(f"A NumPy version >{np_minversion} and <{np_maxversion}"在使用 Python 的科学计算库时&#xff0c;经常会遇到各…

CSAPP Lab04——Cache Lab大师手笔,匠心制作

浮沉浪似人潮 哪会没有思念 你我伤心到 讲不出再见 ——讲不出再见 完整代码见&#xff1a;CSAPP/cachelab-handout at main SnowLegend-star/CSAPP (github.com) Part A: Cache Simulator 这个lab描述背大锅&#xff0c;开始我是真有点没看懂题目的描述。特别是“M 20,1”“…

基于Nodejs的简易邮件SMTP服务器

仅用于内部开发环境无法访问邮件服务器的情况下&#xff0c;测试SMTP邮件发送有没有成功。收到邮件发送请求后仅打印内容和保存附件用于测试验证。 安装库 实验环境使用了Nodejs版本16。 npm install smtp-server mailparser JS版SMTP服务器代码 没有使用TSL/SSL&#xff0c…

构建大型语言模型(LLM)产品的实战指南

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

双击bat文件查看ip地址

echo off echo Running batch file as administrator...:: 下面这行是以管理员身份运行 ipconfig 命令&#xff0c;并将结果输出到控制台 cmd /c "ipconfig"echo Batch file execution completed. pause注意文件名不能为 ipconfig.bat 可以是 ipconfigs.bat 另一种…

【JavaScript】JS 的 btoa 和 atob 全局函数

在 JavaScript 中&#xff0c;btoa 和 atob 是两个处理 Base64 编码的全局函数&#xff0c;它们通常用于在浏览器环境中对二进制数据进行编码和解码。 不过&#xff0c;需要注意的是&#xff0c;这两个函数并非 JavaScript 标准规范&#xff08;ECMAScript&#xff09;的一部分…

MATLAB .m文件的命名规则

matlab的.m文件的命名规则&#xff1a; 文件名命名要用英文字符&#xff0c;首字符不能是数字或下划线。 文件名不能与matlab的内部函数名相同。 .m文件名的命名尽量不要是简单的英文单词&#xff0c;最好是由大小写英文/数字/下划线等组成。 原因是简单的单词命名容易与mat…

基于多尺度相关小波分解的单幅图像去雾和去噪方法(MATLAB)

小波变换具有优美的数学背景和强大的多分辨率分析能力。它集成和发展了短时傅里叶变换的思想并克服了其时间窗口不可变的缺点。小波变换通过使用具有局部感受野和多尺度的基函数。形成了同时具有局部和全局性质的信号表征。与DCT等全局变换相比&#xff0c;小波变换可以防止局部…

58、试除法求约数

试除法求约数 题目描述 给定n个正整数ai&#xff0c;对于每个整数ai,请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数n。 接下来n行&#xff0c;每行包含一个整数ai。 输出格式 输出共n行&#xff0c;其中第 i 行输出第 i 个整数ai的所有约数。 数据…

oracle查看序列

在Oracle数据库中&#xff0c;查看序列的方式主要有以下几种&#xff1a; 查看当前用户下的所有序列名称&#xff1a; sql复制代码 SELECT sequence_name FROM user_sequences; 查看所有用户的序列&#xff1a; sql复制代码 SELECT sequence_name FROM all_sequences; 查看…

Java面试八股之Executors可以创建哪几种类型的线程池

Executors可以创建哪几种类型的线程池 newSingleThreadExecutor&#xff1a; 创建一个单线程的线程池&#xff0c;此线程池确保所有的任务都在同一个线程中按顺序执行。适用于需要保证任务顺序执行&#xff0c;或者在单线程中运行的任务。 newFixedThreadPool&#xff1a; …

知识蒸馏——讨论区

更多内容请了解&#xff1a; 知识蒸馏——基础知识 知识蒸馏——学生模型 知识蒸馏——代码实现 知识蒸馏——讨论区 知识蒸馏——讨论区 一、教师模型的预测结果&#xff08;软标签&#xff09;与传统标签的区别&#xff1f;二、教师模型的软标签与真实标签的关系三、为什么学…

YOLOv5改进 | Conv篇 | 利用YOLOv10提出的UIB模块二次创新C3(附代码 + 完整修改教程)

一、本文介绍 本文给大家带来的改进机制是利用利用YOLOv10提出的UIB模块二次创新C3助力YOLOv5进行有效涨点,其中C2fUIB模块所用到的CIB模块是一种紧凑的倒置块结构,它采用廉价的深度卷积进行空间混合,并采用成本效益高的点卷积进行通道混合。本文针对该方法给出多种使用方法…