Bootstrap

【简单更改代码】YOLOv8实现断点恢复训练、增加训练轮次、减少训练轮次

目录

一、认识相关参数

1、YOLO模型中best.pt和last.pt的区别:(训练选择last.pt)

2、用于训练YOLOv8模型的,具体参数含义

二、使用官方脚本命令训练(含代码对比)

1、还未训练完所有epoch,希望继续训练。

2、已经训练完所有epoch,希望增加训练epoch。

三、使用python脚本训练(含代码对比)

1、还未训练完所有epoch,希望继续训练。

2、已训练完所有epoch,增加训练epoch。

四、减少训练轮次

1、方法

(1)修改self.epochs训练轮次

(2)更改resume路径

(3)添加一行ckpt的值

(4)重新运行训练代码

2、训练结果

3、跟原训练代码对比

注意:训练结束一定要还原trainer.py代码!!!!

参考资料:


一、认识相关参数

1、YOLO模型中best.pt和last.pt的区别:(训练选择last.pt)

权重文件权重来源权重特点适用场景
best.pt训练过程中每个epoch结束对验证集评估,取表现最好的模型权重代表验证集上的最优表现推理(如预测目标)和部署(如将模型应用到实际项目)阶段,以获取最佳性能
last.pt最后一次训练迭代结束后的模型权重是最后训练时刻的模型权重状态用于在之前训练基础上继续训练模型,从上次训练结束点接着进行训练

2、用于训练YOLOv8模型的,具体参数含义

参数含义
data数据,是模型训练的基础,包括训练集、验证集和测试集等。数据的多样性(如图像、文本等)和质量会直接影响模型的性能。
model模型,是对现实世界中问题的数学抽象,定义了输入和输出之间的关系。在PyTorch中,模型通常是一个继承自nn.Module的类,包含了网络结构和参数。
project项目,是指为了实现特定目标而进行的一系列有组织的活动,包括数据收集、模型选择、训练、评估和部署等步骤。
epochs轮次,指模型对整个数据集进行一次完整训练的次数。增加epochs可以提高模型的拟合能力,但过多的epochs可能导致过拟合。
pretrained预训练,指模型在大规模数据集上进行预训练,学习到通用的特征表示,然后在特定任务上进行微调。预训练模型可以显著提高模型的性能,尤其是在数据量较小的情况下。
resume恢复,指从之前保存的模型状态继续训练,而不是从头开始。这在训练中断或需要进一步优化模型时非常有用.

注意:减少训练轮次需更改triner.py配置文件,单独放在本文第四节进行介绍。

二、使用官方脚本命令训练(含代码对比)

通常的YOLO训练命令如下:(总共训练100epoch):

yolo task=detect mode=train model=yolov8n.pt data=coco128.yaml epochs=100

这个命令会启动一个YOLOv8的目标检测任务,使用yolov8n.pt作为预训练模型,coco128.yaml作为数据集配置文件,训练100个轮次。 

1、还未训练完所有epoch,希望继续训练。

  • 方法:将model替换为训练中途的last.pt文件,并且添加resume=True。

  • 结果:模型将会从断点处开始训练直到100epoch结束。

yolo task=detect mode=train model=runs/detect/exp/weights/last.pt data=coco128.yaml epochs=100 resume=True
  • 跟原训练代码对比:

参数断点重续前断点重续后
modelyolov8n.ptruns/detect/exp/weights/last.pt
resume未指定(默认为False)True

2、已经训练完所有epoch,希望增加训练epoch。

  • 方法:将epochs替换为10(表示继续训练10次),并且将已有的权重进行加载。

  • 结果:模型将会加载第100个epoch时的模型权重,但是会显示从0epoch开始训练。

yolo task=detect mode=train model=runs/detect/exp/weights/last.pt data=coco128.yaml epochs=10 pretrained=True
  •  跟原训练代码对比:

参数训练结束后继续增加epoch轮次后
modelyolov8n.ptruns/detect/exp/weights/last.pt
epochs10010
pretrained未指定(默认为False)True

三、使用python脚本训练(含代码对比)

训练时的命令(总共训练50epoch):

from ultralytics import YOLO

if __name__ == '__main__':
    # 从零开始构建新模型
    model = YOLO("yolov8n.pt")
    # 训练模型
    model.train(data="rooftop202411215new.yaml",epochs=50,device=0)
    # 在验证集上评估模型性能
    metrics = model.val()
    # 将模型导出为ONNX格式
    path = model.export(format="onnx")

这个命令会启动一个YOLOv8的目标检测任务,使用yolov8n.pt作为预训练模型,rooftop202411215.yaml作为数据集配置文件,训练50个轮次。

1、还未训练完所有epoch,希望继续训练。

  • 方法:将model替换为训练中途的last.pt文件,并且添加resume=True。

  • 结果:模型将会从断点处开始训练直到50epoch结束,显示从上一次断点epoch开始。

from ultralytics import YOLO

if __name__ == '__main__':
    # 从零开始构建新模型
    model = YOLO("E:/yolov8_test/yolov8_test/ultralytics-main/ultralytics-main/runs/segment/train4/weights/last.pt")
    # 训练模型
    model.train(data="rooftop202411215new.yaml",epochs=50,device=0,resume=True)
    # 在验证集上评估模型性能
    metrics = model.val()
    # 将模型导出为ONNX格式
    path = model.export(format="onnx")

  •  跟原训练代码对比:

参数断点重续前断点重续后
modelyolov8n.pt.../runs/detect/exp/weights/last.pt
resume未指定(默认为False)True

2、已训练完所有epoch,增加训练epoch。

  • 方法:将已有的权重进行加载,再将epochs替换为5,pretrained=True。

  • 结果:模型将会在已有权重的基础上再加载训练5个epoch,显示从0epoch开始训练。

from ultralytics import YOLO

if __name__ == '__main__':
    # 从零开始构建新模型
    model = YOLO("E:/yolov8_test/yolov8_test/ultralytics-main/ultralytics-main/runs/segment/last.pt")
    # 训练模型
    model.train(data="rooftop202411215new.yaml",epochs=5,device=0,pretrained=True)
    # 在验证集上评估模型性能
    metrics = model.val()
    # 将模型导出为ONNX格式
    path = model.export(format="onnx")

  • 跟原训练代码对比:

参数训练结束后继续增加epoch轮次后
modelyolov8n.pt.../runs/detect/exp/weights/last.pt
epochs505(表示再增加5次训练)
pretrained未指定(默认为False)True

四、减少训练轮次

训练代码如下:(减少训练轮次无需更改原训练代码

from ultralytics import YOLO

if __name__ == '__main__':
    # 从零开始构建新模型
    model = YOLO("ultralytics/cfg/models/v8/yolov8n.yaml")  # 从零开始构建新模型
    # 训练模型
    model.train(data="rooftop202411215new.yaml",epochs=10,device=0)
    # 在验证集上评估模型性能
    metrics = model.val()
    # 将模型导出为ONNX格式
    path = model.export(format="onnx")

这个命令会启动一个YOLOv8的目标检测任务,使用yolov8n.pt作为预训练模型,rooftop202411215.yaml作为数据集配置文件,训练10个轮次。

下面会介绍在训练时或者训练中断后想减少训练轮次的方法、训练结果、训练代码对比(不变):

1、方法

(1)修改self.epochs训练轮次

在ultralytics/yolo/engine/trainer.py中找到def__init,并在其中找到self.epochs = self.args.epochs进行注释,重新修改self.epochs成自己需要的轮次。

  • 如下是我把原本的10次训练减少到5次训练:

(2)更改resume路径

在ultralytics/yolo/engine/trainer.py中找到check_resume,并在其中找到resume = self.args.resume进行注释·,重新修改resume成需要断点恢复的last.pt路径。

  • 如下是我把resume修改成需要断点恢复的last.pt绝对路径:

(3)添加一行ckpt的值

在ultralytics/yolo/engine/trainer.py中找到resume_training,在resume_training里面添加一行ckpt的值,让ckpt指向需要断点恢复的last.pt路径。

  • 如下是我把ckpt指向需要断点恢复的last.pt绝对路径:

(4)重新运行训练代码

完成前面3个步骤后,可点击运行trainer.py,报错也无所谓,再重新运行python训练脚本即可。

  • 如下是我直接重新运行之前的训练脚本,可以看到所有参数都无需更改:
from ultralytics import YOLO

if __name__ == '__main__':
    # 从零开始构建新模型
    model = YOLO("ultralytics/cfg/models/v8/yolov8n.yaml")  # 从零开始构建新模型
    # 训练模型
    model.train(data="rooftop202411215new.yaml",epochs=10,device=0)
    # 在验证集上评估模型性能
    metrics = model.val()
    # 将模型导出为ONNX格式
    path = model.export(format="onnx")

 2、训练结果

        训练结果会继续保存在重续前的文件夹,训练轮次会减少为所更改的轮次,并且训练会从上一次中断处继续开始。

  • 如下是我的训练结果中的训练过程:

3、跟原训练代码对比

训练代码无区别!!!只需修改ultralytics/yolo/engine/trainer.py内python脚本即可!!!

下面是trainer.py的python脚本对比:

参数断点重续前中断减少epoch轮次后
self.epochsself.args.epochs5(表示减少为5个轮次进行训练)
resumeself.args.resume.../runs/detect/exp/weights/last.pt
ckpt

ckpt = torch.load('.../runs/segment/train14/weights/last.pt')

注意:训练结束一定要还原trainer.py代码!!!!

不然接下来运行所有的训练代码,无论你代码中的训练轮次是多少,都只会训练5个轮次!!!!

  • 如下是我还原trainer.py代码的过程步骤:(修改后点击运行,报错也无所谓)

参考资料:

YOLOv8(Ultralytics)从断点处继续训练(Resume)_yolov8 resume-CSDN博客

yolov8断点恢复训练及减少训练次数和增加训练次数_深度学习_darkredrock-GitCode 开源社区

;