训练深度学习模型是个漫长的过程,尤其是像YOLOv8这样的目标检测模型。我遇到过太多次训练到一半突然中断的情况——可能是服务器掉电、GPU内存不足,或者是训练程序意外崩溃。每次看到训练到一半的模型被迫终止,都让人特别抓狂。
更糟的是,有些数据集需要训练很长时间才能收敛。比如我去年处理的一个工业缺陷检测项目,完整训练需要300个epoch,每次训练都要3天时间。如果因为意外中断就得从头开始训练,不仅浪费时间,还可能错过重要的项目节点。
续训功能就是为解决这个问题而生的。它能让我们从上次中断的地方继续训练,而不是从头开始。但很多人不知道的是,简单的续训操作背后藏着不少坑。比如续训后学习率调度器状态不对、优化器动量参数重置、早停机制误判等问题,都可能导致续训后的模型性能不如连续训练的效果。
YOLOv8在训练过程中会自动保存检查点文件,通常存放在runs/detect/train/weights目录下。这些.pt文件不只是保存了模型权重,还包含了训练状态的全套信息:
理解这点很重要,因为完整的续训需要恢复所有这些状态,而不仅仅是加载模型权重。我曾经犯过只恢复模型权重的错误,结果续训后模型性能大幅下降。
默认情况下,YOLOv8会:
建议在开始长时间训练前,先确认你的保存设置。我有次设置了很大的save_period,结果在训练中断时发现最近的检查点已经是20个epoch前的了,不得不浪费很多计算资源。
最直接的续训方法就是设置resume=True参数:
python复制from ultralytics import YOLO
model = YOLO('runs/detect/train/weights/last.pt')
results = model.train(resume=True)
这个方法会自动:
但要注意,这种方法会沿用原来的epoch总数。比如你原本设置训练100个epoch,已经训练了60个,那么续训后会继续训练剩余的40个epoch。
如果想在续训时增加总训练轮次,需要修改两处:
python复制model = YOLO('runs/detect/train/weights/last.pt')
results = model.train(resume=True, epochs=150) # 假设想训练到150个epoch
但这里有个坑:仅仅这样设置可能不够,因为YOLOv8内部会从检查点读取已完成的epoch数。更可靠的做法是直接修改检查点文件中的epoch计数(后面会详细介绍)。
有时候基础方法不够用,特别是当你想:
这时可以手动修改YOLOv8的源代码(记得备份原文件!):
python复制def check_resume(self):
# 原代码:resume = self.args.resume
resume = 'runs/detect/train/weights/last.pt' # 硬编码检查点路径
return resume
python复制def resume_training(self, ckpt):
ckpt = torch.load('runs/detect/train/weights/last.pt') # 手动加载检查点
start_epoch = 100 # 假设要从第100个epoch开始
# ...其余代码保持不变
YOLOv8默认使用早停机制(patience),如果验证指标长时间不提升就会提前终止训练。续训时可能需要调整这个参数:
python复制# 在ultralytics/engine/trainer.py中找到_setup_train方法
self.stopper, self.stop = EarlyStopping(patience=300), False # 增大patience值
我有次续训后模型很快停止,就是因为没注意到早停计数器是从检查点恢复的,patience值已经所剩无几。
续训后要特别注意观察训练曲线是否连贯:
如果发现异常,比如损失突然上升,可能是状态恢复不正确。这时最好回退到上一个检查点重新续训。
为了确保续训没有影响模型性能,可以:
在我的测试中,正确配置的续训模型性能差异通常在1%以内。如果差距过大,说明续训过程可能有问题。
可能原因:
解决方案:
有时续训后epoch计数不从正确位置开始。可以:
python复制# 修改ultralytics/engine/trainer.py
start_epoch = 100 # 明确指定起始epoch
续训时如果修改了batch size可能导致OOM。建议:
根据我多次续训YOLOv8模型的经验,总结出以下建议:
定期保存检查点:不要依赖默认的保存频率,对于长时间训练,设置save_period=5或更低。
记录训练配置:每次训练都要保存完整的配置参数,包括:
验证续训效果:续训完成后,在验证集上立即测试性能,与中断前的指标对比。
代码版本控制:训练脚本和YOLOv8版本的变更可能导致续训失败。我吃过这个亏,现在每次训练都会记录代码库的git commit hash。
保留完整日志:训练日志是诊断续训问题的关键。建议保存控制台输出到文件,并记录中断时的具体情况。