物体检测-系列教程28:YOLOV5 源码解析18(训练脚本解读:训练函数4)

😎😎😎物体检测-系列教程 总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
点我下载源码

24、epoch循环训练------更新、评估、保存

这部分是训练过程的每个epoch结束之前执行的一系列操作,主要包括学习率调整、模型评估、日志记录、模型保存等

	# Scheduler
    scheduler.step()
    # DDP process 0 or single-GPU
    if rank in [-1, 0]:
        # mAP
        if ema is not None:
            ema.update_attr(model, include=['yaml', 'nc', 'hyp', 'gr', 'names', 'stride'])
        final_epoch = epoch + 1 == epochs
        if not opt.notest or final_epoch:  # Calculate mAP
            results, maps, times = test.test(opt.data,
                                             batch_size=total_batch_size,
                                             imgsz=imgsz_test,
                                             model=ema.ema.module if hasattr(ema.ema, 'module') else ema.ema,
                                             single_cls=opt.single_cls,
                                             dataloader=testloader,
                                             save_dir=log_dir)

        # Write
        with open(results_file, 'a') as f:
            f.write(s + '%10.4g' * 7 % results + '\n')  # P, R, mAP, F1, test_losses=(GIoU, obj, cls)
        if len(opt.name) and opt.bucket:
            os.system('gsutil cp %s gs://%s/results/results%s.txt' % (results_file, opt.bucket, opt.name))

        # Tensorboard
        if tb_writer:
            tags = ['train/giou_loss', 'train/obj_loss', 'train/cls_loss',
                    'metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95',
                    'val/giou_loss', 'val/obj_loss', 'val/cls_loss']
            for x, tag in zip(list(mloss[:-1]) + list(results), tags):
                tb_writer.add_scalar(tag, x, epoch)

        # Update best mAP
        fi = fitness(np.array(results).reshape(1, -1))  # fitness_i = weighted combination of [P, R, mAP, F1]
        if fi > best_fitness:
            best_fitness = fi

        # Save model
        save = (not opt.nosave) or (final_epoch and not opt.evolve)
        if save:
            with open(results_file, 'r') as f:  # create checkpoint
                ckpt = {'epoch': epoch,
                        'best_fitness': best_fitness,
                        'training_results': f.read(),
                        'model': ema.ema.module if hasattr(ema, 'module') else ema.ema,
                        'optimizer': None if final_epoch else optimizer.state_dict()}

            # Save last, best and delete
            torch.save(ckpt, last)
            if best_fitness == fi:
                torch.save(ckpt, best)
            del ckpt
  1. 更新学习率调度器的状态,根据预定的策略(如学习率衰减)调整学习率,以帮助模型更好地收敛
  2. 如果不是分布式训练或者在分布式训练的主进程:
  3. 如果使用了指数移动平均(EMA)模型,将更新EMA模型的属性:
  4. 更新EMA模型的属性,包括模型配置(yaml)、类别数量(nc)、超参数(hyp)、损失比例(gr)、类别名称(names)和步长(stride),这是为了确保EMA模型与训练模型保持同步
  5. final_epoch ,判断当前epoch是否是训练的最后一个epoch,确定何时执行一些只在训练结束时需要进行的操作(如保存模型)非常关键
  6. 如果设置为在每个epoch结束时都进行测试(notest为False)或者当前是最后一个epoch,则执行模型测试
  7. 从测试脚本中调用测试函数,进行模型评估。计算模型在测试集上的性能指标,包括精度、召回率和mAP等。根据是否使用EMA以及是否在模型上使用了DataParallel或DistributedDataParallel,选择适当的模型进行评估
  8. 打开测试文件
  9. 将测试结果写入到指定的文件中,results_file是存储结果的文件路径,s是包含训练信息的字符串,results包含了测试指标的值
  10. 如果指定了云存储桶(bucket)和文件命名(name)
  11. 将结果文件上传到云存储
  12. 如果配置了TensorBoard日志记录器
  13. 定义一组标签,用于在TensorBoard中组织不同的训练和验证指标
  14. 遍历每个指标及其对应的标签
  15. 使用TensorBoard的add_scalar函数记录这些指标,在TensorBoard中进行可视化
  16. fi ,调用辅助函数fitness计算一个综合性能指标(称为"fitness"),它基于测试结果(例如精度、召回率、mAP等)
  17. 如果当前epoch的fitness分数高于迄今为止的最佳分数,则
  18. best_fitness ,更新最佳fitness分数
  19. save ,决定是否保存模型。如果不是显式地设置为不保存模型(nosave为False),或者当前是最后一个epoch并且没有进行模型进化(evolve为False),则保存模型
  20. 如果满足保存模型的条件:
  21. 读取并保存当前模型的状态,包括epoch数、最佳fitness分数、训练结果、模型本身以及优化器的状态(如果不是最后一个epoch)
  22. 将模型的状态保存到文件中。last变量代表最后一个checkpoint的文件名
  23. 如果当前模型的fitness等于最佳fitness,则
  24. 将其保存为最佳模型的checkpoint
  25. 删除临时保存的模型状态字典,释放内存

这部分展示了在训练过程中每个epoch结束之前执行的关键步骤,包括更新学习率、评估模型性能、记录和保存结果、以及条件性地保存模型的状态。这些步骤对于监控训练进度、评估模型性能和保证训练过程的可重现性非常重要

25、结束epoch循环训练的后续处理

这部分主要涉及在训练结束的清理和保存工作,包括重命名和保存训练结果、模型状态、上传权重到云存储、绘制结果图表和清理资源等

    if rank in [-1, 0]:
        # Strip optimizers
        n = ('_' if len(opt.name) and not opt.name.isnumeric() else '') + opt.name
        fresults, flast, fbest = 'results%s.txt' % n, wdir + 'last%s.pt' % n, wdir + 'best%s.pt' % n
        for f1, f2 in zip([wdir + 'last.pt', wdir + 'best.pt', 'results.txt'], [flast, fbest, fresults]):
            if os.path.exists(f1):
                os.rename(f1, f2)  # rename
                ispt = f2.endswith('.pt')  # is *.pt
                strip_optimizer(f2) if ispt else None  # strip optimizer
                os.system('gsutil cp %s gs://%s/weights' % (f2, opt.bucket)) if opt.bucket and ispt else None  # upload
        # Finish
        if not opt.evolve:
            plot_results(save_dir=log_dir)  # save as results.png
        logger.info('%g epochs completed in %.3f hours.\n' % (epoch - start_epoch + 1, (time.time() - t0) / 3600))

    dist.destroy_process_group() if rank not in [-1, 0] else None
    torch.cuda.empty_cache()
    return results
  1. 如果不是分布式训练或者是分布式训练的主进程:
  2. n,构造文件名的前缀。如果用户提供了命名(opt.name)且名称不是全数字,则在名称前加上下划线;否则直接使用名称。这有助于生成更具可读性和组织性的文件名
  3. fresults, flast, fbest,基于上一步得到的名称前缀n,构造结果文件、最后一个模型状态文件和最佳模型状态文件的完整路径
  4. 使用for循环结合zip函数遍历原始文件名和新文件名的列表,f1是原始文件名,f2是新文件名
  5. 如果原始文件(f1)存在
  6. 则将其重命名为新的文件名(f2),保持文件命名的一致性和可识别性
  7. ispt ,判断文件是否是.pt格式的模型文件,对于接下来是否执行某些特定操作(如剥离优化器状态)很关键
  8. 如果文件是.pt格式的模型文件,则执行辅助函数strip_optimizer,从模型文件中移除优化器的状态。这可以减小文件大小,便于分享或部署模型
  9. 如果指定了云存储桶(opt.bucket)且文件是模型文件,则使用gsutil cp命令将文件上传到云存储桶中。这便于模型的远程存储和访问
  10. 如果不是在执行进化训练(opt.evolve)
  11. 调用辅助函数plot_results,在指定的日志目录中保存训练结果的图表(通常为results.png),有助于可视化训练过程
  12. 记录一条日志信息,训练完成,包括完成的epochs数和总耗时(以小时计)
  13. 如果当前进程是分布式训练中的非主进程,则销毁进程组。这是分布式训练结束时的清理工作,有助于正确地关闭分布式训练环境
  14. 清空CUDA缓存。这有助于释放未使用的GPU内存,使其可用于其他应用程序
  15. 返回训练过程中的最终结果,包括模型性能指标等重要信息
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器学习杨卓越

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值