做了几年工业视觉检测算法的落地我发现在模型之外最容易被忽视、也最容易翻车的一环其实是评价指标。很多人拿着论文里的数字直接对比自己的实验结果发现复现不出同样效果还有人模型明明训练得不错一上产线就被客户质疑“漏检率到底多少”根源往往不是模型本身而是指标选错了、算错了、或者根本不知道指标在说什么。这篇文章围绕工业异常检测里最核心的几类评价指标展开重点聊聊I-AUROC、像素级AUROC和PRO分数。我会把每个指标的定义、计算方式、适用场景、局限性以及我在实际项目里踩过的坑都讲清楚最后再给出一套我自己常用的指标组合策略。无论你是在做学术对比、工业落地还是刚入坑想搞清楚论文里的表格到底怎么回事这篇都能给你一个相对完整的参考。1. 内容整体设计与思路拆解1.1 为什么评价指标在工业异常检测里这么容易“骗人”工业异常检测和通用图像分类有个本质区别异常样本极其稀缺而且异常的种类几乎是无穷无尽的。你可能训练时只见过划痕和脏污上线后却来了压伤、凹陷、毛刺、色差、边缘破损。这种“开放集”特性决定了模型的目标不只是分类“好”和“坏”而是要能对“没见过的东西”产生响应。在这种背景下评价指标的作用就变得格外关键。它不光是衡量模型好坏的尺子更直接决定了你在调参、选模型、定阈值时的方向。如果指标选得不对你花了好几周优化的东西可能在真实场景里毫无意义。我见过最典型的情况某个模型在ImageNet风格的分类任务上表现一般但在异常检测的像素级指标上却出奇地高结果一上产线就被打回原形。原因很简单论文里报告的像素级AUROC在计算时用了带形态学膨胀的ground truth而产线里根本没有这种“宽容度”。这就是指标和现实脱节带来的典型后果。1.2 指标体系的整体架构从图像级到像素级再到区域级工业异常检测的评价体系按粒度可以分成三层。第一层是图像级指标回答的问题是“这张图有没有问题”。代表就是I-AUROCImage-level AUROC也是论文里最常出现的数字。第二层是像素级指标回答“具体哪个位置有问题”常见的是像素级AUROC、F1-max、Dice系数等。第三层是区域级指标不仅看像素重合法还要求检测结果在结构上覆盖真实的异常区域代表就是PRO分数Per-Region Overlap。为什么要区分这三层因为工业场景里不同角色关心的问题不一样。管理层关心图像级的漏检率质检员关心像素级的定位精度而设备维护工程师关心的是结构性的区域覆盖——比如一个缺陷是不是被完整识别出来而不是只擦到边。2. 核心细节解析与实操要点2.1 I-AUROC图像级指标的定义、计算与“欺骗性”先讲I-AUROC。它本质上就是二分类里的AUROC只是样本换成了整张图片。你把所有测试图片输入模型得到每张图的异常分数比如最大像素异常分数或平均异常分数然后计算正常图和异常图的分数分布重叠程度。值越接近1说明模型把正常图和异常图分得越开。计算公式不复杂本质上是通过遍历所有可能的阈值计算真正例率TPR和假正例率FPR然后对ROC曲线求面积。但它有一个特别容易误导人的特性AUROC只关心排序不关心绝对分数。举个例子。模型给出的分数是0.99和0.98只要所有正常图的分数都低于所有异常图AUROC就是1.0但这两个分数在实际阈值选择上几乎没法用。工业部署需要的是一个明确的分数阈值AUROC给不了你它只能告诉你“大体上能不能分开”。这也是为什么I-AUROC高不代表你能直接上线。更隐蔽的一个坑是类别不平衡。如果在测试集里正常图有1000张异常图只有20张AUROC依然能算但它的置信区间会非常大。有时候你换了随机种子I-AUROC从0.97掉到0.93不一定是模型退化了可能只是异常样本太少导致的统计波动。所以报告I-AUROC时最好一起给出样本量否则数字没有可比性。2.2 像素级AUROC更精细但更容易“虚高”的指标像素级AUROC的思路是把每个像素当成一个样本正常像素作为负类异常像素作为正类计算模型在每个像素上的异常分数与ground truth的ROC面积。这个指标在论文里几乎是标配因为它能体现模型对异常区域的定位能力。但实际操作里它有三个大坑。第一个坑是“像素数不平衡”会把指标拉高。正常像素数量往往是异常像素的几十倍甚至上百倍这种情况下即使模型在异常区域上的分数只是略高于正常区域AUROC也会非常高。你看到一个模型像素级AUROC是0.97感觉很强但实际可视化出来检测结果可能只是把异常区域染了一团模糊的浅色。第二个坑是ground truth需要形态学膨胀。MVTec AD官方提供的像素级ground truth是经过膨胀处理的目的是为了容忍边缘标注误差。很多刚入坑的人没注意到这点拿未经膨胀的标注去评测自己训练的模型结果和别人论文里的数字完全对不上。这不一定是你的模型差而是评测口径不同。第三个坑是逐像素计算忽略了空间结构。一个把异常区域完整覆盖的检测结果和一个只在异常区域零星命中几个像素的检测结果像素级AUROC可能差别不大但在工业场景里前者才是真正可用的。这直接引出了PRO分数的设计动机。2.3 PRO分数从“像素对不对”到“区域有没有被覆盖”PRO分数全称是Per-Region Overlap最早由Bergmann等人在MVTec AD的相关工作中系统使用用来评估模型对每个独立异常区域的覆盖程度。它的核心思想很直观把ground truth中每个连通域当成一个独立的区域对每个区域单独计算“被预测为异常的像素占该区域总像素的比例”然后对所有区域求平均。这样就不会被大面积异常区域带偏也不会因为背景像素太多而稀释掉关键信息。这里有一个非常关键的设计细节PRO分数在计算时会对预测结果做不同尺度的高斯模糊然后取一个覆盖多个阈值区间的最优曲线。具体来说它对预测的异常分数图做高斯滤波从sigma等于某个小值逐步增大然后再设定一系列分数阈值统计每个区域的重叠率。最后以平均重叠率作为PRO分数的值。这个做法让指标对边缘预测的不确定性更鲁棒不会因为异常区域边缘几个像素的误差就对分数产生剧烈影响。我经常用一句话向客户解释PRO分数I-AUROC是“整张图分不分得开”像素级AUROC是“每个像素猜不猜得准”PRO是“每个缺陷有没有被完整找出来”。三个指标回答的问题完全不一样不能互相替代。3. 实操过程与核心环节实现3.1 PRO分数的计算流程与代码设计这里我给出一个我自己用过的PRO分数计算流程你可以直接参考这个思路去实现。首先准备好三样东西模型输出的异常分数图大小和原图一致可以归一化到0到1、ground truth的二值掩码、以及一组预设的高斯核sigma值。接着按以下步骤走。第一步对ground truth做连通域分析。用OpenCV的connectedComponentsWithStats把标注里的每个异常区域分离出来得到每个区域的掩码。这里要特别注意过滤掉面积过小的连通域我一般会把小于25个像素的区域过滤掉否则统计结果会被噪声干扰。第二步对预测的异常分数图做多尺度高斯模糊。以sigma从0.5到16为例可以取等差数列或对数间隔我常用的是8到16个尺度。每个尺度得到一个平滑后的分数图。第三步对每个尺度和每个阈值计算每个连通域内的平均重叠率。阈值我习惯用0.1到0.7之间的均匀采样因为在较低阈值下普通的背景噪声就会开始产生大量假阳性这会导致分数过于乐观而在过高的阈值下连真正的异常区域都很难被完整覆盖分数又会太低。我之前试过阈值为0.8以上时就算是一个表现很好的模型PRO分数也会掉到0.5以下这对模型间区分度的帮助不大。第四步对所有连通域在不同尺度和不同阈值下的重叠率取平均得到最终的PRO分数。计算时可以用双线性插值把每个区域内的预测分数插值到固定尺寸也可以用区域掩码直接做矩阵运算。注意PRO分数在实现时最容易被忽略的一个环节是“区域级平均而不是像素级平均”。如果你直接把所有区域的像素合在一起算覆盖率本质上又回到了像素级指标。必须在每个连通域内单独计算然后对所有区域取平均这才叫Per-Region。3.2 三种指标的组合策略我实际项目里的选择标准在真实项目里我很少只依赖单一指标。我一般按项目阶段选择组合方式。如果是模型选型和学术对比阶段我会同时看I-AUROC和PRO。I-AUROC用来衡量整体可分性PRO用来衡量异常定位的结构性质量。因为PRO在计算时引入了多尺度模糊和区域级平均它对不同模型的排序往往比像素级AUROC更能区分出谁的区域预测更完整。如果两个模型的I-AUROC差不多但PRO分数差距明显我大概率会选择PRO分数更高的那个哪怕它的像素级AUROC略低一点。如果是产线部署阶段我会把重心转向F1-max和精确率-召回率曲线。原因很现实AUROC是阈值无关的指标但部署时你必须定一个阈值。F1-max是在所有可能的阈值里找到F1分数最高的那个点它直接告诉你在当前样本分布下最优的漏检和误杀平衡点在哪个位置。我会用验证集找到F1-max对应的阈值再用测试集验证这个阈值下的精确率和召回率最终形成可交付的报告。如果是客户需要验收报告只给三个数字缺陷召回率异常图被正确识别的比例、过杀率正常图被误报为异常的比例、以及平均像素IoU。这些指标客户能直接换算成产能损失和漏检成本比AUROC、PRO这些统计学术语直观得多。3.3 可视化指标背后必须有“肉眼可验证”的证据支撑我还想强调一件事无论你用哪个指标都必须配套输出可视化的检测结果图。指标只是压缩后的数字它可能骗人可视化不会。我每次评估模型时都会额外生成一张“困难样本集”的可视化图把ground truth和模型的预测热力图放在同一个坐标系下对比。这样即使指标看起来不错我也能快速发现模型是在“真正理解”异常区域还是在高频纹理区域上碰巧打出了高响应。具体做法也很简单从验证集里挑出I-AUROC分数最低的那20张异常图以及F1-max阈值下被误分类的10张正常图和10张异常图把它们的输入原图、真实掩码、预测热力图、叠加图排成4列的网格。这张图比任何指标数值都有说服力。4. 常见问题与排查技巧实录4.1 为什么我实现的PRO分数和论文里的对不上这个问题我见过太多次了。多数时候不是算法错了而是几个细节没对齐。第一MVTec AD的官方ground truth是经过膨胀处理的而你的模型预测可能是在原始标注下训练的两者存在天然的口径差异。第二论文里报告PRO分数时对预测热力图做了某种缩放或归一化预处理不一定是原始输出直接计算。第三阈值范围和高斯核参数的选择会影响最终数值。我自己的经验是如果复现结果和论文差距在2到3个点以内大概率是参数细节不一致如果差距超过5个点就要检查是不是区域划分的逻辑出了问题。比如你是不是把整张图当成一个区域而不是用连通域拆分这个错误会让PRO分数明显偏高而且会掩盖小目标区域的检测缺陷。4.2 I-AUROC和像素级AUROC的表现趋势不一致正常吗完全正常。一个模型可能在图像级AUROC上表现一般但在像素级AUROC上非常高反过来也一样。这取决于模型的设计目标。有些模型是设计出来做“全局判定”的最后一层是全局池化加分类器头它的图像级分数很稳定但像素级定位会糊成一片。有些模型则天然适合像素级任务比如基于U-Net或特征金字塔结构的方法它们的像素级热力图更锐利但图像级分数可能因为背景干扰而波动。所以当你发现两个指标趋势不一致时不要急着怀疑实现代码先确认你的模型结构对哪类任务更友好。如果两个指标都偏低那才是真的有问题。4.3 上线后模型指标好但实际产线效果差的排查思路这种情况通常是数据集和现实分布不一致导致的。测试集里的异常图是精心挑选的、光照一致的、角度固定的但产线上的缺陷可能出现在不同光照、不同角度、不同材料批次下。模型的I-AUROC再高也只是在你给定的测试分布下高换一个分布就失效了。我的排查顺序是这样的第一步从产线直接采集一批真实缺陷图数量不用多50到100张就够用标注工具粗略勾出异常区域第二步用这批图跑一遍模型计算I-AUROC和PRO对比实验室结果第三步如果掉点严重优先检查输入图像的预处理流程是否一致尤其是分辨率和归一化方式第四步检查是否有新类型的缺陷如果有把这些缺陷加入训练集做增量学习或少样本微调。这套排查流程我用过很多次大多数问题都在第二步和第三步就暴露了。4.4 指标速查表指标回答的问题计算粒度对异常占比敏感度工业部署适配度典型使用场景I-AUROC整张图是否异常图像级低低学术对比、模型初选像素级AUROC每个像素是否异常像素级高中定位能力粗评PRO分数每个异常区域是否被完整覆盖区域级低高区域覆盖质量评估F1-max阈值选择图像级/像素级高高部署阈值标定5. 结合我的项目经验聊聊指标选择背后更本质的事情做工业异常检测这几年我慢慢意识到一个道理指标从来不是越复杂越好而是要跟你要解决的问题对齐。很多刚入行的朋友喜欢在论文里堆一堆指标好像数字越多就越严谨其实恰恰相反指标越多越容易迷失。我自己的习惯是每个项目只锁定两个核心指标一个用于衡量“检测能力”一个用于衡量“部署可行性”。模型选型阶段看I-AUROC加PRO调参阶段看F1-max加像素IoU交付阶段看缺陷召回率和过杀率。这样每个阶段都有明确的方向不会因为一个指标好看就忽略了另一个维度。还有一个细节就是所有指标报告里我都会附上测试集的样本构成比如正常图数量、异常图数量、异常类型数量。没有样本量的指标都是不负责任的数字。最后再分享一个不太会被写进论文但实战里很有用的小技巧计算指标时无论是I-AUROC还是PRO都要确保测试集的异常图里同时包含“大面积缺陷”和“小面积缺陷”。如果测试集里全是明显的大面积异常所有指标都会虚高因为这类样本对任何模型来说都太简单了。主动加入一些小缺陷和低对比度缺陷指标会真实很多也更接近产线的实际情况。