Xác thực và metric
Xác thực chạy mô hình trên một split của dataset qua val() và trả về dictionary phẳng gồm các key metric và giá trị float. Các key là chuỗi literal, và tập key nhận được phụ thuộc vào tác vụ chứ không phải family.
Chạy xác thực
val() nhận dataset và trả về các metric.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")metrics = model.val(data="coco8.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])print(metrics["speed/total_ms"])libreyolo val model=LibreYOLO9s.pt data=coco8.yamlfrom libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")metrics = model.val(data="coco8.yaml", split="train", batch=4) print(metrics)Giá trị trả về là một dict phẳng ánh xạ các key metric tới số. Mọi key đều là
literal, vì vậy hãy đọc theo tên thay vì vị trí. Với detect, segment và classify
nó là một lớp con của dict có thêm kết quả theo từng lớp đối tượng dưới dạng
thuộc tính, được mô tả bên dưới.
Các đối số chính là data, split, batch, imgsz, conf, iou, workers,
device, augment, save_json và verbose. conf mặc định là 0.001 và
iou là 0.6, đều lỏng hơn nhiều so với giá trị mặc định khi dự đoán vì một
lượt quét mAP cần phần đuôi có độ tin cậy thấp. imgsz mặc định theo kích thước
đầu vào riêng của mô hình thay vì một số cố định. split nhận val, test
hoặc train và không nhận giá trị nào khác. Khi không có data, một checkpoint
đã huấn luyện được xác thực trên dataset mà nó đã được huấn luyện; trọng số đã
phát hành không mang dataset nào và cần data=.
Mọi trường khác của cấu hình xác thực được truyền qua dưới dạng đối số keyword,
gồm save_dir, max_det, eval_max_det, half, amp_dtype, cache,
save_plots, single_cls và agnostic_nms. Với half=True trên CUDA, việc xác
thực chạy dưới autocast ở amp_dtype, và đầu ra bfloat16 được ép sang float32
trước khi hậu xử lý; huấn luyện với amp_dtype="bfloat16" cũng xác thực theo cách
đó.
agnostic_nms=True chỉ giữ box có điểm cao nhất trong các box chồng lấn vượt
iou, bất kể lớp của chúng. Nó chạy trên các phát hiện đã hoàn tất của family,
sau classes=, nên mAP, confusion matrix, các đường cong và số đếm theo từng ảnh
đều chấm điểm cùng các box. Nó bao phủ detect và segment, và mọi tác vụ khác phát
sinh ValueError. Phía predict nằm ở Ngưỡng và lọc.
single_cls=True chấm điểm phát hiện như một lớp đối tượng duy nhất. Ground truth
được gộp về lớp 0, và các phát hiện của mô hình được giữ theo classes= trong
không gian nhãn của chính mô hình, rồi gán lại nhãn 0, nên một checkpoint được
huấn luyện trên nhiều lớp đối tượng được chấm điểm như một detector một lớp.
Key metric theo từng tác vụ
Phát hiện trả về nhóm số liệu COCO:
metrics/mAP50-95 metrics/mAP50 metrics/mAP75metrics/mAP_small metrics/mAP_medium metrics/mAP_largemetrics/AR1 metrics/AR10 metrics/AR100 metrics/AR_max_detmetrics/AR_small metrics/AR_medium metrics/AR_largemetrics/precision metrics/recallmetrics/precision(B) metrics/recall(B) metrics/mAP50(B) metrics/mAP50-95(B)Hai key trong đó dễ gây nhầm lẫn. metrics/precision và metrics/recall là các
alias được giữ để tương thích ngược: chúng mang giá trị mAP 50-95 và AR@100,
không phải một cặp precision và recall. Hãy dùng các key có tên cụ thể.
Phân đoạn thực thể trả về các số liệu mAP và AR ở trên dưới dạng số liệu mặt nạ
trong các key không có hậu tố, với phiên bản hộp dưới hậu tố (B) và phiên bản
mặt nạ được lặp lại dưới (M). Với tác vụ này, precision và recall chỉ tồn tại
ở dạng có hậu tố metrics/precision(B)/metrics/recall(B) và
metrics/precision(M)/metrics/recall(M), cả hai cặp mang cùng giá trị alias
như detect: cặp (B) là mAP50-95 và AR@100 của hộp, cặp (M) là mAP50-95 và
AR@100 của mặt nạ.
| Tác vụ | Key |
|---|---|
| detect | metrics/mAP50-95, metrics/mAP50, metrics/mAP75, cùng phân tích theo kích thước và recall ở trên |
| segment | phiên bản mặt nạ của các key detect ở trên (key không hậu tố là mặt nạ); precision/recall chỉ có dạng (B)/(M), cả hai được alias theo cùng cách |
| pose | metrics/keypoints_mAP50-95, metrics/keypoints_mAP50, metrics/keypoints_mAP75, metrics/keypoints_mAP_M, metrics/keypoints_mAP_L, và các key keypoints_AR tương ứng |
| obb | metrics/mAP50-95, metrics/mAP50, metrics/mAP75, metrics/precision, metrics/recall, cùng các bản sao có hậu tố (OBB) |
| classify | metrics/accuracy_top1, metrics/accuracy_top5 |
| semantic | metrics/mIoU, metrics/pixel_accuracy |
| panoptic | metrics/PQ, metrics/SQ, metrics/RQ, metrics/PQ_things, metrics/PQ_stuff, metrics/categories |
| depth | metrics/abs_rel, metrics/rmse, metrics/delta1, metrics/delta2, metrics/delta3 |
| normal | metrics/mean_angular_error, metrics/median_angular_error, metrics/within_11_25, metrics/within_22_5, metrics/within_30 |
| edge | metrics/ODS, metrics/OIS, metrics/best_threshold |
| restore | metrics/PSNR, metrics/SSIM |
| matte | metrics/MAE, metrics/Smeasure |
| ocr | metrics/det_precision, metrics/det_recall, metrics/det_hmean, metrics/e2e_precision, metrics/e2e_recall, metrics/e2e_f1, metrics/rec_1-NED |
| point | metrics/precision, metrics/recall, metrics/f1, metrics/MLE, metrics/MAE, metrics/RMSE, cùng một key quét mAP |
metrics/precision và metrics/recall của OBB không phải alias: chúng là
precision và recall thực ở IoU 0.50, lấy tại operating point lỏng nhất (mọi dự
đoán vượt qua conf, mặc định 0.001). Các bản sao có hậu tố (OBB) lặp lại
cùng bốn giá trị dưới tên theo tác vụ, cùng quy ước với (B) và (M) ở trên.
accuracy_top5 thực ra là top-min(5, num_classes), vì vậy trên dataset ba lớp,
nó là top-3 mà mọi sample đều thỏa mãn, nên giá trị là 1.0.
Kết quả phân loại cũng cung cấp hai giá trị này dưới dạng các thuộc tính top1 và
top5, bên cạnh confusion_matrix.
Key quét của tác vụ point được dựng từ các ngưỡng khoảng cách, vì vậy với giá
trị mặc định, nó là metrics/mAP@[0.01:0.10] và key một ngưỡng là
metrics/mAP@0.01. Truyền dist_thresholds sẽ thay đổi cả hai chuỗi.
Phần lớn tác vụ còn trả về key fitness, là số đơn mà cơ chế chọn checkpoint
tốt nhất sử dụng theo mặc định. Phát hiện, phân đoạn và OBB không có key này;
family của chúng được chọn theo metrics/mAP50-95, vốn có trong dictionary trả
về. Tư thế không trả về fitness lẫn metrics/mAP50-95; thay vào đó, trainer
của tác vụ đặt best_metric_key thành metrics/keypoints_mAP50-95.
Phân loại ImageFolder bổ sung macro metrics/precision, metrics/recall và metrics/f1, lấy trung bình trên các lớp đối tượng có trong nhãn đích đánh giá. Top-1 vẫn là fitness mặc định. Phát hiện còn trả về metrics/best_conf và metrics/best_conf_f1, chọn ngưỡng tối ưu micro-F1 tại IoU 0.50, và đặt các ngưỡng với khóa là tên lớp đối tượng trên metrics.box.best_conf_per_class. Các phát hiện cùng điểm vẫn được nhóm chung; khi hòa chọn ngưỡng cao hơn. Không có F1 dương sẽ cho 0.0. Phân đoạn không cung cấp các khóa ngưỡng này.
Confusion matrix
Kết quả detect, segment và classify mang results.confusion_matrix. Nó được tính
ở mọi lần xác thực, dù có ghi biểu đồ hay không, và matrix của nó là một mảng
số nguyên lập chỉ mục matrix[predicted, true].
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")metrics = model.val(data="coco8.yaml") cm = metrics.confusion_matrixprint(cm.matrix.shape) # (81, 81): 80 lớp đối tượng cộng backgroundprint(cm.class_accuracy()) # tên lớp: tỉ lệ đối tượng tìm thấy được gán lớp đótp, fp = cm.tp_fp()Với detect và segment, các dự đoán ở độ tin cậy 0.25, hoặc conf nếu cao hơn, được
ghép một-một với các box ground truth thuộc bất kỳ lớp nào ở IoU 0.5, theo thứ tự
IoU cao nhất trước. Một cặp được đếm ở lớp dự đoán và lớp thật của nó, nên một box
đặt đúng chỗ nhưng sai lớp rơi ra ngoài đường chéo. Ma trận có thêm một hàng và
cột background: một ground truth không được ghép cặp được đếm ở hàng
background, một dự đoán không được ghép cặp ở cột background. Segmentation
ghép cặp box, không phải mặt nạ. Với classes=, ground truth của các lớp khác bị
bỏ ra.
Các vùng crowd của COCO (iscrowd=1) theo quy tắc mà mAP áp dụng. Một dự đoán mà
không ground truth nào cùng lớp khớp, nằm ít nhất một nửa bên trong một vùng crowd
cùng lớp (phần giao chia cho diện tích của chính dự đoán), bị bỏ qua thay vì được
đếm. box.image_metrics và các ảnh visualize=True dùng cùng ngưỡng và cùng quy
tắc crowd. Nhãn định dạng YOLO không có vùng crowd.
Với classify, mỗi ảnh được đếm một lần, ở lớp top-1 của nó so với nhãn, và không
có background.
| Phương thức | Trả về |
|---|---|
summary(normalize=False) | Một dict cho mỗi lớp dự đoán, {"Predicted": name, <true class>: value}; với normalize, tỉ lệ của mỗi lớp thật |
to_csv(), to_json() | Phần tóm tắt dưới dạng văn bản CSV hoặc JSON |
to_df() | Phần tóm tắt dưới dạng Polars DataFrame; cần pip install polars |
tp_fp() | True positive theo từng lớp (đường chéo) và false positive (phần còn lại của hàng dự đoán) |
nonzero() | Các ô có giá trị dưới dạng các mảng (predicted, true, count) thẳng hàng |
class_accuracy() | Theo từng lớp, tỉ lệ các instance của nó được gán lớp đó; với detection, chỉ tính các đối tượng tìm thấy |
plot(normalize=True, save_dir="") | Ghi confusion_matrix_normalized.png, hoặc confusion_matrix.png với normalize=False, và trả về đường dẫn |
Trên 2,000 lớp đối tượng, ma trận phân loại dày đặc không được dựng: matrix,
summary(), các hàm xuất to_*() và plot() phát sinh lỗi, trong khi tp_fp(),
nonzero() và class_accuracy() vẫn hoạt động.
Lớp này là libreyolo.validation.ConfusionMatrix, được dựng bằng
ConfusionMatrix(nc, iou_thres=0.5, conf_thres=0.25, *, names=None, task="detect"),
trong đó task là "detect" hoặc "classify".
Precision, recall và F1 theo từng lớp đối tượng
Kết quả detect và segment mang precision, recall và F1 của từng lớp đối tượng qua các ngưỡng độ tin cậy, ghép cặp ở IoU 0.5.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")metrics = model.val(data="coco8.yaml") box = metrics.boxprint(box.px.shape, box.f1_curve.shape) # (1000,) và (classes, 1000)for index, f1 in zip(box.ap_class_index, box.f1): print(model.names[int(index)], round(float(f1), 3))box.px giữ 1000 độ tin cậy, cách đều nhau trên [0, 1]. box.p_curve,
box.r_curve và box.f1_curve là các mảng (classes, 1000), mỗi hàng ứng với một
phần tử của box.ap_class_index, là các chỉ số lớp đối tượng có ground truth trong
split, theo thứ tự tăng dần. box.p, box.r và box.f1 là các giá trị theo từng
lớp ở độ tin cậy làm cực đại F1 trung bình trên các lớp đó. Segmentation tính tất
cả từ box. Chúng là các mảng rỗng khi lượt chạy không tạo ra đường cong nào.
Chỉ số bounding box theo ảnh
Kết quả phát hiện và phân đoạn vẫn tương thích dictionary và còn cung cấp results.box.image_metrics. Mỗi tên tệp ánh xạ đến precision, recall, f1, tp, fp và fn theo quy tắc ghép cặp của trực quan hóa, kể cả khi tắt trực quan hóa. Phân đoạn đếm bounding box ở đây. Tên tệp trùng dùng đường dẫn đầy đủ sau lần xuất hiện đầu. Mẫu số bằng 0 cho kết quả 0.0. Các bản ghi này không được tổng hợp qua các rank phân tán.
Key tốc độ
Mọi validator đều thêm thời gian:
speed/preprocess_ms speed/inference_ms speed/postprocess_msspeed/total_ms speed/total_s speed/images_seenĐây là số mili giây trên mỗi ảnh, lấy trung bình trong lượt chạy. Chúng mô tả máy và cài đặt bạn đã chạy, vì vậy một số liệu lấy từ đây chỉ có ý nghĩa khi được báo cáo cùng phần cứng, kích thước batch và precision.
Backend đánh giá
Metric phát hiện và phân đoạn được tính qua COCO evaluator, còn
faster_coco_eval=True, giá trị mặc định, chọn backend C++ khi đã cài package
faster-coco-eval. Nếu chưa cài, lượt chạy quay về pycocotools với một cảnh báo
cho mỗi process:
faster_coco_eval requested but not installed; falling back to pycocotools.Install with: pip install faster-coco-evalBackend thực sự chạy được ghi lại trên mô hình dưới dạng last_eval_backend, và
CLI báo cáo nó trong đầu ra cho các tác vụ kiểu phát hiện. Đặt
LIBREYOLO_FASTER_COCO_EVAL để ghi đè giá trị cấu hình từ môi trường.
iou_thresholds chỉ được áp dụng trên đường dẫn OBB. Đường dẫn COCO đánh giá
theo lượt quét cố định riêng từ 0.50 đến 0.95 và bỏ qua giá trị này.
Validation loss
Theo mặc định, xác thực chỉ báo cáo độ chính xác. val_loss=True còn tính
objective huấn luyện của family trên các batch xác thực.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")model.train(data="coco8.yaml", epochs=10, val_loss=True)Nó phát ra metrics/loss cùng một metrics/loss/<component> cho mỗi thành phần,
được gán trọng số chính xác như khi huấn luyện, vì vậy các thành phần cộng lại
thành tổng. Qua logger, chúng xuất hiện dưới dạng val/loss và
val/loss/<component>, còn libreyolo monitor đặt metrics/loss chồng lên
train/loss.
Các thành phần là thành phần riêng của family:
| Tác vụ | Family | Thành phần |
|---|---|---|
| detect | yolo9, yolo9_p2, yolo9_e2e | box, cls, dfl |
| detect | yolonas | cls, iou, dfl |
| detect | rfdetr | ce, bbox, giou |
| detect | rtdetr, rtdetrv2 | vfl, bbox, giou |
| detect | dfine | vfl, bbox, giou, fgl, ddf |
| detect | domedetr | vfl, bbox, giou, fgl, ddf, defe_density, defe_reg |
| detect | deim, deimv2, rtdetrv4, ec | mal, bbox, giou, fgl, ddf |
| detect | rtmdet | cls, bbox |
| detect | picodet | cls, bbox, dfl |
| detect | yolox | iou, obj, cls, l1 |
| detect | yolo7 | iou, obj, cls |
| point | fomo | ce |
| classify | resnet, convnext, mobilenetv4, efficientnetv2 | ce |
| semantic | segformer, lingbotvision, dinov2 | sem |
| restore | nafnet | restore |
Tùy chọn này mặc định tắt vì việc gán target làm tăng thời gian và bộ nhớ xác
thực. Validator dùng lại đầu ra mô hình đã tạo cho metric độ chính xác thay vì
chạy forward pass thứ hai, chạy trong no_grad trên mô hình đánh giá hoặc EMA,
và trong huấn luyện multi-GPU, nó được tính cục bộ trên rank 0 mà không có
collective. Việc chọn checkpoint tốt nhất vẫn dựa trên metric độ chính xác.
Có ba điều được chủ ý không thực hiện. Thứ nhất, nó không bao giờ gồm các thành phần khử nhiễu tương phản vì chúng cần ground truth tại thời điểm forward, còn forward xác thực không nhận dữ liệu đó. Thứ hai, nó báo cáo mô hình ở evaluation mode, vì vậy khi forward train và eval của một family thực sự khác nhau ở statistic BatchNorm hoặc stochastic depth, con số phản ánh eval mode; đây là phép so sánh có chủ ý. Thứ ba, tác vụ chưa được family triển khai sẽ phát sinh lỗi cấu hình khi thiết lập thay vì âm thầm bỏ qua:
val_loss=True currently supports RF-DETR detection only; segment, pose, OBB,classify, and semantic tasks are not supportedFOMO là ngoại lệ không thay đổi gì: validator của family này luôn tính loss đó,
và val_loss=True chỉ ảnh hưởng tới các key dùng để công bố.
Không thể kết hợp xác thực có augmentation với validation loss; yêu cầu cả hai sẽ phát sinh lỗi.
Các tệp được ghi khi xác thực
val() luôn ghi config.yaml vào thư mục lưu, mặc định là
runs/val/<model>_<size>_<timestamp> khi không cung cấp save_dir. project,
name và exist_ok chọn thư mục này theo cách huấn luyện vẫn làm: project/name,
với hậu tố tăng dần trừ khi exist_ok=True.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")model.val(data="coco8.yaml", save_json=True, save_dir="runs/val/exp")save_json=True ghi predictions.json cho phát hiện, còn phân đoạn ghi
predictions_bbox.json cùng predictions_masks.json. OBB không hỗ trợ và sẽ
báo rõ.
save_plots=True, hoặc alias plots=True của nó, ghi vào thư mục con plots/ và
cần matplotlib, được cài bằng pip install "libreyolo[plots]". Phát hiện tạo
box_metrics.png, biểu đồ AP và recall theo từng lớp, đường cong
precision-recall và confidence, các đường cong F1 theo từng lớp trong
f1_conf_box.png, confusion matrix dưới dạng số đếm trong confusion_matrix.png
và dưới dạng tỉ lệ của mỗi lớp thật trong confusion_matrix_normalized.png, cùng
ảnh sample đã chú thích khi cài OpenCV. Phân đoạn thêm bản sao phía mặt nạ của
biểu đồ metric, các biểu đồ theo từng lớp và các đường cong precision-recall và
confidence; các đường cong F1 và confusion matrix vẫn ở mức box. Tư thế có bộ
metric và đường cong riêng. Phân loại ghi hai tệp confusion matrix, trừ khi trên
2,000 lớp đối tượng. Các validator khác không triển khai biểu đồ; ngữ nghĩa, toàn cảnh, độ sâu, pháp tuyến, cạnh, phục hồi, matting, OCR, OBB
và point đều không ghi gì ở đó. Lỗi vẽ biểu đồ sẽ cảnh báo và không bao giờ dừng
lượt chạy.
visualize=True ghi ảnh TP/FP/FN của bounding box có xét lớp đối tượng cho phát hiện và phân đoạn, hoặc ảnh so sánh nhãn với top-1 cho phân loại ImageFolder, vào visualize/errors/ và visualize/correct/. Ghép cặp dùng IoU 0.5 và độ tin cậy max(0.25, conf). Mặc định là visualize=False, show_labels=True và show_conf=True. Các tác vụ không hỗ trợ và đánh giá clip V-JEPA 2 từ chối trực quan hóa.
plot_samples=8 giới hạn biểu đồ ảnh mẫu riêng; 0 tắt nó và -1 giữ mọi ảnh. Điều này không thay đổi chỉ số hay đầu ra trực quan hóa.
Xác thực trong khi huấn luyện
Quá trình huấn luyện xác thực mỗi eval_interval epoch, và luôn xác thực sau
epoch cuối cùng, trên split val của dataset, và các metric tạo ra điều khiển
việc chọn best.pt, early stop theo patience và các key val/ trong mọi
logger. Việc xác thực chạy trên trọng số EMA khi bật EMA. Các tệp của nó được ghi
vào thư mục val/ bên trong lượt chạy. val=False tắt xác thực trong khi huấn
luyện, kể cả ở epoch cuối.
Xem Siêu tham số để biết eval_interval,
patience và save_plots, và Logger thí nghiệm để biết
các con số được đưa tới đâu.
Nội dung liên quan
- Xem Dataset để biết các key split và định dạng mà validator đọc.