恢复运行并迭代
准确恢复中断的运行,从 best.pt 热启动新一轮并确保学习率设置生效,然后并排比较各次运行。
实际项目通常由一系列训练运行组成。有些运行会中途停止——笔记本电脑合上、SSH 会话断开,或云端 GPU 被抢占——从零重启会浪费数小时。还有些运行能够完成,而下一轮应该基于这些结果继续,而不是重新从 COCO 开始。
本课将介绍如何中断并恢复一次运行,如何从 best.pt 热启动第二轮并确保学习率设置生效,以及如何在一张表中比较每次运行。你还会了解两种会悄悄浪费运行时间的 resume 行为。
实践操作
选择合适的运行类型#

| 情况 | 运行类型 | 从哪里开始 |
|---|---|---|
| 训练中途断电、连接断开或内存不足 | 恢复运行 | last.pt,包括优化器状态和学习率计划 |
| 运行已完成;增加了数据、修正了标注,或想延长训练 | 热启动 | 将 best.pt 作为预训练模型 |
新增或移除类别、大量修改标签,或 imgsz 发生了较大变化 | 全新开始 | yolo26n.pt |
示例:恢复中断的运行#
resume=True 会从 last.pt 恢复模型、优化器状态、学习率计划和训练轮次计数器,然后继续执行原定计划:
yolo train resume=True model=runs/detect/pills_resume/weights/last.pt一个运行 5 个训练轮次、在第 2 轮后停止的实际输出:
Resuming training runs/detect/pills_resume/weights/last.pt from epoch 3 to 5 total epochs
3/5 0G 1.232 2.393 0.005478 206 320: 100% 6/6 4.5s
4/5 0G 1.345 1.859 0.005833 208 320: 100% 6/6 4.5s
5/5 0G 1.31 1.625 0.005854 191 320: 100% 6/6 4.4s
3 epochs completed in 0.004 hours.from epoch 3 to 5 total epochs:它从最后一次保存的训练轮次之后准确恢复,并沿用原定目标轮数。- 你没有传入
data或epochs:所有参数都来自检查点。恢复运行时可以覆盖一些运行时设置,例如batch、device和workers;其他设置都会被忽略,并显示Resume ignores ...警告。
示例:热启动第二轮#
大多数“下一轮”实验并不是恢复运行,而是从你上一个效果良好的模型开始新运行——也就是在自己的项目中进行普通的迁移学习。使用较低的学习率,让模型进行微调,而不是重新学习:
from ultralytics import YOLO
model = YOLO("runs/detect/pills_v1/weights/best.pt") # 从第 1 轮进行热启动
model.train(
data="my_dataset/data.yaml",
epochs=5,
imgsz=320,
optimizer="AdamW", # 显式设置:optimizer="auto" 会忽略 lr0
lr0=0.0005, # 比第 1 轮自动选择的 0.002 更温和
name="pills_v2_warm",
)日志确认了该设置已生效:optimizer: AdamW(lr=0.0005, momentum=0.937)。微调指南介绍了层冻结和两阶段训练;超参数调优指南介绍了参数搜索。
示例:比较运行#
根据每次运行的改动为其命名——pills_v2_warm、pills_v3_imgsz640、pills_v4_edge_frames——不要用 train2 或 final。每次运行都会生成一个 results.csv,所以只需几行代码就能进行比较:
from pathlib import Path
import pandas as pd
for csv in sorted(Path("runs/detect").glob("*/results.csv")):
df = pd.read_csv(csv)
best = df["metrics/mAP50-95(B)"].max()
print(f"{csv.parent.name:<14} epochs={len(df):<3} best mAP50-95={best:.3f}")pills_resume epochs=5 best mAP50-95=0.579
pills_v1 epochs=10 best mAP50-95=0.659
pills_v2_warm epochs=5 best mAP50-95=0.694热启动训练 5 轮后,mAP50-95 从 0.659 提升至 0.694;而从 COCO 权重开始训练 5 轮(pills_resume)后,mAP50-95 仅达到 0.579。只要类别和标签没有发生变化,热启动就能以较低成本取得进展。运行次数达到几次之后,使用跟踪工具就很划算:Ultralytics Platform(参见比较运行并选出最佳结果),或者使用 Comet 和 Weights & Biases 集成,自动记录每次运行。
让每轮迭代成本更低#
大多数轮次只回答一个问题,例如“新加入的帧有帮助吗?”。探索时,使用以下参数可以更快得到答案:
| 参数 | 示例 | 效果 |
|---|---|---|
fraction | fraction=0.5 | 使用训练图像中按文件名排序的前一半进行训练 |
time | time=0.25 | 0.25 小时后停止,并覆盖 epochs |
patience | patience=10 | 当验证适应度连续 10 轮没有提升时停止 |
imgsz | imgsz=320 | 像素数量是 640 时的四分之一;只在相同尺寸下比较运行结果 |
cache | cache=True | 将解码后的图像保存在 RAM 中,以便后续训练轮次更快加载 |
每轮只改一项,并在发布前使用全尺寸运行确认最佳结果。确实需要全新开始时,使用预训练权重调用同一命令即可:
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # 返回 COCO 预训练权重
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_v3_relabeled")避免这些错误#
症状:出现 WARNING ⚠️ model '.../last.pt' is not a resumable training checkpoint ... Starting new training instead,随后开始全新训练——除非你传入了 data,否则会使用默认的 coco8 数据集。原因:resume=True 只会继续尚未完成的训练。解决方法:停止它,并有意从 best.pt 开始新的训练。
症状:optimizer: 'optimizer=auto' found, ignoring 'lr0=0.0005' and determining best 'optimizer' and 'lr0' automatically...。原因:默认的 optimizer=auto 会自行选择学习率。解决方法:每当设置 lr0 时,都要明确设置 optimizer(例如 "AdamW" 或 "SGD"),并确认日志中的 optimizer: 行。
第二次使用 name="pills_v1" 进行训练时,会写入 pills_v1-2,之后很容易混淆。每次训练都使用新的描述性名称。
显示解答
如果机器速度很快,难以把握按 Ctrl+C 的时机,可以使用回调在第 2 轮后停止运行:
from ultralytics import YOLO
def power_cut(trainer):
if trainer.epoch == 1: # 从 0 开始计数:第 2 轮保存后停止
raise KeyboardInterrupt
model = YOLO("yolo26n.pt")
model.add_callback("on_model_save", power_cut)
model.train(data="my_dataset/data.yaml", epochs=5, imgsz=320, name="pills_resume")yolo train resume=True model=runs/detect/pills_resume/weights/last.pt
python round2.py
python compare_runs.pypills_v2_warm has the best mAP50-95 (0.694 vs 0.659 for pills_v1), with the same
classes and labels, so round three warm-starts from pills_v2_warm/weights/best.pt.