指标先回答使用需求
这篇回顾整理分割评估的方法,归档月份仅用于主题排序。评估前需要先回答:更关心整体体积、细小结构、边界偏差,还是每个目标都不能遗漏?同一个平均分,可能对应完全不同的失败模式。
Metrics Reloaded 建议根据问题特点选择指标,并用互补指标弥补单一指标的局限。原论文 实际工作中,可先明确统计单位,再约定空值政策和边界定义,最后编写评估脚本。
Dice 很直观,但没有覆盖全部错误
对二值预测集合 P 与参考集合 G,Dice 定义为:
Dice(P, G) = 2 * |P intersection G| / (|P| + |G|)
交并比(Intersection over Union,IoU)则是交集大小除以并集大小。对同一组二值集合,且并集非空时,有:
IoU(P, G) = |P intersection G| / |P union G|
Dice = 2 * IoU / (1 + IoU)
换算关系适用于逐例、同一集合上的指标,不能把平均 IoU 直接代入来得到平均 Dice。
它衡量重叠程度,却不直接表达边缘相距多少毫米。目标越小,同样几个像素的偏移可能造成越大的分数变化;目标很大时,局部的重要缺口也可能被整体重叠掩盖。
二值化阈值应在验证集上确定并冻结。用测试集挑出最佳阈值后再汇报结果,相当于让评估数据参与了选择。若比较概率质量,还应另设相应协议,不能只靠一次二值化判断。
空掩膜必须有显式政策
当预测与参考都为空时,Dice 的分母与 IoU 的并集大小都为零,本文约定二者均返回 None,供上层单独统计;只有一方为空时,二者均为 0。下面展示遵循该政策的 Dice 实现,IoU 实现也应先检查并集是否为零。这是一个可说明的协议,并非唯一标准。
import numpy as np
def binary_dice(pred, reference):
p = np.asarray(pred, dtype=bool)
g = np.asarray(reference, dtype=bool)
if p.shape != g.shape:
raise ValueError("mask shapes must match")
denominator = int(p.sum()) + int(g.sum())
if denominator == 0:
return None
return 2 * int(np.logical_and(p, g).sum()) / denominator
输入应已经是同一网格上的二值掩膜,不能把任意概率数组直接转为布尔值。最终报告需要列出双空样本数、参考为空但产生误报的样本数,以及参与 Dice 汇总的数量。否则,忽略 None 后的均值会让背景样本的表现彻底消失。
可以把参考非空样本上的重叠表现,与参考为空样本上的误报情况并列报告。前者回答目标存在时分得怎样,后者回答没有目标时是否保持安静。把双空统一记为满分后再求均值,可能让大量背景样本遮住目标漏检,因此必须说明汇总口径。
边界距离要使用物理尺度
边界指标可补充重叠指标,例如平均表面距离、95% 豪斯多夫距离(HD95)或带容差的表面 Dice。应写明表面提取方法、距离计算方式、双向距离如何聚合,以及采用的实现版本。
三维数据需要传入正确的体素间距和轴顺序。相差一个体素不等于固定的一毫米,各向异性体数据尤其容易出错。表面 Dice 的容差应有任务或标注一致性依据,不能为了抬高结果随意放宽。
空掩膜没有可比较的边界。应明确返回未定义、无穷大或预先约定的惩罚,并报告数量;不要静默写成零距离,让完全漏检看起来像完美边界。
先逐例,再按正确层级聚合
若目标是评估新患者,应优先逐患者或逐体数据计算,再汇总分布。把全部切片的像素合并,会让切片多、目标大的样本支配结果。同一患者多次检查时,也应说明检查与患者两个层级的权重。
除均值外,还应查看中位数、分位数和最差样本。区间估计应尊重组内相关性,例如按患者进行重采样。失败样本可按漏检、误报、边界偏移和拓扑断裂分组,并同时保留原图,避免只挑对方案有利的案例。
若任务关注多个独立目标,还应检查目标级漏检。像素级重叠相近,可能分别对应「每个目标都有少量偏差」与「一个小目标完全消失」,两者的使用后果并不相同。
参考
- Metrics Reloaded: recommendations for image analysis validation:指标选择与应用的系统框架。
- Understanding metric-related pitfalls in image analysis validation:指标定义、数据结构与边界情况的常见陷阱。