Cách Fine-Tune YOLO trên Dataset Tùy chỉnh#
Fine-tuning điều chỉnh một model đã được pretrained để nhận diện các class mới bằng cách bắt đầu từ các trọng số đã học thay vì khởi tạo ngẫu nhiên. Thay vì training từ đầu trong hàng trăm epoch, fine-tuning tận dụng các đặc trưng COCO đã được pretrained và hội tụ trên dữ liệu tùy chỉnh trong thời gian ngắn hơn nhiều.
Hướng dẫn này trình bày cách fine-tune YOLO26 trên các dataset tùy chỉnh, từ cách sử dụng cơ bản đến các kỹ thuật nâng cao như đóng băng layer và training hai giai đoạn.
Fine-Tuning và Training từ đầu#
Một model đã được pretrained đã học các đặc trưng hình ảnh tổng quát - phát hiện biên, nhận diện texture, hiểu hình dạng - từ hàng triệu hình ảnh. Transfer learning thông qua fine-tuning tái sử dụng kiến thức đó và chỉ dạy model nhận biết hình dạng của các class mới, nhờ đó model hội tụ nhanh hơn và cần ít dữ liệu hơn. Training từ đầu loại bỏ toàn bộ kiến thức này và buộc model học mọi thứ từ các pattern ở cấp độ pixel trở lên, đòi hỏi nhiều tài nguyên hơn đáng kể. Xem Hướng dẫn Cấu hình Model YAML để tìm hiểu sự khác biệt giữa các file .yaml chỉ chứa kiến trúc và các checkpoint.
| Fine-tuning | Training từ đầu | |
|---|---|---|
| Trọng số khởi đầu | Pretrained trên COCO (80 class) | Khởi tạo ngẫu nhiên |
| Command | YOLO("yolo26n.pt") | YOLO("yolo26n.yaml") |
| Hội tụ | Nhanh hơn - backbone đã được training | Chậm hơn - tất cả layer học từ đầu |
| Yêu cầu dữ liệu | Thấp hơn - các đặc trưng pretrained bù đắp cho lượng dữ liệu ít hơn | Cao hơn - model phải tự học tất cả đặc trưng chỉ từ dataset |
| Khi nào nên sử dụng | Các class tùy chỉnh với hình ảnh tự nhiên | Các domain khác biệt căn bản với COCO (y tế, vệ tinh, radar) |
Khi một file .pt được load bằng YOLO("yolo26n.pt"), các trọng số pretrained được lưu trong model. Việc gọi .train(data="custom.yaml") sau đó sẽ tự động chuyển tất cả trọng số tương thích sang kiến trúc model mới, khởi tạo lại các layer không khớp (chẳng hạn detection head khi số class khác nhau) và bắt đầu training. Không cần tự load trọng số, thao tác layer hoặc viết code transfer learning tùy chỉnh.
Cách Chuyển Trọng số Pretrained Hoạt động#
Khi một model pretrained được fine-tune trên dataset có số class khác nhau (ví dụ từ 80 class của COCO xuống 5 class tùy chỉnh), Ultralytics thực hiện chuyển trọng số có xét đến shape:
- Backbone và neck được chuyển hoàn toàn - các layer này trích xuất đặc trưng hình ảnh tổng quát và shape của chúng không phụ thuộc vào số class.
- Detection head được khởi tạo lại một phần - các layer output phân loại (
cv3,one2one_cv3) có shape gắn với số class (80 so với 5). Các row tương thích có tên class trùng khớp sẽ được ánh xạ lại trước khi các row không khớp được khởi tạo. Các layer hồi quy box (cv2,one2one_cv2) trong head có shape cố định bất kể số class, nên được chuyển bình thường. - Phần lớn áp đảo các trọng số được chuyển khi thay đổi số class. Ví dụ, fine-tune YOLO26n từ COCO (80 class) trên dataset 5 class sẽ chuyển 606 trong số 708 tensor trọng số, cùng với mọi row phân loại tương thích được khớp theo tên.
Đối với các dataset có cùng số class với model pretrained (ví dụ fine-tune trọng số pretrained trên COCO trên một dataset 80 class khác), 100% trọng số được chuyển, bao gồm cả detection head.
Chuyển Class bằng Alias Tên#
Ultralytics chuyển các row tương ứng trong classification head theo tên class giữa các dataset, không phân biệt chữ hoa chữ thường và khoảng trắng xung quanh. Khi các class tương đương có tên khác nhau, hãy đổi tên các class của checkpoint nguồn trong bộ nhớ trước khi load. Điều này bảo toàn trọng số phân loại pretrained cho các khái niệm dùng chung, vốn nếu không sẽ bị xem là không khớp và được khởi tạo ngẫu nhiên.
Ví dụ Objects365 v2-to-COCO này đổi tên các class nguồn trên checkpoint đã load; sau đó train() truyền chúng đi dưới dạng trọng số pretrained:
from ultralytics import YOLO
# Source Objects365 v2 name (lowercased) -> target COCO name
ALIASES = {
"wild bird": "bird",
"handbag/satchel": "handbag",
"luggage": "suitcase",
"bowl/basin": "bowl",
"orange/tangerine": "orange",
"monitor/tv": "tv",
"stuffed toy": "teddy bear",
"hair dryer": "hair drier",
}
model = YOLO("path/to/yolo26s-objects365.pt")
# Objects365 class names are Title-Cased, so match on the lowercased name
model.model.names = {i: ALIASES.get(name.lower(), name) for i, name in model.model.names.items()}
model.train(data="coco.yaml", epochs=100, imgsz=640)Thiết lập cls_remap mặc định bật tính năng chuyển dựa trên tên này. Trong quá trình training, Remapped N/M cls head rows from pretrained weights by class name được in ra khi các row tương thích được sao chép; đặt cls_remap=False để tắt tính năng này.
Ví dụ Fine-Tuning Cơ bản#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load pretrained model
model.train(data="custom.yaml", epochs=50, imgsz=640)Lựa chọn Kích thước Model#
Các model lớn hơn có năng lực cao hơn nhưng cũng có nhiều parameter hơn cần cập nhật, điều này có thể làm tăng nguy cơ overfitting khi dữ liệu training hạn chế. Bắt đầu với model nhỏ hơn (YOLO26n hoặc YOLO26s) và chỉ tăng quy mô nếu các metric validation đạt trạng thái plateau là một cách tiếp cận thực tế. Kích thước model tối ưu phụ thuộc vào độ phức tạp của tác vụ, số class, mức độ đa dạng của dataset và phần cứng có sẵn để deployment. Xem đầy đủ trang model YOLO26 để biết các kích thước có sẵn và benchmark hiệu năng.
Lựa chọn Optimizer và Learning Rate#
Thiết lập optimizer=auto mặc định chọn optimizer và learning rate dựa trên tổng số iteration training:
- 10.000 iteration trở xuống (dataset nhỏ hoặc ít epoch): AdamW với learning rate thấp được tự động tính toán
- Trên 10.000 iteration (dataset lớn): MuSGD (một optimizer lai giữa Muon+SGD) với lr=0.01
Đối với hầu hết tác vụ fine-tuning, thiết lập mặc định hoạt động tốt mà không cần tinh chỉnh thủ công. Hãy cân nhắc chỉ định rõ optimizer khi:
- Training không ổn định (loss tăng vọt hoặc phân kỳ): thử
optimizer=AdamW, lr0=0.001để hội tụ ổn định hơn - Fine-tune model lớn trên dataset nhỏ: một optimizer được chỉ định rõ với learning rate thấp hơn, chẳng hạn
optimizer=AdamW, lr0=0.001, có thể giúp bảo toàn các đặc trưng pretrained
Khi optimizer=auto, các giá trị lr0 và momentum sẽ bị bỏ qua. Để tự kiểm soát learning rate, hãy chỉ định rõ optimizer: optimizer=SGD, lr0=0.005.
Đóng băng Layer#
Đóng băng ngăn các layer cụ thể được cập nhật trong quá trình training. Điều này tăng tốc training và giảm overfitting khi dataset nhỏ so với năng lực của model.
Parameter freeze chấp nhận một số nguyên hoặc một list. Số nguyên freeze=10 đóng băng 10 layer đầu tiên (index 0-9), bao phủ phần lớn backbone YOLO26. Backbone trải dài từ layer 0-10, vì vậy freeze=10 để block C2PSA cuối cùng (layer 10) có thể training; dùng freeze=11 để đóng băng toàn bộ backbone. Một list có thể chứa các index layer như freeze=[0, 3, 5] để đóng băng một phần backbone, hoặc các chuỗi tên module như freeze=["23.cv2", "23.one2one_cv2"] để kiểm soát chi tiết các nhánh cụ thể bên trong một layer (ở đây là cả hai nhánh hồi quy box của detection head).
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=50, freeze=10)Độ sâu đóng băng phù hợp phụ thuộc vào mức độ tương đồng giữa domain đích với dữ liệu pretrained và lượng dữ liệu training có sẵn:
| Tình huống | Khuyến nghị | Lý do |
|---|---|---|
| Dataset lớn, domain tương tự | freeze=None (mặc định) | Đủ dữ liệu để điều chỉnh tất cả layer mà không bị overfitting |
| Dataset nhỏ, domain tương tự | freeze=10 | Bảo toàn các đặc trưng backbone, giảm số parameter có thể training |
| Dataset rất nhỏ | freeze=23 | Chỉ training detection head, giảm thiểu nguy cơ overfitting |
| Domain khác xa COCO | freeze=None | Các đặc trưng backbone có thể không chuyển tốt và cần được training lại |
Độ sâu đóng băng cũng có thể được xem là một hyperparameter - thử một vài giá trị (0, 5, 10) và so sánh mAP validation là cách thực tế để tìm thiết lập tốt nhất cho một dataset cụ thể.
Các Hyperparameter Quan trọng cho Fine-Tuning#
Fine-tuning thường yêu cầu ít điều chỉnh hyperparameter hơn so với training từ đầu. Các parameter quan trọng nhất là:
epochs: Fine-tuning hội tụ nhanh hơn training từ đầu. Bắt đầu với một giá trị vừa phải và dùngpatienceđể dừng sớm khi các metric validation đạt plateau.patience: Giá trị mặc định là 100, được thiết kế cho các lượt training dài. Giảm xuống 10-20 để tránh lãng phí thời gian cho những lượt đã hội tụ.warmup_epochs: Warmup đưa learning rate dần đến giá trị theo lịch trong các epoch đầu tiên, nhờ đó các batch ban đầu ít có khả năng làm xáo trộn các đặc trưng pretrained hơn. Hãy giữ giá trị khác 0 khi fine-tuning, nhưng không bắt buộc dùng mặc định đầy đủ 3 epoch: quá trình tìm kiếm tiến hóa phía sau YOLO26 COCO fine-tune chính thức — một quá trình tiếp tục training nhiều epoch từ trọng số Objects365 — đã hội tụ vào khoảng một epoch cho mỗi kích thước model.
Để xem danh sách đầy đủ các parameter training, hãy tham khảo tài liệu tham chiếu cấu hình training. Đối với các hành vi mà parameter không cung cấp — learning rate theo từng layer, gradient clipping hoặc metric validation tùy chỉnh — hãy subclass trainer.
Fine-Tuning Hai Giai đoạn#
Fine-tuning hai giai đoạn chia quá trình training thành hai phase. Giai đoạn đầu đóng băng backbone và chỉ training neck cùng head, cho phép các layer detection thích nghi với các class mới mà không làm xáo trộn các đặc trưng pretrained. Giai đoạn thứ hai bỏ đóng băng tất cả layer và training toàn bộ model với learning rate thấp hơn để tinh chỉnh backbone cho domain đích.
Cách tiếp cận này đặc biệt hữu ích khi domain đích khác đáng kể so với COCO (hình ảnh y tế, ảnh chụp từ trên không, ảnh hiển vi), nơi backbone có thể cần được thích nghi nhưng training mọi thứ cùng lúc gây mất ổn định. Để tự động bỏ đóng băng bằng cách tiếp cận dựa trên callback, hãy xem Đóng băng và Bỏ đóng băng Backbone.
from ultralytics import YOLO
# Stage 1: freeze backbone, train head and neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)
# Stage 2: unfreeze all, fine-tune with lower lr
model = YOLO("runs/detect/stage1/weights/best.pt")
model.train(data="custom.yaml", epochs=30, optimizer="AdamW", lr0=0.001, name="stage2", exist_ok=True)Các Vấn đề Thường gặp#
Model không tạo prediction#
-
Dữ liệu training không đủ: training với quá ít sample là nguyên nhân phổ biến nhất - model không thể học hoặc khái quát hóa từ lượng dữ liệu quá ít. Đảm bảo có đủ ví dụ đa dạng cho mỗi class trước khi điều tra các nguyên nhân khác.
-
Kiểm tra path của dataset: path hình ảnh không hợp lệ sẽ gây lỗi dataset. Các file label bị thiếu hoặc rỗng riêng lẻ được xem là hình ảnh background và được báo cáo trong quá trình quét; một split training không có label sẽ gây lỗi. Hãy kiểm tra dataset trước khi training:
yolo detect val model=yolo26n.pt data=custom.yaml -
Giảm ngưỡng confidence: nếu prediction tồn tại nhưng bị lọc, hãy thử
conf=0.1trong quá trình inference. -
Xác minh số class: đảm bảo
nctrongdata.yamlkhớp với số class thực tế trong các file label.
mAP validation đạt plateau sớm#
- Thêm dữ liệu: fine-tuning hưởng lợi đáng kể từ dữ liệu training bổ sung, đặc biệt là các ví dụ đa dạng với góc chụp, ánh sáng và background khác nhau.
- Kiểm tra cân bằng class: các class ít xuất hiện sẽ có AP thấp. Thêm ví dụ hoặc tinh chỉnh
cls_pwtrên tập validation. - Giảm augmentation: đối với dataset rất nhỏ, augmentation mạnh có thể gây hại nhiều hơn lợi ích. Hãy thử
mosaic=0.5hoặcmosaic=0.0. - Tăng độ phân giải: đối với dataset có object nhỏ, hãy thử
imgsz=1280để bảo toàn chi tiết.
Hiệu năng trên các class gốc suy giảm sau fine-tuning#
Hiện tượng này được gọi là catastrophic forgetting - model mất đi kiến thức đã học trước đó khi chỉ fine-tune trên dữ liệu mới. Việc quên kiến thức hầu như không thể tránh khỏi nếu không đưa hình ảnh của dataset gốc vào cùng với dữ liệu mới. Để giảm thiểu hiện tượng này:
- Gộp dataset: đưa các ví dụ của class gốc vào cùng với class mới trong quá trình fine-tuning. Đây là cách đáng tin cậy duy nhất để ngăn việc quên kiến thức.
- Đóng băng backbone và neck: đóng băng cả backbone lẫn neck để chỉ training detection head sẽ hữu ích cho các lượt fine-tuning ngắn với learning rate rất thấp.
- Training trong ít epoch hơn: model training độc quyền trên dữ liệu mới càng lâu thì mức độ quên kiến thức càng tăng.
FAQ#
Không có mức tối thiểu cố định - kết quả phụ thuộc vào độ phức tạp của tác vụ, số class và mức độ tương đồng của domain với COCO. Hình ảnh đa dạng hơn (ánh sáng, góc chụp, background khác nhau) quan trọng hơn số lượng đơn thuần. Hãy bắt đầu với dữ liệu hiện có và tăng quy mô nếu các metric validation chưa đạt yêu cầu.
Load file
.ptpretrained và gọi.train()với path đến mộtdata.yamltùy chỉnh. Ultralytics tự động xử lý chuyển trọng số, khởi tạo lại detection head và chọn optimizer. Xem phần Fine-Tuning Cơ bản để biết ví dụ code hoàn chỉnh.Các nguyên nhân phổ biến nhất là path hình ảnh không hợp lệ, file label bị thiếu hoặc rỗng, sự không khớp giữa
nctrong YAML và các file label thực tế, hoặc ngưỡng confidence quá cao. Xem Các Vấn đề Thường gặp để biết checklist khắc phục sự cố đầy đủ.Điều này phụ thuộc vào kích thước dataset và mức độ tương đồng của domain. Với dataset nhỏ có domain tương tự COCO, đóng băng backbone (
freeze=10) giúp ngăn overfitting. Với domain rất khác COCO, để tất cả layer không bị đóng băng (freeze=None) cho phép backbone thích nghi. Xem Đóng băng Layer để biết các khuyến nghị chi tiết.Đưa các ví dụ của class gốc vào dữ liệu training cùng với class mới. Nếu không thể thực hiện, đóng băng nhiều layer hơn (
freeze=10hoặc cao hơn) và sử dụng learning rate thấp hơn sẽ giúp bảo toàn kiến thức pretrained. Xem Hiệu năng trên các class gốc suy giảm để biết thêm chi tiết.