拓冰建站拓冰建站
首页 / 资讯中心 / 正文

supervision 模型基准测试实战指南:mAP、F1 Score 与混淆矩阵全流程解析

supervision 模型基准测试实战指南mAP、F1 Score 与混淆矩阵全流程解析【免费下载链接】supervisionWe write your reusable computer vision tools. 项目地址: https://gitcode.com/GitHub_Trending/su/supervision本篇指南面向需要横向对比多个目标检测/实例分割模型效果的开发者完整讲解基于supervision的模型基准测试Benchmark流程如何加载 YOLO 格式数据集、构建推理评测循环、重映射类别、可视化预测结果并用MeanAveragePrecisionmAP、F1Score与sv.ConfusionMatrix输出可量化的性能结论。读完后你可以独立完成一套可复制的模型评测方案并理解 mAP 计算背后的 COCO 评测器实现细节。整体流程分为四步准备带标注的评测数据集加载待评测的模型运行模型逐图收集predictions与targets用supervision.metrics中的指标计算 mAP、F1或用混淆矩阵做可视化诊断。指南以实例分割模型为例展开但同样的流程同样适用于目标检测、实例分割与旋转框OBB模型。一、环境准备下载数据集与加载模型1.1 安装依赖基准测试通常涉及三个库roboflow管理与下载数据集、inference调用本地或云端模型、supervision评测指标注意安装带metrics的可选依赖以启用绘图等能力pip install roboflow inference supervision[metrics]1.2 下载数据集评测的前提是一个带标注的数据集。使用roboflow包下载from roboflow import Roboflow rf Roboflow(api_keyYOUR_API_KEY) project rf.workspace(WORKSPACE_NAME).project(PROJECT_NAME) dataset project.version(DATASET_VERSION_NUMBER).download(FORMAT)指南示例使用的是一个小型 Corgi v2 数据集标注质量高且自带测试集rf Roboflow(api_keyYOUR_API_KEY) project rf.workspace(fbamse1-gm2os).project(corgi-v2) dataset project.version(4).download(yolov11)下载后会在当前工作目录生成Corgi-v2-4文件夹其中包含train、test、valid三个目录以及一个data.yaml文件。data.yaml中记录了类别名称与 ID后续加载数据集和重映射类别都会用到它。1.3 加载模型根据所用框架选择对应方式加载模型关键区别在于模型输出转成sv.Detections的方式RF-DETR预训练检测/分割 checkpoint 由rfdetr包提供其predict方法直接返回Detections对象评测循环中无需额外转换from rfdetr.detr import RFDETRSegSmall model RFDETRSegSmall()Inference本地预训练模型Roboflow Inference 提供多种预训练模型且无需 API Keyfrom inference import get_model model get_model(model_idyolov11s-seg-640)Inference平台部署模型在 Roboflow 平台上训练并部署的模型用项目名/模型版本作为 model_idfrom inference import get_model model_id PROJECT_NAME/MODEL_VERSION model get_model(model_idmodel_id)Ultralyticspip install ultralytics8.3.40from ultralytics import YOLO model YOLO(yolo11s-seg.pt)二、评测基准测试的基本问题用哪个数据集选错评测集是基准测试中最常见的错误。四种场景的判断标准如下无关数据集Unrelated Dataset如果有一份从未参与该模型训练的数据集这是最佳选择。训练集Training Set仅当模型不是在该数据上训练时可用。否则绝不要用它做基准测试——结果会虚高得不真实。验证集Validation Set模型训练过程中每个 N 个 epoch 都会在其上评估验证损失往往直接决定是否停止训练。因此即使模型没有直接在这批图上做梯度更新它也已经间接影响了训练结果评测结果可能偏乐观。测试集Test Set专门保留下来的测试数据模型在训练期间从未见过——这才是基准测试应该使用的集合。因此无关数据集或test集是基准测试的首选。但使用无关数据集时还会遇到三类典型陷阱额外类别无关数据集中可能包含模型不认识的类别需要在计算指标前将其过滤掉可参考 过滤检测结果指南。类别不匹配无关数据集的类别名/ID 与模型输出的类别体系不同需要重映射见下文运行模型一节。数据污染如果test集划分不当部分图片可能实际出现在training或validation中结果会过于乐观训练与测试图拍摄于相同环境、光照、角度等高度相似的情况同样会导致此问题。缺少测试集部分数据集不带测试集。此时应自行收集并标注数据退而求其次可用验证集但要意识到结果偏乐观并尽快在真实场景中验证。三、运行模型用 DetectionDataset 构建评测循环有了评测数据集和模型后用sv.DetectionDataset.from_yolo创建数据集迭代器然后对每张图运行模型。其实现位于 DetectionDataset.from_yolo关键参数包括images_directory_path图片目录annotations_directory_pathYOLO 标注目录data_yaml_path记录类别信息的data.yamlforce_masks为True时强制为所有标注加载掩码is_obb为True时以 OBB 格式[class_id, x, y, x, y, x, y, x, y]读取标注show_progress为True时显示 tqdm 进度条。返回的DetectionDataset是一个可迭代对象每次迭代产出(image_path, image, label)三元组其中label即该图的地真Detectionstargets。RF-DETR 版本predict直接返回Detectionsimport supervision as sv test_set sv.DetectionDataset.from_yolo( images_directory_pathf{dataset.location}/test/images, annotations_directory_pathf{dataset.location}/test/labels, data_yaml_pathf{dataset.location}/data.yaml, ) image_paths [] predictions_list [] targets_list [] for image_path, image, label in test_set: predictions model.predict(image[:, :, ::-1]) image_paths.append(image_path) predictions_list.append(predictions) targets_list.append(label)Inference 版本用sv.Detections.from_inference转换模型输出import numpy as np import supervision as sv test_set sv.DetectionDataset.from_yolo( images_directory_pathf{dataset.location}/test/images, annotations_directory_pathf{dataset.location}/test/labels, data_yaml_pathf{dataset.location}/data.yaml, ) image_paths [] predictions_list [] targets_list [] for image_path, image, label in test_set: result model.infer(image)[0] predictions sv.Detections.from_inference(result) image_paths.append(image_path) predictions_list.append(predictions) targets_list.append(label)Ultralytics 版本用sv.Detections.from_ultralytics转换import supervision as sv test_set sv.DetectionDataset.from_yolo( images_directory_pathf{dataset.location}/test/images, annotations_directory_pathf{dataset.location}/test/labels, data_yaml_pathf{dataset.location}/data.yaml, ) image_paths [] predictions_list [] targets_list [] for image_path, image, label in test_set: result model(image)[0] predictions sv.Detections.from_ultralytics(result) image_paths.append(image_path) predictions_list.append(predictions) targets_list.append(label)注意 RF-DETR 传入的图像做了image[:, :, ::-1]处理BGR 转 RGB这是 RF-DETR 接口的约定而 Inference/Ultralytics 直接消费 BGR 原图。四、重映射类别让模型输出与数据集对齐使用无关数据集时模型输出的类别 ID 与名称往往和数据集不一致。例如模型按 COCO 80 类训练输出dogCOCO 中dog的 ID 为 16而数据集只有一个类CorgiID 为 0。先定义一个通用的重映射函数import numpy as np def remap_classes( detections: sv.Detections, class_ids_from_to: dict[int, int], class_names_from_to: dict[str, str], ) - None: new_class_ids [ class_ids_from_to.get(class_id, class_id) for class_id in detections.class_id ] detections.class_id np.array(new_class_ids) new_class_names [ class_names_from_to.get(name, name) for name in detections[class_name] ] detections[class_name] np.array(new_class_names)然后把重映射和剔除数据集中不存在的类别两步嵌入评测循环。数据集的类别名与 ID 可以从data.yaml查看或打印dataset.classes。RF-DETR 版本RF-DETR 自带 COCO 类别配置对应下方映射。一个值得注意的细节是——指南建议按重映射后的 class_id 过滤而不是按模型生成的 class_name 过滤这样才能兼容那些 COCO 稀疏名称查询行为不一致的 RF-DETR 版本import numpy as np import supervision as sv test_set sv.DetectionDataset.from_yolo( images_directory_pathf{dataset.location}/test/images, annotations_directory_pathf{dataset.location}/test/labels, data_yaml_pathf{dataset.location}/data.yaml, ) image_paths [] predictions_list [] targets_list [] for image_path, image, label in test_set: predictions model.predict(image[:, :, ::-1]) remap_classes( detectionspredictions, class_ids_from_to{18: 0}, class_names_from_to{dog: Corgi}, ) predictions predictions[ np.isin(predictions.class_id, np.arange(len(test_set.classes))) ] image_paths.append(image_path) predictions_list.append(predictions) targets_list.append(label)Inference / Ultralytics 版本按class_name过滤即可COCO 预训练模型的dog对应 ID 16import supervision as sv test_set sv.DetectionDataset.from_yolo( images_directory_pathf{dataset.location}/test/images, annotations_directory_pathf{dataset.location}/test/labels, data_yaml_pathf{dataset.location}/data.yaml, ) image_paths [] predictions_list [] targets_list [] for image_path, image, label in test_set: result model.infer(image)[0] # Ultralytics 版为 model(image)[0] predictions sv.Detections.from_inference(result) # Ultralytics 版为 sv.Detections.from_ultralytics(result) remap_classes( detectionspredictions, class_ids_from_to{16: 0}, class_names_from_to{dog: Corgi}, ) predictions predictions[ np.isin(predictions[class_name], test_set.classes) ] image_paths.append(image_path) predictions_list.append(predictions) targets_list.append(label)每个模型训练的类别映射都不同重映射表需要根据所用模型的具体类别配置来编写这一点务必核对模型文档。五、可视化预测直观检查模型的失败点数值指标之前先用图像直观地对比地真targets与预测predictions。用两种颜色的sv.PolygonAnnotator分别标注后拼成 3x3 网格展示import supervision as sv N 9 GRID_SIZE (3, 3) target_annotator sv.PolygonAnnotator(colorsv.Color.from_hex(#8315f9), thickness8) prediction_annotator sv.PolygonAnnotator( colorsv.Color.from_hex(#00cfc6), thickness6 ) annotated_images [] for image_path, predictions, targets in zip( image_paths[:N], predictions_list[:N], targets_list[:N] ): annotated_image cv2.imread(image_path) annotated_image target_annotator.annotate( sceneannotated_image, detectionstargets ) annotated_image prediction_annotator.annotate( sceneannotated_image, detectionspredictions ) annotated_images.append(annotated_image) sv.plot_images_grid(imagesannotated_images, grid_sizeGRID_SIZE)这里紫色#8315f9是地真标注青色#00cfc6是模型预测。对于目标检测模型用sv.BoxAnnotator对于 OBB 模型用sv.OrientedBoxAnnotator更多标注器选项可参考 annotator 文档。六、可视化基准测试ConfusionMatrix.benchmark 逐图落盘如果不想手动拼标注网格可以直接用sv.ConfusionMatrix.benchmark(...)。它的实现见 ConfusionMatrix.benchmark签名为confusion_matrix sv.ConfusionMatrix.benchmark( datasettest_set, callbackcallback, conf_threshold0.3, # 置信度阈值低于该值的预测被丢弃 iou_threshold0.5, # 低于该 IoU 的匹配被判为 FP metric_targetMetricTarget.BOXES, save_directory_path./results, # 可选逐图可视化落盘目录 )其中callback是一个输入图像、返回Detections的函数例如 RF-DETR 场景下可写成lambda image: model.predict(image[:, :, ::-1])源码 docstring 中的示例正是这样写的。关键参数说明均来自源码 docstring 与实现datasetDetectionDataset实例迭代时自动产出图像与地真标注conf_threshold预测置信度阈值默认0.3低于该值的预测不参与 TP/FP/FN 判定iou_threshold预测与地真框或 OBB的 IoU 判定阈值默认0.5低于该值的匹配被判为假阳性metric_target支持BOXES默认与ORIENTED_BOUNDING_BOXES不支持MASKSsave_directory_path指定后为每张图写出一张 2x2 结果网格Ground Truth/True Positives/False Positives/False Negatives四个面板到该目录直接复用原始图像文件名、不建子目录文件已存在时会发出UserWarning并覆盖。目录不存在时会自动mkdir(parentsTrue, exist_okTrue)。落盘由内部的_save_detection_validation_visualization完成最终函数通过cls.from_detections(...)汇总所有图返回可plot()的ConfusionMatrix对象一次调用同时得到逐图诊断图与聚合混淆矩阵。混淆矩阵的判定逻辑值得展开在 evaluate_detection_batch 中每张图的预测先按conf_threshold过滤然后计算预测×地真的 IoU 矩阵取所有IoU iou_threshold的候选匹配按类别先匹配优先、再按 IoU 降序贪心地一对一分配已匹配的对计入矩阵[gt_class, det_class]对角线即 TP非对角线是类别错误未匹配的地真计入最后一列FN未匹配的预测计入最后一行FP。矩阵形状为(num_classes 1, num_classes 1)。得到对象后可用confusion_matrix.plot()渲染热力图支持save_path、normalize、fig_size等参数矩阵本体则存在confusion_matrix.matrix属性中。七、Benchmarking Metrics 之一mAP7.1 计算 mAPmAPMean Average Precision是目标检测最常用的指标衡量模型在所有类别与 IoU 阈值下的平均精度。supervision的实现位于 MeanAveragePrecision构造参数包括metric_target使用BOXES、MASKS还是ORIENTED_BOUNDING_BOXES计算 IoU默认BOXES。注意选择MASKS时predictions 和 targets 必须都携带mask否则compute()会抛出ValueError见 _detections_contentclass_agnostic是否忽略类别、把所有对象当作单类计算class_mapping类别 ID 重映射字典——这可以替代上文手动remap_classes的做法直接在指标侧完成映射image_indices参与计算图像的子集索引。按指南示例分割模型评测掩码计算from supervision.metrics import MeanAveragePrecision, MetricTarget map_metric MeanAveragePrecision(metric_targetMetricTarget.MASKS) map_result map_metric.update(predictions_list, targets_list).compute()update负责累积各图的Detections可多次调用、内部按列表extend并在 compute 前校验预测数与地真数一致compute返回MeanAveragePrecisionResult。7.2 理解 mAP 结果与 mAP 50:95 的含义打印结果一目了然print(map_result)MeanAveragePrecisionResult: Metric target: MetricTarget.MASKS Class agnostic: False mAP 50:95: 0.2409 mAP 50: 0.3591 mAP 75: 0.2915 mAP scores: [0.35909 0.3468 0.34556 ...] IoU thresh: [0.5 0.55 0.6 ...] AP per class: 0: [0.35909 0.3468 0.34556 ...] ... Small objects: ... Medium objects: ... Large objects: ...其中最常用的是mAP 50:95它在 IoU 阈值0.5到0.95步长0.05共 10 档上取平均精度再对类别求平均而mAP 50、mAP 75只考虑单一阈值0.5/0.75。这一点可以从源码严格印证——COCOEvaluatorParameters 中# IoU thresholds [0.5, 0.55, 0.6, 0.65, ..., 0.95] self.iou_thrs np.linspace(0.5, 0.95, int(np.round((0.95 - 0.5) / 0.05)) 1, endpointTrue) self.rec_thrs np.linspace(0.0, 1.00, 101, endpointTrue) # 101 档召回阈值 self.max_dets [1, 10, 100] # 每图最大检测数MeanAveragePrecisionResult直接暴露map50_95、map50、map75属性见 结果类定义无检测或无地真时返回-1哨兵值。结果同样可以绘图map_result.plot()plot()基于 matplotlib 绘制包含mAP50:95、mAP50、mAP75以及 small/medium/large 分档的柱状图实现见 MeanAveragePrecisionResult.plot此外还有to_pandas()方法可将指标导出为 DataFrame方便多模型对比时落表。7.3 面积分档small / medium / largemAP 还会按检测对象的面积拆分结果。源码中常量定义明确mean_average_precision.pySMALL_OBJECT_AREA 32**2 # 1024 像素 MEDIUM_OBJECT_AREA 96**2 # 1024 ~ 9216 像素即 small 为面积小于32²像素、medium 介于32²与96²之间、large 大于96²像素。这与 COCO 官方评测口径一致便于定位模型在远景小目标上的短板。7.4 底层原理内建的 COCO 风格评测器从源码结构看MeanAveragePrecision并非简单循环求值compute()会把累积的 predictions/targets 转成 COCO 风格的字典images/annotations/categories标注含bbox、area、iscrowd、ignore等字段然后交给内建的 COCOEvaluator 完成完整评测对每张图、每个类别先按分数降序排列预测并截断到max_dets[-1]100个按metric_target分派 IoU 计算BOXES走box_iou_batch_with_jaccard含 crowd Jaccard 约定、MASKS走批量掩码 IoU、OBB 走oriented_box_iou_batch对 10 档 IoU 阈值逐一做贪心匹配同一地真至多匹配一次crowd 除外记录dtMatches/gtMatches/dtIgnore最后_accumulate()在阈值 × 召回 × 类别 × 面积档 × max_dets五维张量上按置信度降序累积 TP/FP做单调精度包络if pr[i] pr[i - 1]: pr[i - 1] pr[i]后在 101 档召回阈值处采样得到各档 Average Precision。这套流程与 pycocotools 的评测语义对齐_pycocotools_summarize甚至按 pycocotools 的 12 项统计口径打印摘要因此用supervision跑出的 mAP 可以与传统 COCO 评测直接互相对照。八、Benchmarking Metrics 之二F1 ScoreF1 是精确率多少预测是正确的与召回率多少真实实例被检出的调和平均F1 2 * precision * recall / (precision recall)尤其适合关注假阳性与假阴性平衡的场景。supervision的 F1Score 构造参数metric_target同上支持BOXES默认/MASKS/ORIENTED_BOUNDING_BOXESaveraging_method跨类别聚合方式默认AveragingMethod.WEIGHTED。AveragingMethod 定义了三种MACRO各类别等权平均不考虑类别不平衡、MICRO全局统计 TP/FP/FN样本多的类权重更大、WEIGHTED按各类真值实例数加权兼顾类别不平衡。计算方式与 mAP 一致的两段式 APIfrom supervision.metrics import F1Score, MetricTarget f1_metric F1Score(metric_targetMetricTarget.MASKS) f1_result f1_metric.update(predictions_list, targets_list).compute()打印结果print(f1_result)F1ScoreResult: Metric target: MetricTarget.MASKS Averaging method: AveragingMethod.WEIGHTED F1 50: 0.5341 F1 75: 0.4636 F1 thresh: [0.53406 0.5278 0.52153 ...] IoU thresh: [0.5 0.55 0.6 ...] F1 per class: 0: [0.53406 0.5278 0.52153 ...] ... Small objects: ... Medium objects: ... Large objects: ...与 mAP 类似F1 也支持f1_result.plot()出图、按 small/medium/large 面积分档拆分compute()内部会对ANY、SMALL、MEDIUM、LARGE四个口径各算一次见 F1Score.compute。面积分档口径与 mAP 相同 32²、32² ~ 96²、 96²像素。从源码看F1 的 IoU 阈值序列取np.linspace(0.5, 0.95, 10)即同样是 10 档 0.05 步长且当某张图只有预测没有地真时如背景图所有预测直接计为假阳性——这一边界行为在实现中有显式处理。此外supervision.metrics 还导出了Precision、Recall、MeanAverageRecall三个同类指标共享同一套Metric.update(...) - compute()接口与MetricTarget体系在需要更细粒度对比时可自行组合。九、常见问题FAQQ如何用 supervision 基准测试一个模型使用supervision.metrics.MeanAveragePrecision用update(predictions_list, targets_list)累积各图的预测与地真Detections再调用compute()得到结果。若要做混淆矩阵则用sv.ConfusionMatrix.from_detections(predictionspredictions, targetstargets, classesclasses)构造后调用plot()。QMeanAveragePrecision 使用哪些 IoU 阈值在0.50到0.95之间、步长0.05上计算 mAP即 mAP50:95并单独给出 mAP50 与 mAP75——源码中iou_thrs np.linspace(0.5, 0.95, 10)印证了这一点。Q能评测分割模型吗可以。将模型输出转为Detections传入MeanAveragePrecision.update(...)即可若metric_target为BOXESmAP 路径直接使用detections.xyxy构造 COCO 风格边框选MASKS则要求预测与地真都带掩码。QConfusionMatrix 是什么、怎么用sv.ConfusionMatrix按类别可视化 TP / FP / FNsv.ConfusionMatrix.from_detections(predictions..., targets..., classes..., conf_threshold0.3, iou_threshold0.5)注意conf_threshold源码默认值为0.3构造confusion_matrix.plot()渲染热力图。若想把逐图验证可视化写盘给sv.ConfusionMatrix.benchmark(...)传save_directory_path./results它会在该目录中按原始图像文件名写出包含Ground Truth、True Positives、False Positives、False Negatives四个面板的 2x2 结果网格。十、小结本文围绕supervision的模型基准测试流程展开要点回顾数据集选择是结果可信度的第一道关口优先使用未参与训练的无关数据集或test集警惕数据污染与类别不匹配评测循环以 DetectionDataset.from_yolo 为核心(image_path, image, label)三元组让你可以无差别地接入 RF-DETR、Inference、Ultralytics 等不同框架只需在循环内把模型输出转成sv.Detections类别重映射通过class_ids_from_to/class_names_from_to两张映射表完成过滤时按class_idRF-DETR或class_nameInference/Ultralytics保留数据集内的类别ConfusionMatrix.benchmark一次调用同时给出聚合混淆矩阵与逐图 TP/FP/FN 诊断网格save_directory_path直接落盘、复用原文件名mAP 与 F1共享update() - compute()的两段式 API支持BOXES/MASKS/ORIENTED_BOUNDING_BOXES三种 IoU 口径、10 档 0.05 步长 IoU 阈值、small/medium/large 面积分档其底层是内建的 COCO 风格评测器结果可与 pycocotools 口径直接对照更多指标Precision、Recall、MeanAverageRecall与指标参数说明可进一步参考仓库中 docs/metrics 目录下的文档。【免费下载链接】supervisionWe write your reusable computer vision tools. 项目地址: https://gitcode.com/GitHub_Trending/su/supervision创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门