재개 및 반복
중단된 실행을 정확히 재개하고, 실제로 적용되는 학습률로 best.pt에서 새 라운드를 웜 스타트한 다음 실행들을 나란히 비교합니다.
실제 프로젝트에서는 학습을 여러 차례 실행합니다. 노트북을 닫거나, SSH 연결이 끊기거나, 클라우드 GPU가 선점되어 실행이 중간에 종료되기도 합니다. 처음부터 다시 시작하면 몇 시간의 작업을 잃게 됩니다. 실행을 마친 뒤에는 COCO에서 다시 시작하는 대신, 다음 반복을 이전 결과를 바탕으로 진행해야 합니다.
이 강의에서는 실행을 중단한 뒤 재개하고, 실제로 적용되는 학습률로 best.pt에서 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 통합을 사용하면 모든 실행을 자동으로 기록합니다.
각 반복의 비용 줄이기#
대부분의 반복은 "새 프레임이 도움이 되었는가?"와 같은 질문 하나에 답하기 위한 것입니다. 탐색하는 동안 다음 인수를 사용하면 더 빠르게 결과를 확인할 수 있습니다.
| 인수 | 예시 | 효과 |
|---|---|---|
fraction | fraction=0.5 | 파일 이름순으로 정렬한 학습 이미지의 앞부분 절반만 사용해 학습합니다. |
time | time=0.25 | epochs을 덮어쓰고 0.25시간 후에 중지합니다. |
patience | patience=10 | 검증 적합도가 10에포크 동안 개선되지 않으면 중지합니다. |
imgsz | imgsz=320 | 640 크기의 4분의 1에 해당하는 픽셀을 사용합니다. 실행 결과는 같은 크기에서만 비교하세요. |
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.