目录
1、YOLO模型中best.pt和last.pt的区别:(训练选择last.pt)
一、认识相关参数
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
-
跟原训练代码对比:
参数 | 断点重续前 | 断点重续后 |
---|---|---|
model | yolov8n.pt | runs/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轮次后 |
---|---|---|
model | yolov8n.pt | runs/detect/exp/weights/last.pt |
epochs | 100 | 10 |
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")
-
跟原训练代码对比:
参数 | 断点重续前 | 断点重续后 |
---|---|---|
model | yolov8n.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轮次后 |
---|---|---|
model | yolov8n.pt | .../runs/detect/exp/weights/last.pt |
epochs | 50 | 5(表示再增加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.epochs | self.args.epochs | 5(表示减少为5个轮次进行训练) |
resume | self.args.resume | .../runs/detect/exp/weights/last.pt |
ckpt | 无 | ckpt = torch.load('.../runs/segment/train14/weights/last.pt') |
注意:训练结束一定要还原trainer.py代码!!!!
不然接下来运行所有的训练代码,无论你代码中的训练轮次是多少,都只会训练5个轮次!!!!
- 如下是我还原trainer.py代码的过程步骤:(修改后点击运行,报错也无所谓)