Tiếp tục và lặp lại
Tiếp tục chính xác một lần chạy bị gián đoạn, khởi tạo vòng mới từ best.pt với learning rate thực sự được áp dụng, và so sánh các lần chạy cạnh nhau.
Các dự án thực tế gồm nhiều lần chạy training. Một số lần chạy bị dừng giữa chừng — laptop đóng, phiên SSH bị ngắt hoặc GPU đám mây bị thu hồi — và chạy lại từ đầu đồng nghĩa với việc mất hàng giờ công sức. Một số lần chạy khác hoàn tất; vòng tiếp theo nên dựa trên kết quả đó thay vì bắt đầu lại từ COCO.
Trong bài học này, bạn sẽ ngắt một lần chạy rồi tiếp tục, khởi tạo vòng hai từ best.pt với learning rate thực sự được áp dụng, và so sánh mọi lần chạy trong một bảng. Bạn cũng sẽ tìm hiểu hai hành vi resume có thể âm thầm gây lãng phí thời gian chạy.
Thực hành
Chọn đúng loại lần chạy#

| Tình huống | Loại lần chạy | Bắt đầu từ |
|---|---|---|
| Mất điện, mất kết nối hoặc hết bộ nhớ giữa chừng | Tiếp tục | last.pt, cùng trạng thái optimizer và lịch trình |
| Lần chạy đã hoàn tất; có thêm dữ liệu, sửa nhãn hoặc cần training lâu hơn | Khởi tạo từ weights hiện có | best.pt dưới dạng model pretrained |
Thêm hoặc xóa class, thay đổi nhiều nhãn hoặc imgsz thay đổi đáng kể | Bắt đầu mới | yolo26n.pt |
Ví dụ thực hành: Tiếp tục lần chạy bị gián đoạn#
resume=True khôi phục model, trạng thái optimizer, lịch trình learning rate và bộ đếm epoch từ last.pt, rồi tiếp tục kế hoạch ban đầu:
yolo train resume=True model=runs/detect/pills_resume/weights/last.ptĐầu ra thực tế từ lần chạy 5 epoch bị dừng sau epoch thứ 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: quá trình chạy tiếp tục chính xác sau epoch được lưu gần nhất, với số epoch mục tiêu ban đầu.- Bạn không truyền
datahoặcepochs: mọi đối số đều được lấy từ checkpoint. Có thể ghi đè một số thiết lập runtime nhưbatch,devicevàworkerskhi tiếp tục; mọi thiết lập khác sẽ bị bỏ qua kèm cảnh báoResume ignores ....
Ví dụ thực hành: Khởi tạo vòng hai từ weights hiện có#
Hầu hết thử nghiệm ở “vòng tiếp theo” không phải là tiếp tục lần chạy cũ; đó là những lần chạy mới bắt đầu từ model tốt gần nhất của bạn — hình thức transfer learning thông thường trong chính dự án của bạn. Hãy dùng learning rate thấp hơn để model được tinh chỉnh thay vì học lại:
from ultralytics import YOLO
model = YOLO("runs/detect/pills_v1/weights/best.pt") # khởi tạo từ weights của vòng 1
model.train(
data="my_dataset/data.yaml",
epochs=5,
imgsz=320,
optimizer="AdamW", # đặt rõ ràng: optimizer="auto" bỏ qua lr0
lr0=0.0005, # nhẹ hơn mức 0.002 được tự động chọn cho vòng 1
name="pills_v2_warm",
)Log xác nhận thiết lập đã có hiệu lực: optimizer: AdamW(lr=0.0005, momentum=0.937). Hướng dẫn fine-tuning trình bày cách đóng băng layer và training hai giai đoạn; hướng dẫn tinh chỉnh hyperparameter trình bày các lượt tìm kiếm.
Ví dụ thực hành: So sánh các lần chạy#
Đặt tên mỗi lần chạy theo thay đổi đã thực hiện — pills_v2_warm, pills_v3_imgsz640, pills_v4_edge_frames — không dùng train2 hoặc final. Mỗi lần chạy ghi một results.csv, vì vậy chỉ cần vài dòng để so sánh:
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.694Năm epoch khởi tạo từ weights hiện có đã nâng mAP50-95 từ 0.659 lên 0.694, trong khi năm epoch bắt đầu từ weights COCO (pills_resume) chỉ đạt 0.579. Khởi tạo từ weights hiện có giúp tiến triển với chi phí thấp hơn — miễn là class và nhãn không bị thay đổi trong quá trình đó. Khi số lần chạy tăng lên, dùng một công cụ theo dõi sẽ rất hữu ích: Ultralytics Platform (xem So sánh các lần chạy và chọn kết quả tốt nhất), hoặc các tích hợp Comet và Weights & Biases, sẽ tự động ghi lại mọi lần chạy.
Giảm chi phí cho mỗi vòng#
Hầu hết các vòng giải đáp một câu hỏi, chẳng hạn “các khung hình mới có hữu ích không?”. Những đối số này giúp bạn nhận được câu trả lời nhanh hơn trong quá trình thử nghiệm:
| Đối số | Ví dụ | Tác động |
|---|---|---|
fraction | fraction=0.5 | Training trên nửa đầu số ảnh training (được sắp xếp theo tên tệp) |
time | time=0.25 | Dừng sau 0.25 giờ, ghi đè epochs |
patience | patience=10 | Dừng khi fitness trên tập validation không cải thiện trong 10 epoch |
imgsz | imgsz=320 | Chỉ dùng một phần tư số pixel so với kích thước 640; chỉ so sánh các lần chạy ở cùng kích thước |
cache | cache=True | Giữ ảnh đã giải mã trong RAM để các epoch tiếp theo tải nhanh hơn |
Mỗi vòng chỉ thay đổi một yếu tố, rồi xác nhận kết quả tốt nhất bằng một lần chạy ở kích thước đầy đủ trước khi đưa vào sử dụng. Khi cần bắt đầu mới, chỉ cần dùng cùng lệnh với weights pretrained:
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # quay lại trọng số được huấn luyện trước trên COCO
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_v3_relabeled")Tránh những lỗi này#
Triệu chứng: WARNING ⚠️ model '.../last.pt' is not a resumable training checkpoint ... Starting new training instead, sau đó là một lần chạy hoàn toàn mới — trên dataset coco8 mặc định, trừ khi bạn truyền data. Nguyên nhân: resume=True chỉ tiếp tục các lần chạy bị dừng sớm. Cách khắc phục: dừng lại và chủ động bắt đầu một lần chạy mới từ best.pt.
Triệu chứng: optimizer: 'optimizer=auto' found, ignoring 'lr0=0.0005' and determining best 'optimizer' and 'lr0' automatically... Nguyên nhân: optimizer=auto mặc định tự chọn learning rate. Cách khắc phục: đặt rõ ràng optimizer (ví dụ "AdamW" hoặc "SGD") mỗi khi đặt lr0, đồng thời xác nhận dòng log optimizer:.
Huấn luyện lần thứ hai với name="pills_v1" sẽ ghi vào pills_v1-2, khiến bạn dễ nhầm lẫn về sau. Hãy dùng tên mới, có ý nghĩa mô tả cho mỗi lần chạy.
Hiển thị lời giải
Nếu khó canh thời điểm nhấn Ctrl+C trên máy nhanh, bạn có thể dùng callback để tự dừng lượt chạy sau epoch 2:
from ultralytics import YOLO
def power_cut(trainer):
if trainer.epoch == 1: # Đánh chỉ mục từ 0: dừng sau khi lưu epoch 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.