再開してイテレーションを進める
中断した実行を正確に再開し、実際に適用される学習率を使ってbest.ptから新しいラウンドをウォームスタートし、実行結果を並べて比較します。
実際のプロジェクトでは、トレーニングを何度も実行します。途中で止まることもあります。ノートPCを閉じた、SSHセッションが切れた、クラウドGPUがプリエンプトされたなどの理由です。最初からやり直すと、何時間分もの作業が無駄になります。実行が完了した場合は、COCOからやり直すのではなく、その結果を土台に次のラウンドを進めるべきです。
このレッスンでは、実行を中断して再開する方法、実際に適用される学習率でbest.ptから2回目のラウンドをウォームスタートする方法、すべての実行結果を1つの表で比較する方法を学びます。また、実行をひそかに無駄にする2つのresumeの挙動も説明します。
実践的
適切な実行方法を選ぶ#

| 状況 | 実行の種類 | 開始元 |
|---|---|---|
| 途中での停電、接続切断、またはメモリ不足 | 再開 | last.pt。オプティマイザーの状態とスケジュールも含まれます |
| 実行が完了した後にデータを追加、ラベルを修正、またはトレーニングを延長する場合 | ウォームスタート | 事前学習済みモデルとしてのbest.pt |
クラスの追加や削除、多数のラベル変更、またはimgszの大幅な変更 | 新規開始 | yolo26n.pt |
実例: 中断した実行を再開する#
resume=Trueは、last.ptからモデル、オプティマイザーの状態、学習率スケジュール、エポックカウンターを復元し、元の計画を続行します。
yolo train resume=True model=runs/detect/pills_resume/weights/last.pt5エポックの実行を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 ...の警告が表示されます。
実例: 2回目のラウンドをウォームスタートする#
「次のラウンド」で行う実験の多くは再開ではなく、最後に得た良好なモデルから始める新しい実行です。これは、同じプロジェクト内で行う通常の転移学習です。モデルに学習をやり直させるのではなく、微調整させるため、学習率を下げます。
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)。ファインチューニングガイドではレイヤーの凍結と2段階トレーニングを、ハイパーパラメーター調整ガイドではスイープを説明しています。
実例: 実行結果を比較する#
変更内容に合わせて実行に名前を付けます。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の重み(pills_resume)から5エポック実行した場合は0.579にとどまりました。クラスやラベルが途中で変更されていなければ、ウォームスタートは低コストで進捗を得る方法です。実行回数が数回を超えると、トラッカーを使う価値が出てきます。Ultralytics Platform(実行を比較して最適なものを選ぶを参照)、またはCometやWeights & Biasesとのインテグレーションを使えば、すべての実行を自動で記録できます。
各ラウンドのコストを抑える#
多くのラウンドでは、「新しいフレームは役に立ったか?」など、1つの問いに答えます。試行中にすばやく答えを得るには、次の引数が役立ちます。
| 引数 | 例 | 効果 |
|---|---|---|
fraction | fraction=0.5 | トレーニング画像をファイル名順に並べたうち、前半だけでトレーニングします |
time | time=0.25 | 0.25時間後に停止し、epochsを上書きします |
patience | patience=10 | 検証時のfitnessが10エポックにわたって改善しない場合に停止します |
imgsz | imgsz=320 | 640の場合のピクセル数の4分の1です。実行結果は同じサイズでのみ比較してください |
cache | cache=True | デコード済み画像をRAMに保持し、後続のエポックでの読み込みを高速化します |
ラウンドごとに変更する項目は1つにし、採用する前にフルサイズで実行して最良の設定を確認してください。新規開始が必要な場合も、事前学習済みの重みを指定して同じ呼び出しを使います。
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: のログ行を確認してください。
2回目のトレーニングで 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.