1. 为什么单看Dice在真实项目中会翻车
1.1 一个让我印象深刻的失败案例
先讲个我自己项目里真实发生过的事。前几年做一个肝脏肿瘤分割的评估,A模型的Dice是0.87,B模型是0.85,看起来A模型赢了。但把两个模型的结果铺到CT序列上逐层看,我发现A模型在肿瘤边缘有一层食指厚的"糖霜"——把周围正常的肝组织也划拉进来了。B模型虽然Dice略低,但边界干净利落,外科大夫看了说"这个能直接用"。
问题出在哪?Dice对内部的大的重叠区域很敏感,但对边界上那薄薄一层错分,惩罚小得可怜。肿瘤表面如果有个区域和真值偏差了3毫米,体素数占比可能不到5%,Dice根本反映不出来,但在临床手术规划里,这3毫米可能就决定了能不能切干净,要不要多切一刀正常组织。
这个案例让我彻底改变了对待评价指标的态度:任何单一指标都不足以支撑一个医学图像分割项目的质量判断,必须理解每个指标在数学上到底在衡量什么,它在放大什么、忽略什么。这也是我写这篇文章的初衷——从一个踩过坑的人的角度,把从Dice到MSD这些指标掰开揉碎讲清楚。
1.2 医学图像分割评价的完整维度拆解
医学图像分割评价,表面上是"算个分数",本质上是在回答三个问题:预测的区域和真实区域在位置和大小上有多吻合?边界形状有多接近?在临床应用最关心的局部有没有致命偏差?
这三件事,没有一个指标能同时回答。
重叠类指标(Dice、IoU、VOE、RVD)回答的是第一个问题,它们衡量体素集合的相似程度。距离类指标(ASD、HD、MSD)回答的是第二个问题,它们衡量表面之间的距离。还有一些临床导向的指标,比如过分割率、欠分割率、最大直径相对误差,回答的是第三个问题。
所以,构建评价体系的第一性原理是:根据你的分割目标,找到多个互补的指标,每个指标负责"盯住"一种可能出错的模式。只报一个Dice的论文和项目报告,在我这里一律视为评估不完整,不管结果多好看。
2. 重叠类指标家族:Dice、IoU、VOE、RVD的数学意义与实战选型
2.1 Dice和IoU:一对可以互相换算的"亲兄弟"
Dice的定义是两倍交集除以并集加交集:
[ Dice = \frac{2|X \cap Y|}{|X| + |Y|} ]
IoU(也叫Jaccard指数)定义是:
[ IoU = \frac{|X \cap Y|}{|X \cup Y|} ]
两者可以精确互换:
[ Dice = \frac{2 \times IoU}{1 + IoU} ]
这个换算关系意味着在实际项目中,这两个指标本质上是一个东西的不同尺度的表达。IoU的数值通常比Dice低一些——因为它在分母上把错分的体素算了两次。
打个比方:如果一个分割结果的IoU是0.75,乘以2再除以1.75,Dice就是0.857,看起来"好看"了不少。有些论文喜欢报Dice,也有用IoU的,两者没有优劣之分,但你在对比不同文献结果的时候,一定要先确认两边用的是同一个指标,或者自己换算过,否则对比完全失真。
从误差敏感度来看,IoU对小偏差更"苛刻"一些。在病变很小、比如只有几百个体素的时候,一个微小的偏移就会让IoU掉得很快,而Dice相对钝感。所以病灶越小,我越倾向于同时报IoU,避免Dice虚高给你一个"模型还行"的错觉。
2.2 VOE和RVD:器官移植场景里必须看的两个数
VOE(Volumetric Overlap Error)是1减去体素级的IoU,公式是:
[ VOE = 1 - IoU ]
它表示的是"预测体积和真实体积之间,有多大比例没有对上"。数值越小越好。RVD(Relative Volume Difference)则是相对体积差异:
[ RVD = \frac{|X| - |Y|}{|Y|} ]
这里X是预测,Y是真值,RVD可以大于0也可以小于0。正的RVD意味着预测的体积整体偏大(过分割倾向),负的则意味着偏小(欠分割倾向)。
这两个指标在器官分割、尤其是移植相关的场景里非常重要。举个例子,做肝移植手术的术前规划,肝脏体积的估算直接关系到移植后肝功能是否足够。如果一个模型Dice有0.9,但RVD是+15%,意味着它系统性多算了很多肝脏组织,放在这个场景里是致命的。反过来,有的模型Dice一般,但RVD非常接近0,说明它在总体积估计上很准,这是Dice给不了的信息。
所以碰到器官分割的评估任务,我的固定操作是:Dice + VOE + RVD三个放在一起看,RVD负责判断是否有系统性偏大或偏小的倾向,VOE负责量化总体失配率。
2.3 重叠指标的天然盲区:边界错分的"灰色地带"
重叠类指标有一个共同的数学盲区——对空间分布的均匀性不敏感。
假设预测结果和真值完全不重叠的面积被分散在100个细小区域,或者集中在一整片,只要总的重叠体素数相同,Dice和IoU算出来的值完全一样。但临床意义完全不同:一片连续的错分区域可能落在关键解剖结构上,而100个散点可能是噪声。
还有更隐蔽的问题:Dice对大结构偏移的惩罚不足。当一个结构本身很大,比如整个大脑皮层,即使边界整体向内收缩了5毫米,损失的体素占全体积的比例依然很小,Dice可能只掉零点零零几。但5毫米的边界收缩对神经外科导航来说已经不能被接受了。
重叠指标无法回答"边界对不对"的问题。要回答这个问题,必须上距离类指标。当年我天真地只靠Dice筛模型,后来被上级医生指着屏幕上的边界质疑问"这切面你们怎么评估的",才彻底意识到这个盲区有多致命。
3. 距离类指标实战:从边界平均偏差到MSD的稳定性设计
3.1 ASD:告诉你边界的"平均状态"
ASD(Average Surface Distance,平均表面距离)的通用定义是:对于预测表面上的每一个点,计算它到真实表面上最近点的距离,然后对所有点取平均。严格对称的版本还会反向从真实表面到预测表面再算一遍,两个方向的距离取平均:
[ ASD = \frac{1}{|S_X| + |S_Y|} \left( \sum_{x \in S_X} d(x, S_Y) + \sum_{y \in S_Y} d(y, S_X) \right) ]
其中(S_X)是预测表面点集,(S_Y)是真值表面点集,(d(p, S))表示点(p)到表面(S)的最短欧氏距离。
ASD的实用价值在于,它用毫米这个物理单位来量化边界平均贴合度。当你说"这个模型的平均表面距离是1.2毫米"的时候,临床医生能立刻在脑中形成一个空间概念——这比抽象的小数直观得多。
但ASD有一个弱点:它是个平均值,个别大偏差会被大多数正常区域"平均掉"。就像一堆人里有一两个身高特别高的,平均身高看着正常。如果分割结果在某一个局部飞出去一大块,ASD可能只增加零点几毫米,你完全察觉不到。
3.2 HD:抓住"最坏情况"的那把尺子
HD(Hausdorff Distance,豪斯多夫距离)定义的是两个表面点集之间最大的最短距离:
[ HD = \max \left( \max_{x \in S_X} d(x, S_Y), \max_{y \in S_Y} d(y, S_X) \right) ]
翻译成人话:在预测表面上找一个点,它离真值表面最远,这个最远距离是多少?然后在真值表面上也找一个点,离预测表面最远,又是多少?取两者中较大的那个。
这个指标回答的问题是:"你分割结果里最离谱的那个地方,离谱到什么程度?"对于三维重建、手术导航、放疗计划这类对局部极值敏感的任务,HD比Dice重要得多。一个Dice很漂亮的模型,如果在某层切片上把血管外壁的细小分支切错了一截,HD会立刻暴露出问题,Dice根本无动于衷。
不过HD也有让人头疼的地方:它对真值标注里的一个小噪声点极度敏感。如果标注人员手滑在远离病灶的地方点了一个孤立噪点,HD就会被这个噪点拉得很大,实际上模型没有大问题。所以HD更适合作为"最大值控制指标",配合其他指标一起用,而不是单独当筛选用。
3.3 MSD:为什么百分位数的引入是工程实践的一大步
MSD(Maximum Symmetric Surface Distance)通常指对称表面的最大距离,在很多文献中和HD是同一个概念。但在实际的评测工具和竞赛中,MSD往往被实现为一个更稳健的版本——计算对称表面距离的某个高百分位数,而不是单纯的最大值。
拿医学分割十项全能竞赛(MSD Challenge)来说,官方实现里用的就是HD的第95百分位数作为稳健版本。这个设计非常聪明:去掉最极端的5%噪声点,剩下的最大值就是"排除异常点干扰后的最大偏差"。这个指标更适合在真实标注质量参差不齐的数据集上评估模型——不会被一两个标注抖动毁掉整个得分。
我自己实践下来的经验:如果是比赛或公开榜评测,看官方的MSD定义;如果是自己项目内部模型筛选,裸HD和95%分位HD都算一下。两个数接近,说明分割边界很稳定;差距巨大,说明有零星噪点或者某个切片出现了区域性错误,值得回去排查数据质量或者模型预测的可视化结果。
3.4 距离类指标的物理单位直觉:从体素到毫米的换算
距离类指标牵扯到一个工程细节——体素间距。医学图像的体素大小通常不是各向同性的,比如CT常见的层间距是1到5毫米,而面内分辨率可能是0.5到1毫米。计算表面距离时,如果直接拿体素坐标算欧氏距离,不同方向上的距离会被严重扭曲。
标准做法是:先把体素坐标乘上对应的spacing(体素间距)转换成物理坐标,再计算距离。这一步看似简单,但漏做的人不在少数。我之前评审过一些复现实验,HD算出来大得离谱,查到最后就是没乘spacing——把5毫米层厚的数据当成1毫米各向同性处理了。
此外,表面点的采样密度对距离估计也有影响。实际工程中,一般先在二值分割掩膜上用行进立方体(Marching Cubes)算法提取三角网格表面,然后在网格表面均匀采样点。采样点太稀疏,距离估计会偏高;太密集,计算量暴增。经验值是每个表面大约1万到10万个点,足以在合理时间内得到稳定结果,具体数量可根据体素分辨率微调。
4. 实战案例复盘:一个肿瘤分割项目里各种指标打架怎么办
4.1 项目背景与模型设计
为了让上面的理论落地,我复盘一个肝脏肿瘤分割项目的评估全过程。项目需求来自临床:用术前CT自动分割肝脏和肿瘤,辅助外科制定切除方案。数据共120例,包含不同期相的增强CT,层厚1到3毫米不等,肿瘤大小跨度很大,最小的病灶仅有200多体素,最大的占了半个肝叶。
我训练了三个模型做对比:第一个是经典UNet,第二个是UNet加注意力模块(Attention UNet),第三个是带深监督的ResUNet。训练策略一致,数据增强一致,用五折交叉验证评估,确保对比公平。
4.2 五个指标一起看时的数据对比
模型评估结果如下表:
| 模型 | Dice | IoU | RVD (%) | ASD (mm) | HD95 (mm) |
|---|---|---|---|---|---|
| UNet | 0.832 | 0.712 | +6.8 | 1.75 | 12.3 |
| Attention UNet | 0.851 | 0.734 | +2.1 | 1.21 | 8.6 |
| ResUNet深度监督 | 0.849 | 0.731 | +3.4 | 1.34 | 9.2 |
单看Dice,Attention UNet和ResUNet打平,似乎加不加深度监督无所谓。但ASD差了不少,Attention UNet的1.21毫米对ResUNet的1.34毫米,说明它在边界贴合上明显更优。RVD上Attention UNet只有2.1%,ResUNet却有3.4%的系统性偏大——这解释了为什么它Dice不低但边界质量差一些。
真正拉开差距的是HD95:UNet的12.3毫米意味着某些切片上出现了严重的局部失控,这在肿瘤切除规划中是难以接受的。Attention UNet的8.6毫米虽然不算理想,但至少说明"最坏情况"是可控的。
这个案例的结论很清楚:如果只上报Dice,UNet看起来只差了0.02,可能会被误判为"基本可用"。但加上ASD和HD95,三类模型的质量差异立刻分明,只有Attention UNet进入了可以交付临床评审的候选线。
4.3 指标组合的"最低配置"建议
那么问题来了,实际项目里到底怎么选指标?我根据任务类型给一个最低配置建议:
- 病灶分割(小目标):Dice + HD95 + RVD。Dice反映整体重叠,HD95抓住"最差切片",RVD判断系统性偏差。
- 器官分割(大目标):Dice + ASD + VOE。大器官对均值距离更敏感,ASD对边界质量很敏锐,VOE补充总体匹配情况。
- 放疗/手术规划类任务:Dice + HD95 + ASD + 过分割/欠分割率。这类场景局部极值直接关乎安全,宁可多算几个指标也不嫌多。
- 多器官多标签全分割任务:每个标签分开计算Dice + HD95,另外加一个全脑或全腹部的平均表面距离,评估整体协调性。
在实际业务汇报里,我的习惯是做一个"指标仪表盘",把Dice、IoU、RVD、ASD、HD95全部列出来,每行一个测试模型或一个时间版本,一眼就能看出哪个模型在哪一类错误上更突出。这比只报一个平均数管用得多,也更经得起临床和合作方的追问。
5. 实操中绕不开的坑:工具实现差异、采样与标注稀疏性
5.1 不同库计算出来的HD可能天差地别
这是很多初接触评价指标的人最容易栽的坑。同样是"豪斯多夫距离",不同工具包的定义和实现细节差异很大:
| 工具/库 | 表面定义方式 | 距离计算方式 | 备注 |
|---|---|---|---|
| 自写Python脚本 | 体素边界作为表面 | 体素中心欧氏距离 | 结果偏高,不推荐 |
| Surface Distance库 | Marching Cubes三角网格 | 点到网格最近距离 | 医学影像评估常用 |
| SimpleITK的Hausdorff | 二值掩膜边界 | 体素级距离变换 | 速度快,精度一般 |
| MONAI的compute_hausdorff_distance | 距离变换 | 支持百分位数 | 需要确认是否乘spacing |
你可能会觉得"都是HD能差到哪去",我实测过:同样一组分割结果,用体素级距离变换算HD,和用三角网格表面距离算HD,在薄壁结构或细长血管上能差出2到3倍。因为体素级方法把整个体素当成一个点,对角线距离全被算进去了;三角网格方法才是真正贴近"表面到表面"的定义。
所以在项目报告里,一定要记录指标计算用的是哪个库、哪个版本、表面是怎么提取的。没有这个信息,别人没法复现你的评估,你自己隔了半年回头看也不敢确定数字是怎么来的。
5.2 距离变换还是三角网格?
从实用角度出发,我的建议分两个层级:
如果只是快速查看模型效果,自己写脚本时用scipy.ndimage.distance_transform_edt做体素级距离变换就够了。先对预测体素取反,算每个背景体素到前景的最近距离,然后只取预测表面边界的距离值,再求平均或百分位。优点是实现简单、速度快,缺点如上所述,精度有限。
如果是要发论文、打榜、做严谨的横向对比,必须用Marching Cubes提取网格后计算点到三角面的距离。推荐medpy.metric.binary.hd95,它内部封装了表面距离计算,很多医学影像评估任务都以它作为基准。用之前一定要确认它读入的数据是0/1二值掩膜,并且自己处理好spacing参数,否则会自动假设体素各向同性。
我自己的项目模板里,评估代码和训练代码分两个仓库管理。评估仓库固定依赖某个版本的medpy或者Surface Distance库,并且每个指标都写了一个单元测试,用已知几何体(比如球体和立方体)验证数值正确性,防止依赖升级后数值漂移。这看起来有点过度设计,但在一个项目上跑两三个月之后,你会发现这是最省心的一种方式。
5.3 稀疏标注和逐层标注对距离指标的影响
医学图像标注通常分为两种模式:逐层密集标注(每一层切片都画轮廓)和稀疏标注(每隔几层标注一次,中间层插值获得)。这两种模式对重叠指标的影响相对温和,但对距离指标的影响非常刺眼。
稀疏标注下,真值表面不是真实解剖边界,而是插值生成的近似表面。插值会让表面看起来更平滑,但实际位置上可能偏移了几个体素。这时你计算的HD和ASD,实际上是"模型和插值表面之间的差距",而不是"模型和真实边界之间的差距"。临床上后者的意义更大,但技术上只能算前者。
应对方法有两个:一是尽可能要求逐层密集标注,至少在评测集上做到;二是在解读距离指标时,把标注方式作为一个重要的协变量,标注间隔越大的数据集,对HD的解释要越保守。我见过一些公开数据集号称提供"金标准",实际是稀疏插值出来的,用HD的时候很容易被误导,这种坑一定要提前排查。
5.4 体素间距归一化、边界腐蚀和裁剪不会告诉你的事
最后还有一个很少在论文里写明的操作:在计算距离指标前,很多资深团队会先对二值掩膜做一次边界腐蚀,去掉最外层的孤立单体素噪声。这个操作能把标注抖动和预测噪声带来的HD虚高压下去,但也可能把真实的细长突起腐蚀掉,导致HD偏低。要不要腐蚀、腐蚀多少半径,必须提前固定下来并写进评估配置,不能每轮评估都改。
体素间距归一化也很关键。数据集里如果混着1毫米和3毫米层厚的图像,直接混合计算距离,3毫米层的表面距离天然会有系统偏大。建议先把所有图像和标签重采样到统一的各向同性分辨率(比如1×1×1毫米),再跑评估。重采样本身会引入轻微插值误差,但比起不同层厚之间的系统差异,这个误差是可以接受的。
6. 构建一套有说服力的评价体系:统计检验与结果呈现
6.1 配对检验:两个模型谁更好,不能靠平均分拍脑袋
评估指标的另一个常见误区是只看均值,不看方差。A模型平均Dice比B模型高0.01,好像更好,但如果看每个测试样本的配对差值,方差很大,那0.01的差距很可能是噪声。
正确的做法是做配对样本的显著性检验。比如同一组100个病例,分别用A和B模型推理,可以得到100个配对Dice差值。对这个差值序列做Wilcoxon符号秩检验或者配对t检验,如果p值足够小(比如小于0.05),才能说A模型显著优于B模型。否则,哪怕均值高,也只能说"两者在当前数据上没有显著差别"。
医学图像分割任务样本量一般不大,数据分布也不是严格正态,Wilcoxon符号秩检验更稳妥。它对异常值不敏感,而且只需要配对的差值方向信息,几乎成了我的默认选择。
6.2 置信区间和箱线图的呈现艺术
除了假设检验,展示指标的分布信息比只报一个均值更有价值。
我用箱线图展示Dice、HD95在测试集上的分布。箱体越窄,模型越稳定;箱体拉开一长串,说明有病例分割效果很差。对HD95这种极易被极值干扰的指标,箱线图上的离群点往往直接指向质量有问题的病例,值得逐个可视化检查。
如果数据量够,还可以画每个病例的得分散点图,用Dice做横轴、HD95做纵轴,落在右上角的病例都是"双高"的好结果,左下角的则是需要重点检查的失败案例。这种图在给临床合作方汇报时特别好用,比一堆小数直观得多。
6.3 把指标与临床结局挂钩:评估的终点是决策
评价指标本身不是目的,最终的落脚点是辅助决策。我在几个项目里尝试过把分割评估和下游临床任务串联起来:
- 放疗计划场景中,分割质量决定剂量分布误差,可以计算"基于分割的剂量误差"作为终极指标。
- 手术规划场景中,分割边界决定切缘距离,可以计算"预测切缘距离 vs 真实切缘距离"的偏差。
- 病灶负荷评估场景中,分割体积决定肿瘤分期,可以计算"分期改变率"。
这种做法的好处是,当有人质疑"Dice 0.85够不够用"时,你可以直接用下游任务的性能损失来回答。比如某个模型虽然Dice只有0.84,但肿瘤分期准确率95%,和Dice 0.90的模型差异不大,那它在这个临床任务上的价值就完全可以接受。指标永远是手段,决策质量和患者安全才是目的。
7. 从指标到判断:写在最后的一点体会
每次有人让我推荐一个"最好的分割评价指标",我的答案都是一样的:不存在这样的指标。Dice告诉你整体重叠程度,IoU对局部偏差更敏锐,RVD暴露系统性体积偏移,ASD描述平均边界状态,HD95震慑最坏情况。它们合在一起才能拼出分割质量的全貌。
我自己在评估流程上已经形成了一套固定的习惯,这里分享给大家参考:每个项目建一个评估清单,包含至少一个重叠类指标、一个平均距离类指标、一个最大距离类指标,外加一个和任务强相关的临床指标;所有指标用同一个固定版本的工具库计算,并在配置文件里记录spacing、采样密度、是否腐蚀等全部参数;每个模型的评估结果必须配两张可视化图,一张是边界叠加图,一张是距离热力图,光有数字不看图,评估就是盲人摸象。
医学图像分割的评价是一个既需要严谨数学语言,又需要大量工程直觉的活。希望这篇从Dice到MSD的实战拆解,能帮你少踩一些我当年踩过的坑,在你的项目里建立起一套真正可信、经得起推敲的评估体系。