ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

FiftyOne 语义分割评估(evaluate_segmentations)完整实战指南

FiftyOne 语义分割评估(evaluate_segmentations)完整实战指南 FiftyOne 语义分割评估evaluate_segmentations完整实战指南【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone本篇技术指南聚焦 FiftyOne 项目中评估语义分割模型的核心方法evaluate_segmentations()涵盖像素级pixelwise与边界带boundary-only两种评估策略、eval_key带来的逐样本指标字段、SegmentationResults的聚合报告能力以及 mask targets 的配置与最佳实践。读完本文你将掌握如何对数据集中的Segmentation字段执行端到端的语义分割评估并在 FiftyOne App 中交互式诊断模型的强项与短板。本文基于 docs/source/user_guide/evaluation/segmentations.rst 整理并结合 fiftyone/utils/eval/segmentation.py 源码与 tests/unittests/evaluation_tests.py 测试用例进行深化佐证。一、概述为什么需要分割评估语义分割模型的输出是一张与输入图像同尺寸的逐像素类别掩码mask。与检测任务评估边界框的 IoU、分类任务评估标签的正确率不同分割评估需要在像素粒度上衡量预测掩码与真实掩码的一致程度。FiftyOne 提供的evaluate_segmentations()方法正是为此设计它评估存储在数据集某个Segmentation字段中的语义分割模型预测并以真实掩码ground truth为基准计算各类指标。从源码看该方法的完整签名定义在 fiftyone/core/collections.py其核心实现在 fiftyone/utils/eval/segmentation.py底层复用 sklearn 的confusion_matrix与classification_report完成统计。调用它之后会返回一个SegmentationResults实例提供多种生成聚合评估报告的方法。默认情况下评估会以像素级pixel level对完整掩码进行逐像素多分类评估同时你也可以通过参数切换到仅评估边界像素boundary pixels等其他策略。该功能自 FiftyOne OSS 0.7.3 起可用Enterprise 版本自 1.0 起支持。二、快速上手一个最小可用示例下面的代码演示了最基础的用法对数据集中已有的预测字段与真实字段执行像素级分割评估。import fiftyone as fo import fiftyone.zoo as foz # 加载数据集 dataset foz.load_zoo_dataset(quickstart, max_samples10) # 对predictions字段执行评估真实掩码在ground_truth字段 results dataset.evaluate_segmentations( predictions, gt_fieldground_truth, eval_keyeval_simple, ) # 打印分类报告 results.print_report() # 在 App 中可视化 session fo.launch_app(dataset)evaluate_segmentations()的核心参数如下完整签名见 fiftyone/core/collections.py参数默认值说明pred_field必填存放预测Segmentation实例的字段名gt_fieldground_truth存放真实Segmentation实例的字段名eval_keyNone评估键用于引用本次评估提供后会在每个样本上写入指标字段mask_targetsNone字典将像素值2D 掩码或 RGB 十六进制字符串3D 掩码映射为语义标签不提供时使用观测到的像素值作为标签methodNone评估方法字符串取值见fo.evaluation_config.segmentation_backends.keys()默认由fo.evaluation_config.default_segmentation_backend决定progressNone是否渲染进度条True/FalseNone时使用fiftyone.config.show_progress_bars的默认值也可传入进度回调函数从源码 fiftyone/utils/eval/segmentation.py 可以看到调用时会依次完成校验集合与标签字段类型pred_field、gt_field必须同为Segmentation类型→ 解析配置 → 注册评估运行register_run→ 注册样本字段register_samples→ 逐样本评估evaluate_samples→ 计算自定义指标 → 保存运行结果。三、默认评估策略像素级简单评估Simple Evaluation3.1 策略原理当method未指定或显式设置为simple时FiftyOne 采用SimpleEvaluation对应配置类SimpleEvaluationConfig源码见 fiftyone/utils/eval/segmentation.py执行评估将掩码中的每一个像素视为一次多分类预测逐像素统计真实类别与预测类别的对应关系最终聚合出整张掩码的混淆矩阵。该策略有两个重要行为需要牢记尺寸自动对齐如果预测掩码的尺寸与真实掩码不一致预测掩码会被缩放到与真实掩码一致源码位于 fiftyone/utils/eval/segmentation.py 中的_compute_pixel_confusion_matrix缩放通过eta.core.image.render_frame_mask完成。背景类约定掩码值0与#000000在计算 precision、recall 等指标时被当作背景类background class处理。3.2 参数详解bandwidth、compute_dice 与 averageSimpleEvaluationConfig在基类之上增加了三个关键配置项参数默认值说明bandwidthNone沿真实掩码轮廓contour向两侧扩展的带宽像素仅在该带状区域内计算准确率典型取值为 5 像素。不指定时评估整张掩码compute_diceFalse是否为每个样本额外计算 Dice 系数averagemicro向每个样本写入 precision/recall 时所使用的平均策略bandwidth的实现路径是当bandwidth非空时先通过eta.core.image.get_contour_band_mask(gt_mask, bandwidth)提取真实掩码的轮廓带状掩码再只对带状区域内的像素计算混淆矩阵见 fiftyone/utils/eval/segmentation.py。这一策略尤其适用于关注分割边界质量的场景——比如评估模型对物体边缘的拟合程度。3.3 eval_key逐样本指标字段当指定eval_key后每个样本的准确率、精确率、召回率会被记录在样本的顶层字段中Accuracy: sample.eval_key_accuracy Precision: sample.eval_key_precision Recall: sample.eval_key_recall这些字段在评估开始时由register_samples动态创建类型为FloatField见 fiftyone/utils/eval/segmentation.py随后在逐样本遍历中被填充。你可以直接利用这些字段通过dataset.bounds(eval_key_accuracy)查看样本级准确率的取值范围通过排序、过滤等操作快速定位表现最差/最好的样本在 FiftyOne App 中交互式探索模型在不同样本上的强弱。帧级扩展当被评估的字段是帧级frame-level字段时除了样本级字段每一帧还会被记录下列字段见 fiftyone/utils/eval/segmentation.pyAccuracy: frame.eval_key_accuracy Precision: frame.eval_key_precision Recall: frame.eval_key_recall若开启compute_diceTrue还会额外写入eval_key_dice字段样本级与帧级均会写入。3.4 指标计算细节样本级指标基于该样本内各帧像素混淆矩阵累加后计算。值得注意的源码细节fiftyone/utils/eval/segmentation.py若某样本缺少真实掩码或预测掩码字段为None或has_mask为 False该样本会被跳过并发出警告不参与指标统计混淆矩阵的行代表真实类别ground truth列代表预测类别predictions每个匹配项都会以(gt_label, pred_label, pixel_count, gt_id, pred_id)的形式被记录支撑后续逐类别分析SegmentationResults.dice_score()基于混淆矩阵计算整体 Dice 分数2 * TP / (2 * TP FP FN)见 fiftyone/utils/eval/segmentation.py。四、完整示例用 DeepLabv3 双模型对比演示评估流程官方文档给出了一个非常完整的实战示例加载 COCO-2017 数据集用两个不同骨干网络的 DeepLabv3 模型ResNet50 与 ResNet101生成预测掩码然后以 ResNet101 的预测作为伪 ground truth评估 ResNet50 的预测质量。这个思路特别适合模型蒸馏对比或不同骨干网络输出一致性的分析场景。import fiftyone as fo import fiftyone.zoo as foz # 加载 COCO-2017 中的少量样本 dataset foz.load_zoo_dataset( quickstart, dataset_namesegmentation-eval-demo, max_samples10, shuffleTrue, ) # 两个模型均基于 VOC 类别训练 CLASSES ( background,aeroplane,bicycle,bird,boat,bottle,bus,car,cat,chair,cow, diningtable,dog,horse,motorbike,person,pottedplant,sheep,sofa,train, tvmonitor ) dataset.default_mask_targets { idx: label for idx, label in enumerate(CLASSES.split(,)) } # 添加 DeepLabv3-ResNet101 预测 model foz.load_zoo_model(deeplabv3-resnet101-coco-torch) dataset.apply_model(model, resnet101) # 添加 DeepLabv3-ResNet50 预测 model foz.load_zoo_model(deeplabv3-resnet50-coco-torch) dataset.apply_model(model, resnet50) print(dataset) # 评估 ResNet50 的掩码以 ResNet101 的掩码作为ground truth results dataset.evaluate_segmentations( resnet50, gt_fieldresnet101, eval_keyeval_simple, ) # 感知样本间的相似度差异 print(Accuracy range: (%f, %f) % dataset.bounds(eval_simple_accuracy)) print(Precision range: (%f, %f) % dataset.bounds(eval_simple_precision)) print(Recall range: (%f, %f) % dataset.bounds(eval_simple_recall)) # 打印分类报告 results.print_report() # 在 App 中可视化结果 session fo.launch_app(dataset)该示例中有几个值得拆解的关键点default_mask_targets的妙用通过设置数据集的default_mask_targets掩码中的每个像素值都被映射为语义标签背景、飞机、自行车……。这样在 App 中可以直接查看语义标签并且后续每次调用evaluate_segmentations()都无需再手动指定mask_targets。更正式的做法是使用Segmentation字段的mask_targets属性将标签直接存储在字段上参见下文存储掩码标签一节。dataset.bounds()快速体检对eval_simple_accuracy等字段取bounds可以瞬间了解所有样本的指标分布区间判断模型是否存在明显的样本级波动。results.print_report()输出聚合报告报告基于 sklearn 的classification_report实现见 fiftyone/utils/eval/base.py逐类别输出 precision、recall、F1 与 support按像素加权是了解模型在哪些类别上表现好、哪些类别上表现差的直接入口。五、SegmentationResults聚合报告与可视化evaluate_segmentations()返回的SegmentationResults继承自BaseClassificationResults见 fiftyone/utils/eval/base.py因此它天然具备一套完整的分类指标报告能力。常用方法如下方法说明print_report(classesNone, digits2)打印逐类别的 precision/recall/F1/support 分类报告源码metrics(classesNone, averagemicro, beta1.0)计算 accuracy、precision、recall、fscore、support 等指标字典源码print_metrics(...)打印metrics()的结果confusion_matrix(classesNone, include_otherFalse, include_missingFalse)生成像素级混淆矩阵行真实列预测源码plot_confusion_matrix(...)以混淆矩阵热力图形式可视化源码dice_score()计算整个评估的 Dice 分数源码report()/plot_pr_curve()/plot_roc_curve()生成评估报告与 PR/ROC 曲线由于底层统计单位是像素这些方法天然支持按像素加权的语义例如metrics()返回的support是参与统计的像素总数print_report()中各类的support是该类在真实掩码中的像素数。这使分割评估与图像分类评估在 API 层面保持了一致性降低了学习成本。此外SegmentationResults暴露了pixel_confusion_matrix属性像素值混淆矩阵方便你直接访问底层统计数据进行自定义分析。评估运行时产生的全部结果还可以通过dataset.load_evaluation_view(eval_key)和dataset.get_evaluation_info(eval_key)重新加载对应测试见 tests/unittests/evaluation_tests.py。六、mask targets让语义标签贯穿评估与可视化6.1 作用与三种提供方式掩码中存储的原始值是像素值如0、1、2……或 RGB 十六进制字符串它们本身不具备语义。mask_targets的作用就是将像素值映射为可读的语义标签如0 → background、1 → cat。FiftyOne 支持三种提供方式在调用evaluate_segmentations()时通过mask_targets参数传入仅影响本次评估results dataset.evaluate_segmentations( predictions, gt_fieldground_truth, eval_keyeval, mask_targets{0: background, 1: cat, 2: dog}, )在数据集上设置dataset.default_mask_targets示例见上文第四节的 DeepLabv3 代码数据集内所有Segmentation字段共享在Segmentation字段上直接存储mask_targets属性将标签固化在字段本身见下文。在evaluate_samples的实现中fiftyone/utils/eval/segmentation.pymask_targets若为 RGB 形式会被自动转换为整数像素值通过fof.hex_to_int然后按值排序得到values与classes两个对齐列表若未提供则扫描数据集中真实出现过的全部掩码像素值作为类别。传入的mask_targets可以只包含部分类别此时评估仅针对这些语义类进行。6.2 存储掩码标签storing mask targets官方文档特别建议为数据集中的Segmentation字段存储掩码标签这样既可以在 App 中直接查看语义标签又避免了每次运行evaluate_segmentations()时手动指定mask_targets的重复工作。存储方式是将mask_targets字典直接赋值给Segmentation字段的mask_targets属性# 假设 segmentations 是数据集中的一个 Segmentation 字段 dataset._get_label_field_attr(segmentations).mask_targets { 0: background, 1: cat, 2: dog, }也可在创建/加载标签时直接设置Segmentation(maskmask, mask_targets{...})。设置后App 会用这些标签渲染分割结果评估调用也会自动读取字段级标签无需重复传入mask_targets。七、底层实现速览从调用到报告的调用链为帮助读者深入理解这里梳理evaluate_segmentations()的完整内部调用链对应 fiftyone/utils/eval/segmentation.py校验validate_non_grouped_collection校验集合非分组validate_collection_label_fields校验pred_field与gt_field均为Segmentation类型L106-L109配置解析_parse_config根据method找到对应后端配置类methodNone时使用fo.evaluation_config.default_segmentation_backend默认simple可通过环境变量DEFAULT_FIFTYONE_SEGMENTATION_BACKEND或FIFTYONE_SEGMENTATION_BACKENDS覆盖见 fiftyone/core/config.py运行注册register_run记录运行元数据register_samples创建eval_key_accuracy/_precision/_recall以及可选的_dice样本字段帧级字段时同步创建帧字段L181-L215逐样本评估evaluate_samples遍历样本帧级字段时遍历帧对每张掩码调用_compute_pixel_confusion_matrix计算像素混淆矩阵累加得到样本级与全局混淆矩阵同时收集(gt_label, pred_label, pixel_count, gt_id, pred_id)匹配记录L378-L493结果封装构造SegmentationResults其内部将混淆矩阵解析为带权重的ytrue/ypred序列从而复用BaseClassificationResults的全部报告与绘图方法L496-L551自定义指标若通过custom_metrics传入额外指标则在评估完成后计算并合并进metrics()的返回结果。这套链路与 tests/unittests/evaluation_tests.py 中test_evaluate_segmentations_simple的行为一一对应空视图评估返回空混淆矩阵、mask_targets控制类别集合、metrics()[support]等于参与统计的像素数。此外 tests/unittests/evaluation_tests.py 的test_evaluate_segmentations_rgb专门验证了 3D RGB 掩码的评估路径test_evaluate_segmentations_no_eval_keyL3215则验证了不传eval_key时只返回结果、不写样本字段的行为。八、最佳实践与注意事项结合官方文档与源码实现总结以下实战建议优先存储掩码标签在Segmentation字段上固化mask_targets让 App 可视化与评估流程共享同一套语义标签避免重复劳动。善用eval_key的逐样本字段eval_key_accuracy等字段让你能用视图View直接过滤出最差的样本——例如dataset.sort_by(eval_accuracy)后定位模型失效场景再用 App 的 Model Evaluation 面板 做交互式分析。用bandwidth关注边界质量分割模型在类别边界处最容易出错。设置bandwidth5可将评估聚焦到真实掩码轮廓附近 5 像素的带状区域量化模型的边缘拟合能力。缺掩码样本会被跳过并告警真实或预测掩码缺失None或无has_mask的样本不参与统计请留意日志中的 warning确保评估集合符合预期。背景类约定像素值0/#000000被视作背景类参与 precision/recall 计算。若你的语义类别中存在非背景但值为 0的特殊情况请确认标签映射是否符合预期。显式指定methodsimple虽然simple是默认分割评估后端但显式指定可以让代码自文档化并避免未来默认后端变更带来的行为漂移。结合 Model Evaluation 面板在 App 中通过 Model Evaluation 面板对评估结果进行交互式下钻是官方推荐的、最快捷的分析方式。九、小结evaluate_segmentations()为语义分割模型的像素级质量评估提供了开箱即用的完整方案默认的simple策略将每个像素视为一次多分类预测自动处理掩码尺寸对齐与背景类约定eval_key把 accuracy/precision/recall可选 Dice写入每个样本与帧让评估结果可以直接用于视图过滤和 App 交互式探索SegmentationResults则继承了完整的分类报告、混淆矩阵与 PR/ROC 可视化能力。结合mask_targets的标签管理与bandwidth的边界带策略你可以针对不同的业务目标构建定制化的分割评估流水线。【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表