Cách tinh chỉnh YOLO trên một tập dữ liệu tùy chỉnh#
Fine-tuning giúp điều chỉnh mô hình đã huấn luyện trước để nhận diện các lớp mới bằng cách bắt đầu từ trọng số đã học thay vì khởi tạo ngẫu nhiên. Thay vì huấn luyện lại từ đầu trong hàng trăm epoch, quá trình tinh chỉnh tận dụng các đặc trưng COCO đã được huấn luyện trước và hội tụ trên dữ liệu tùy chỉnh chỉ trong một phần thời gian.
Hướng dẫn này đề cập đến việc tinh chỉnh YOLO26 trên các tập dữ liệu 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 lớp và huấn luyện hai giai đoạn.
Tinh chỉnh so với Huấn luyện từ đầu#
Một mô hình đã huấn luyện trước đã học các đặc trưng trực quan tổng quát - phát hiện cạnh, nhận dạng kết cấu, hiểu hình dạng - từ hàng triệu hình ảnh. Học chuyển giao thông qua tinh chỉnh sẽ tái sử dụng kiến thức đó và chỉ dạy mô hình hình dạng của các lớp mới, đó là lý do tại sao nó hội tụ nhanh hơn và yêu cầu ít dữ liệu hơn. Huấn luyện từ đầu sẽ loại bỏ tất cả những điều đó và buộc mô hình phải học mọi thứ từ các mẫu ở cấp độ điểm ảnh, điều này đòi hỏi tài nguyên lớn hơn đáng kể.
| Tinh chỉnh (Fine-Tuning) | Huấn luyện từ đầu | |
|---|---|---|
| Trọng số bắt đầu | Được huấn luyện trước trên COCO (80 lớp) | Khởi tạo ngẫu nhiên |
| Câu lệnh | YOLO("yolo26n.pt") | YOLO("yolo26n.yaml") |
| Hội tụ | Nhanh hơn - backbone đã được huấn luyện | Chậm hơn - tất cả các lớp học từ con số không |
| Yêu cầu dữ liệu | Thấp hơn - các đặc trưng huấn luyện trước bù đắp cho việc thiếu dữ liệu | Cao hơn - model phải học tất cả đặc trưng chỉ từ tập dữ liệu |
| Khi nào nên sử dụng | Các lớp tùy chỉnh với hình ảnh tự nhiên | Các lĩnh vực khác biệt hoàn toàn với COCO (y tế, vệ tinh, radar) |
Khi một tệp .pt được tải bằng YOLO("yolo26n.pt"), các trọng số đã huấn luyện trước sẽ được lưu trữ trong mô hình. Việc gọi .train(data="custom.yaml") sau đó sẽ tự động chuyển tất cả các trọng số tương thích sang kiến trúc mô hình mới, khởi tạo lại bất kỳ lớp nào không khớp (chẳng hạn như phần đầu phát hiện khi số lượng lớp khác nhau) và bắt đầu quá trình huấn luyện. Không cần tải trọng số thủ công, thao tác lớp hoặc mã học chuyển giao tùy chỉnh.
Cách thức hoạt động của việc chuyển đổi trọng số huấn luyện trước#
Khi một model đã được huấn luyện trước được tinh chỉnh trên một tập dữ liệu có số lượng lớp khác nhau (ví dụ: 80 lớp của COCO sang 5 lớp tùy chỉnh), Ultralytics thực hiện chuyển đổi trọng số nhận biết hình dạng:
- Backbone và neck chuyển đổi hoàn toàn - các lớp này trích xuất các đặc trưng hình ảnh tổng quát và hình dạng của chúng độc lập với số lượng lớp.
- Đầu phát hiện được khởi tạo lại một phần - các lớp đầu ra phân loại (
cv3,one2one_cv3) có hình dạng gắn liền với số lượng lớp (80 so với 5), vì vậy chúng không thể chuyển giao và được khởi tạo ngẫu nhiên. Các lớp hồi quy hộp (cv2,one2one_cv2) ở phần đầu có hình dạng cố định bất kể số lượng lớp, do đó chúng chuyển giao bình thường. - Đa số các trọng số được chuyển đổi khi thay đổi số lượng lớp. Ví dụ: tinh chỉnh YOLO26n từ COCO (80 lớp) sang một tập dữ liệu 5 lớp sẽ chuyển đổi 606 trong số 708 tensor trọng số: chỉ các lớp phân loại phụ thuộc vào số lượng lớp mới được khởi tạo lại, trong khi các nhánh backbone, neck và hồi quy bbox vẫn còn nguyên vẹn.
Đối với các tập dữ liệu có cùng số lượng lớp với model huấn luyện trước (ví dụ: tinh chỉnh các trọng số đã huấn luyện trước trên COCO sang một tập dữ liệu 80 lớp khác), 100% trọng số sẽ chuyển đổi bao gồm cả head phát hiện.
Truyền Chuyển đổi Lớp với Bí danh Tên#
Ultralytics truyền các hàng phần đầu phân loại khớp theo tên lớp giữa các tập dữ liệu, bỏ qua chữ hoa chữ thường và khoảng trắng xung quanh. Khi các lớp tương đương sử dụng các tên khác nhau, hãy đổi tên các lớp checkpoint nguồn trong bộ nhớ trước khi tải. Thao tác này bảo lưu trọng số phân loại được huấn luyện trước cho các khái niệm được chia sẻ mà nếu không sẽ được coi là không khớp và được khởi tạo ngẫu nhiên.
Ví dụ chuyển đổi Objects365 v2 sang COCO này đổi tên các lớp nguồn trên điểm kiểm tra đã tải, sau đó train() sẽ truyền qua dưới dạng trọng số đã huấn luyện trước:
from ultralytics import YOLO
# Source Objects365 v2 name -> 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")
model.model.names = {i: ALIASES.get(name, name) for i, name in model.model.names.items()}
model.train(data="coco.yaml", epochs=100, imgsz=640)Ví dụ tinh chỉnh cơ bản#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load pretrained model
model.train(data="custom.yaml", epochs=50, imgsz=640)Chọn kích thước model#
Các mô hình lớn hơn có dung lượng lớn hơn nhưng cũng có nhiều tham số cần cập nhật hơn, điều này có thể làm tăng nguy cơ quá khớp (overfitting) khi dữ liệu huấn luyện bị hạn chế. Bắt đầu với một mô hình nhỏ hơn (YOLO26n hoặc YOLO26s) và tăng dần quy mô chỉ khi các chỉ số xác thực đạt mức ổn định là một cách tiếp cận thực tế. Kích thước mô hình tối ưu phụ thuộc vào độ phức tạp của tác vụ, số lượng lớp, tính đa dạng của tập dữ liệu và phần cứng có sẵn để triển khai. Xem trang mô hình YOLO26 đầy đủ để biết các kích thước khả dụng và điểm chuẩn hiệu suất.
Lựa chọn bộ tối ưu hóa (Optimizer) và tốc độ học (Learning Rate)#
Thiết lập optimizer=auto mặc định sẽ chọn trình tối ưu hóa và tốc độ học dựa trên tổng số vòng lặp huấn luyện:
- < 10,000 lần lặp (tập dữ liệu nhỏ hoặc ít epoch): AdamW với tốc độ học thấp, được tính toán tự động
- > 10.000 vòng lặp (tập dữ liệu lớn): MuSGD (trình tối ưu hóa kết hợp Muon+SGD) với lr=0,01
Đối với hầu hết các tác vụ tinh chỉnh, cài đặt mặc định hoạt động tốt mà không cần điều chỉnh thủ công. Hãy cân nhắc đặt bộ tối ưu hóa một cách rõ ràng khi:
- Huấn luyện không ổn định (mất mát tăng vọt hoặc phân kỳ): thử
optimizer=AdamW, lr0=0.001để hội tụ ổn định hơn - Tinh chỉnh một mô hình lớn trên tập dữ liệu nhỏ: tốc độ học thấp hơn như
lr0=0.001giúp giữ nguyên các đặc trưng đã huấn luyện trước
Khi optimizer=auto, các giá trị lr0 và momentum sẽ bị bỏ qua. Để kiểm soát tốc độ học theo cách thủ công, hãy thiết lập rõ ràng trình tối ưu hóa: optimizer=SGD, lr0=0.005.
Đóng băng lớp (Freezing Layers)#
Việc đóng băng ngăn các lớp cụ thể cập nhật trong quá trình huấn luyện. Điều này giúp tăng tốc độ huấn luyện và giảm hiện tượng quá khớp khi tập dữ liệu nhỏ so với dung lượng của mô hình.
Tham số freeze chấp nhận một số nguyên hoặc một danh sách. Một số nguyên freeze=10 đóng băng 10 lớp đầu tiên (chỉ mục 0-9), bao gồm hầu hết phần xương sống (backbone) của YOLO26. Phần xương sống kéo dài từ lớp 0-10, do đó freeze=10 giữ cho khối C2PSA cuối cùng (lớp 10) có thể huấn luyện được; sử dụng freeze=11 để đóng băng toàn bộ phần xương sống. Một danh sách có thể chứa các chỉ mục lớp như freeze=[0, 3, 5] để đóng băng một phần xương sống, hoặc các chuỗi tên mô-đun như freeze=["23.cv2", "23.one2one_cv2"] để kiểm soát chi tiết các nhánh cụ thể trong một lớp (ở đây là cả hai nhánh hồi quy hộp của đầu phát hiện).
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 miền mục tiêu và dữ liệu huấn luyện trước, cũng như lượng dữ liệu huấn luyện khả dụng:
| Kịch bản | Khuyến nghị | Lý do |
|---|---|---|
| Tập dữ liệu lớn, miền tương đồng | freeze=None (mặc định) | Đủ dữ liệu để thích nghi tất cả các lớp mà không bị quá khớp |
| Tập dữ liệu nhỏ, miền tương đồng | freeze=10 | Bảo toàn các đặc trưng backbone, giảm các tham số huấn luyện |
| Tập dữ liệu rất nhỏ | freeze=23 | Chỉ head phát hiện được huấn luyện, giảm thiểu rủi ro quá khớp |
| Miền khác xa COCO | freeze=None | Các đặc trưng backbone có thể không chuyển đổi tốt và cần huấn luyện lại |
Độ sâu đóng băng cũng có thể được coi là một siêu tham số - thử một vài giá trị (0, 5, 10) và so sánh mAP validation là một cách thực tế để tìm cài đặt tốt nhất cho một tập dữ liệu cụ thể.
Các siêu tham số chính cho việc tinh chỉnh#
Việc tinh chỉnh thường yêu cầu ít điều chỉnh siêu tham số hơn so với huấn luyện từ đầu. Các tham số quan trọng nhất là:
epochs: Quá trình tinh chỉnh hội tụ nhanh hơn so với huấn luyện từ đầu. Bắt đầu với một giá trị vừa phải và sử dụngpatienceđể dừng sớm khi các chỉ số xác thực đạt mức ổn định.patience: Giá trị mặc định là 100 được thiết kế cho các đợt huấn luyện dài. Việc giảm giá trị này xuống 10-20 giúp tránh lãng phí thời gian cho các đợt đã hội tụ.warmup_epochs: Quá trình khởi động mặc định (3 epoch) sẽ tăng dần tốc độ học từ số không, giúp ngăn các bản cập nhật gradient lớn làm hỏng các đặc trưng đã huấn luyện trước trong các vòng lặp đầu tiên. Nên giữ nguyên mặc định ngay cả khi tinh chỉnh.
Để có danh sách đầy đủ các tham số huấn luyện, hãy xem tài liệu tham khảo cấu hình huấn luyện.
Tinh chỉnh hai giai đoạn#
Tinh chỉnh hai giai đoạn chia quá trình huấn luyện thành hai giai đoạn. Giai đoạn đầu tiên đóng băng backbone và chỉ huấn luyện neck và head, cho phép các lớp phát hiện thích nghi với các lớp mới mà không làm gián đoạn các đặc trưng đã huấn luyện trước. Giai đoạn thứ hai mở đóng băng tất cả các lớp và huấn luyện toàn bộ model với tốc độ học thấp hơn để tinh chỉnh backbone cho miền mục tiêu.
Phương pháp này đặc biệt hữu ích khi miền mục tiêu khác biệt đáng kể so với COCO (hình ảnh y tế, hình ảnh trên không, kính hiển vi), nơi phần xương sống có thể cần điều chỉnh nhưng việc huấn luyện mọi thứ cùng lúc gây ra sự mất ổn định. Để tự động rã đông bằng phương pháp dựa trên callback, hãy xem Đóng băng và Rã đông Phần xương sống.
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, lr0=0.001, name="stage2", exist_ok=True)Các lỗi thường gặp#
Model không đưa ra dự đoán nào#
- Dữ liệu huấn luyện không đầy đủ: huấn luyện với rất ít mẫu 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ừ quá ít dữ liệu. Hãy đảm bảo có đủ các ví dụ đa dạng cho mỗi lớp trước khi tìm hiểu các nguyên nhân khác.
- Kiểm tra đường dẫn tập dữ liệu: đường dẫn không chính xác trong
data.yamlsẽ âm thầm tạo ra các nhãn bằng không. Chạyyolo detect val model=yolo26n.pt data=custom.yamltrước khi huấn luyện để xác nhận nhãn tải chính xác. - Giảm ngưỡng độ tin cậy: nếu có các dự đoán nhưng bị lọc bỏ, hãy thử
conf=0.1trong quá trình suy luận. - Xác minh số lượng lớp: đảm bảo
nctrongdata.yamlkhớp với số lượng lớp thực tế trong các tệp nhãn.
mAP validation chững lại sớm#
- Thêm dữ liệu: tinh chỉnh hưởng lợi đáng kể từ dữ liệu huấn luyện bổ sung, đặc biệt là các ví dụ đa dạng với góc độ, ánh sáng và nền khác nhau.
- Kiểm tra độ cân bằng lớp: các lớp có ít đại diện sẽ có AP thấp. Sử dụng
cls_pwđể áp dụng trọng số lớp tần suất nghịch đảo (bắt đầu vớicls_pw=0.25cho sự mất cân bằng vừa phải, tăng lên1.0cho sự mất cân bằng nghiêm trọng). - Giảm tính năng tăng cường: đối với các tập dữ liệu rất nhỏ, việc tăng cường mạnh có thể gây hại nhiều hơn là có lợi. Hãy thử
mosaic=0.5hoặcmosaic=0.0. - Tăng độ phân giải: đối với các tập dữ liệu có các đối tượng nhỏ, hãy thử
imgsz=1280để giữ lại chi tiết.
Hiệu năng suy giảm trên các lớp gốc sau khi tinh chỉnh#
Đây được gọi là hiện tượng quên thảm họa (catastrophic forgetting) - model mất đi kiến thức đã học trước đó khi chỉ được tinh chỉnh trên dữ liệu mới. Việc quên hầu như không thể tránh khỏi nếu không bao gồm các hình ảnh tập dữ liệu gốc cùng với dữ liệu mới. Để giảm thiểu điều này:
- Hợp nhất các tập dữ liệu: bao gồm các ví dụ về các lớp gốc cùng với các lớp mới trong quá trình tinh chỉnh. Đây là cách duy nhất đáng tin cậy để ngăn chặn việc quên.
- Đóng băng backbone và neck: đóng băng cả backbone và neck để chỉ head phát hiện huấn luyện sẽ giúp ích cho các lần tinh chỉnh ngắn với tốc độ học rất thấp.
- Huấn luyện ít epoch hơn: model huấn luyện càng lâu trên dữ liệu mới hoàn toàn, sự quên càng tăng lên.
Câu hỏi thường gặp#
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ố lượng lớp và mức độ tương đồng của miền với COCO. Hình ảnh đa dạng hơn (ánh sáng, góc độ, nền khác nhau) quan trọng hơn số lượng thô. Hãy bắt đầu với những gì bạn có và mở rộng nếu các chỉ số validation không đạt yêu cầu.
Tải tệp
.ptđã huấn luyện trước và gọi.train()với đường dẫn đếndata.yamltùy chỉnh. Ultralytics tự động xử lý việc chuyển trọng số, khởi tạo lại đầu phát hiện và chọn trình tối ưu hóa. Xem phần Tinh chỉnh Cơ bản để biết ví dụ mã hoàn chỉnh.Nguyên nhân phổ biến nhất là đường dẫn không chính xác trong
data.yaml(làm âm thầm tạo ra các nhãn bằng không), sự không khớp giữanctrong tệp YAML và các tệp nhãn thực tế, hoặc ngưỡng độ tin cậy quá cao. Xem Các lỗi phổ biến để có danh sách kiểm tra khắc phục sự cố đầy đủ.Điều này phụ thuộc vào kích thước tập dữ liệu và độ tương đồng về miền. Đối với các tập dữ liệu nhỏ có miền tương tự như COCO, việc đóng băng phần xương sống (
freeze=10) giúp ngăn ngừa hiện tượng quá khớp. Đối với các miền rất khác so với COCO, việc để tất cả các lớp rã đông (freeze=None) cho phép phần xương sống thích ứng. Xem Đóng băng các lớp để biết các khuyến nghị chi tiết.Bao gồm các ví dụ về các lớp ban đầu trong dữ liệu huấn luyện cùng với các lớp mới. Nếu điều đó là không thể, việc đóng băng nhiều lớp hơn (
freeze=10trở lên) và sử dụng tốc độ học thấp hơn sẽ giúp bảo tồn kiến thức đã huấn luyện trước. Xem Hiệu suất suy giảm trên các lớp ban đầu để biết thêm chi tiết.