ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

工业异常检测评价指标:从I-AUROC到PRO的选型指南

工业异常检测评价指标:从I-AUROC到PRO的选型指南 1. 工业异常检测评价指标一个被低估的“技术分水岭”做工业异常检测的人几乎每天都要跟I-AUROC、PRO这些词打交道。尤其是这几年基于MVTec AD、VisA这些公开数据集刷榜越来越卷指标上差个0.1%都要写进论文里强调半天。但我发现一个很普遍的问题不少人只是把I-AUROC当作“准确率”一样的东西在用对PRO到底解决了什么问题、为什么像素级指标不能只看P-AUROC、以及这些指标在真实产线落地时有哪些“失真”场景其实没有想太透。这篇内容想从评价指标本身出发结合我在工业视觉项目里实测过的经验把I-AUROC、PRO、P-AUROC这套体系掰开揉碎讲清楚。不管你是刚入门异常检测的研究生还是正准备把算法模型部署到产线检测设备上的工程师这篇文章都能帮你建立一套“指标如何指导模型选型与阈值决策”的完整认知。我会把公式、计算逻辑、踩坑记录、代码示例全部放出来尽量做到看完就能直接在自己的实验结果表里用起来。先说一句核心结论放在前面指标不是用来“证明模型好”的而是用来“解释模型在哪里好、在哪里不好”的。想清楚这一点你在异常检测里踩的坑会少一大半。2. 为什么I-AUROC和PRO能成为工业异常检测的“事实标准”2.1 从业务场景出发异常检测到底在检测什么工业异常检测这块和通用目标检测有个本质差异——你要检的“缺陷”往往没有固定形状、没有预设类别甚至样本量少到不足以训练一个分类器。比如注塑件表面的流纹、电池极片的划痕、纺织品的缺口这批东西在出厂前可能连标准图像都没有一个批次里的缺陷类型和位置都可能是全新的。所以这个任务通常被建模为“无监督/自监督学习”只用正常样本训练推理阶段检测出偏离正常分布的区域。评价一个模型好不好从根本上说就看两件事第一能不能把“有缺陷的图像”从“正常图像”里筛出来第二能不能把缺陷像素的位置大致定位出来方便后续机械臂或者人工复核。I-AUROC评估的是第一件事PRO评估的是第二件事。这两个指标刚好对应了工业场景里两个完全不同的诉求筛选效率和定位精度。很多新人在实验报告里只报I-AUROC觉得分数高就是模型好其实在真实项目里定位能力往往才是决定能否上线的关键指标。2.2 为什么不能拿“准确率”当核心指标凡是做过工业检测项目的人应该都体会过类别极度不均衡的痛苦。正常品率可能高达99%缺陷品率只有1%甚至更低。这种情况下你就算写一个“永远判正常”的傻瓜模型准确率也有99%看起来非常漂亮。说白了准确率这玩意儿在异常检测里基本没有参考价值。I-AUROC这类指标的设计初衷就是在不设阈值的情况下衡量模型把“异常样本”和“正常样本”区分开的能力。它不关心你阈值选在哪只看模型对正负样本打分排序的能力。这个特性让它天然适合在样本极度不均衡的工业场景里用。而PRO和P-AUROC则是更进一步把评价粒度下沉到像素级把正常像素和缺陷像素当作两组样本衡量模型能否在空间上精准区分它们。顺带提一句即使是I-AUROC也会受到数据集本身难度的影响。真实产线的缺陷形态比公开数据集复杂得多所以你在MVTec上看到的0.99到现场数据上可能只有0.9甚至更低这是非常正常的不能只盯着公开榜单的分数。2.3 I-AUROC、P-AUROC、PRO三者到底有什么区别很多人把这三个指标搞混其实它们的侧重点差异非常大。这里先用一张表说清楚后面再展开讲每个指标的原理。指标名称评估粒度核心问题对定位能力的要求I-AUROC图像级别这张图是正常还是异常不要求P-AUROC像素级别像素级预测能否区分正常/缺陷像素要求但容易被大缺陷区域带偏PRO连通域级别每个缺陷区域连通域是否都被完整检出要求且对每个区域一视同仁我先给个直观类比。I-AUROC像是体检报告上的“是否异常”总判定你只知道身体有问题但不知道哪儿有问题P-AUROC像是给出了一份粗略的器官示意图但画得糊一点也没事PRO则更像是要求医生把每一个病灶区域都圈出来不能因为某个病灶比较大就掩盖了旁边小病灶没被发现的失误。P-AUROC最大的问题在于它在统计像素时是把所有缺陷像素和所有正常像素混在一起算的。如果一个缺陷区域特别大占了缺陷总像素的80%那这个区域的定位表现就直接主导了P-AUROC的分数剩下的小缺陷即使完全没检出也可能因为分母够大而“被平均”掉。PRO指标就是为了解决这个问题提出的。它把每个连通域即每个独立的缺陷区域当作一个单元逐个区域计算“该检出的像素里有多大比例被正确检出”然后对所有连通域取平均。这样大区域和小区域在评价体系里地位平等任何一个区域的漏检都会被直接反映到分数上。2.4 PRO背后的“等权思想”为什么它更贴近产线需求在真实产线上一个工件上同时出现两处缺陷是非常常见的事。如果模型只检出了大的那处把小的那处漏了P-AUROC的表现依然会很好看但产线端会直接把漏检的那件货当成次品放过去这就是质量事故了。PRO通过给每个连通域等权强制模型在每个区域上都不能有明显短板。我看到有些自研算法在MVTec上I-AUROC能到0.99但PRO只有0.85左右试用方一开始觉得“还挺高”直到现场测试才发现小缺陷的漏检率其实很高完全不能上线。后来我们调阈值、换损失函数PRO指标上升了实际定位效果也确实肉眼可见地变好了。这说明了什么指标不是用来刷的它是用来指导你发现模型短板的。所以我的习惯是实验室里做对比I-AUROC和PRO一起看做最终选型以PRO为主要参考I-AUROC作为辅助参考。如果某个模型I-AUROC高但PRO低说明它的全局判别能力强但空间定位能力弱这在工业场景里会很危险。3. I-AUROC的计算逻辑、公式推导与实操代码3.1 ROC曲线和AUROC的基本逻辑I-AUROC的本质是ROC曲线接受者操作特征曲线下的面积。这里我不打算堆太多数学定义直接说人话。模型对每个测试样本会输出一个“异常分数”S分数越高代表模型越觉得这个样本像异常。然后我们遍历所有可能的阈值t把分数大于等于t的样本判为“异常”小于t的判为“正常”。对每个阈值t我们都能算出两个数TPR真实阳性率即“真正是异常的样本里有多大比例被你判成了异常”和FPR错误阳性率即“本来是正常的样本里有多大比例被你误判成了异常”。把每个阈值下的FPR, TPR点画出来连成曲线就是ROC曲线。曲线越靠近左上角说明模型在任意阈值下都能很稳定地把异常和正常分开。AUROC就是曲线下的面积取值在0到1之间0.5等于乱猜1.0等于完全可分。用统计学的话说AUROC还等价于“随机从一个异常样本和一个正常样本中各抽一个模型给异常样本打高分的概率”。这个理解方式特别重要因为它解释了为什么AUROC对类别不均衡不敏感——它不是拿“类别总数”来算而是拿“配对比较”来算。3.2 基于sklearn计算I-AUROC实际工程里我们不会真的把ROC曲线遍历一遍再求积分。sklearn.io里直接就有封装好的函数。假设你已经把测试集通过模型得到了一组图像级别的分数import numpy as np from sklearn.metrics import roc_auc_score, roc_curve # y_true: 图像级别标签1表示异常0表示正常 # y_score: 模型输出的图像级别异常分数越大越异常 y_true np.array([0, 0, 1, 0, 1, 1, 0, 1]) y_score np.array([0.12, 0.08, 0.87, 0.15, 0.72, 0.91, 0.20, 0.66]) # 计算I-AUROC i_auroc roc_auc_score(y_true, y_score) print(fI-AUROC: {i_auroc:.4f}) # 如果想画ROC曲线 fpr, tpr, thresholds roc_curve(y_true, y_score)这里有个细节容易被忽略roc_auc_score对正负样本的标签编码约定是1为正。如果你数据集里把异常标记为0、正常标记为1算出来的AUROC会变成对称的镜像值1 - auroc也就是比0.5小很多。我见过不止一个同学在这里踩坑捣鼓半天以为是模型训练有问题。另外提一句如果测试集很小比如只有十几张图AUROC的分辨率是非常粗糙的。它可能离散地只能取到几个值这个时候不能因为模型0.8比0.75高就下结论说“模型A优于模型B”需要做置信区间或者增加验证样本。3.3 为什么I-AUROC不能反映定位能力我接触过不少做分割类算法的朋友刚开始评估异常检测模型时很习惯用“像素准确率”来看定位效果后来发现定位不准又换成P-AUROC。但只拿P-AUROC依然会吃暗亏——就像前面说的它会被大区域带偏。而I-AUROC干脆连像素信息都不看。它只关心整张图像最终被打出来的分数是否够高完全不要求模型对缺陷位置有任何区分能力。所以在做异常检测算法评测时I-AUROC高只能说明“模型适合做筛选用”不能说明“模型能指导维修”。说到这里必须强调一个实践原则如果要评测定位能力千万不要用I-AUROC凑合。你在选型时至少得同时计算P-AUROC和PRO两个指标一起看才能比较全面地反映定位质量。4. PRO指标的原理、计算步骤与代码实现4.1 PRO的定义与数学表达PRO的全称是Per-Region Overlap翻译过来是“逐区域重叠率”。它的核心思想是把每个缺陷连通域当作独立单元先算每个区域的检出率再对所有区域取平均。具体计算逻辑我用通俗步骤描述对真实标签Ground Truth做连通域分析把每个独立的缺陷区域标记出来。MVTec AD这类数据集的掩码通常直接用连通域分析就能提取出多个region。对每个连通域region把模型的像素级预测分数或二值化后的掩码与该区域的真实掩码做对比计算出该区域的“检出比例”。这里的“检出比例”定义为模型预测为缺陷或分数高于某个内部阈值的像素中有多少落在该真实区域内与该区域总像素数的比例。把所有连通域的检出比例取平均就是PRO。如果模型对一个小缺陷只检出了20%的像素另一个大缺陷检出了98%P-AUROC可能因为大缺陷像素多而显得“整体检出率很高”但PRO就是20% 98%/ 2 59%直接把这个偏科问题暴露出来。4.2 计算PRO的完整代码下面给出一段基于Python的PRO计算参考实现。这里有个关键点PRO怎么算本质上依赖两个选择——怎么定义“检出”的阈值以及怎么对连通域做标记。业界一份广泛认可的测评代码是MVTec官方库里的实现我这里给出一个简化但逻辑一致的自实现版本方便你自己加进实验脚本。import numpy as np from scipy import ndimage from sklearn.metrics import roc_auc_score def compute_pro(gt_masks, pred_scores, num_thresholds200): gt_masks: list[np.array]每个元素是 (H, W) 的二值掩码1为缺陷 pred_scores: list[np.array]每个元素是 (H, W) 的模型输出分数越大越异常 pro_list [] for gt, score in zip(gt_masks, pred_scores): # 1. 对真实掩码做连通域标记 labeled_gt, num_regions ndimage.label(gt.astype(int)) if num_regions 0: continue # 2. 对每个连通域单独计算“区域检出率”并取平均 region_overlaps [] for region_id in range(1, num_regions 1): region_mask (labeled_gt region_id) region_pixels region_mask.sum() if region_pixels 0: continue # 这里用内部阈值的方式定义“预测为正” # 简单起见对每个区域统计预测分数0.5的像素占区域总像素的比例 hit_ratio (score[region_mask] 0.5).sum() / region_pixels region_overlaps.append(hit_ratio) # 取所有区域的均值作为该图像的PRO pro_list.append(np.mean(region_overlaps)) return np.mean(pro_list)注意这个简化版本的阈值是写死的0.5。严谨的PRO计算方式有两种一种是固定阈值下计算另一种是遍历多个阈值取曲线再用一个固定FPR下的PRO值作为最终分数。后者更常用于论文报告因为固定0.5对某些模型不公平——有些模型的输出分数整体偏低。更稳妥的做法是借鉴AUROC的思路遍历多个阈值在每个阈值下都算一次“平均区域重叠率”得到一条PRO曲线然后取FPR在0.3或0.05视数据集而定以内的最大PRO值作为最终报告指标。这样做可以避免因为阈值选择不当带来的误判。4.3 计算P-AUROC与PRO时的“坑位”提示第一连通域分析时不要忽略面积过小的孤立噪点。真实标注掩码里经常会有零散的几个像素点如果这些也算作独立连通域PRO会被严重拉低。通常的做法是对连通域做一次“面积过滤”去掉小于某个阈值的碎片区域。这个阈值需要根据你实际缺陷的大小来定没有万能参数。第二pred_scores的尺寸必须和gt完全一致。有些分割模型的输出会做下采样然后插值回原图。插值操作本身会引入边缘误差如果先做插值再算PRO最好确认插值方式nearest还是bilinear不会对结果造成太大偏移。我的习惯是算P-AUROC和PRO之前统一用nearest插值把预测分数resize到原图尺寸然后再做二值化比较。第三如果一张图里没有缺陷也就是gt全为0这组数据不能参加PRO计算。PRO本身关注的是“缺陷检出能力”没有缺陷的自然无从谈检出。但I-AUROC计算时这些正常图必须参加它们是负样本的重要组成部分。这俩指标的样本集合不一样很多人在对比实验结果时没注意直接报“PROxx, I-AUROCxx”结果发现他PRO比I-AUROC还高一看就是没把数据分清楚。5. 从评价指标看工业异常检测算法全景与选型思路5.1 主流的工业异常检测算法在指标上的表现特征目前公开数据集上常见的算法大致可以分成三类基于嵌入向量的如PatchCore、PaDiM、基于重建的如UninAD、DRAEM、基于合成异常的如CutPaste、DFR。它们在I-AUROC和PRO上的表现规律其实很明显基于嵌入向量的方法通常I-AUROC很高因为特征提取能力强对全局异常的区分度好。但PRO不一定同步高因为它对局部精细区域的判别有时候不够细腻尤其当缺陷纹理不明显时容易漏。基于重建的方法PRO更稳定因为模型逐像素重建对空间位置的误差天然敏感。但这类方法的I-AUROC可能不如嵌入法高因为正常纹理的轻微偏差也可能被放大成重构误差导致误报偏多。基于合成异常的方法取决于合成的策略。合成得好区域定位能力会比较强PRO会好看合成得不好可能只是把I-AUROC刷上去了但对真实缺陷的泛化能力很差。选型时的参考标准如果你是做“分拣”更看重不漏过任何一个异常品那I-AUROC的优先度高一些如果你是做“返修定位”或者“缺陷分类前置的预处理”那PRO更应该被重视。5.2 大模型时代评价指标如何迁移最近大模型相关的异常检测方向很热包括基于CLIP等预训练视觉语言模型做零样本异常检测。这类方法在评估时评价指标仍是I-AUROC和PRO但多了一个维度提示词对结果的影响。你写“a scratch on the surface”还是“a tiny crack”可能导致AUROC波动好几个点。所以很多人开始在Prompt Ensembling和阈值调优上做文章这本质上也是在“用评价指标反推模型行为”。熟悉评价指标的定义对你做大模型方向的实验也很有帮助。比如你想验证“CLIP在工业异常检测上的迁移能力”必须同时报告零样本I-AUROC、线性探测后的I-AUROC以及细粒度定位的PRO。理由很简单大模型在下游任务里是否真的学到了空间结构单看图像级AUROC说明不了问题必须结合PRO验证。5.3 指标组合策略工业异常检测项目里我建议怎么报数项目汇报和论文写作其实是两种不同的需求。论文审稿人更看重I-AUROC和PRO的绝对值但项目现场我一般要求测试团队至少报五个数I-AUROC、P-AUROC、PRO、FPRTPR0.95、以及误检率在固定阈值下。后面两个指标和你最终要设置的报警阈值密切相关。FPRTPR0.95的意思是在保证95%的异常样本被检出的前提下允许有多少正常样本被误报为异常。这个指标对产线的意义非常大——它直接告诉你报警率能压多低。很多模型的AUROC看起来有0.98但实际调阈值时一旦要保证TPR达到95%FPR就直接飙到10%甚至20%这样的系统上线之后每条产线每天可能被误报几百次根本跑不下去。所以我更推荐的做法是利用I-AUROC/PRO做模型选型用FPRTPR0.95做阈值设定后续产线上再叠加人工复核抽样。这套组合拳比单纯看一个AUROC靠谱得多。6. 实战避坑指南与常见问题速查6.1 我实测过的一些“指标异常”现象分析场景一I-AUROC很高PRO很低。这通常意味着模型抓住了图像的“全局特征差异”但对局部异常像素的识别不敏感。这种模型适合做初筛不适合做精细定位。排查方向试试增加局部Patch损失或者提高输入分辨率。场景二P-AUROC和PRO差距很大。比如P-AUROC有0.93PRO只有0.72。这大概率是模型只处理好了大缺陷小缺陷区域漏检严重。排查方向统计缺陷连通域的面积分布看看模型是不是只对大面积缺陷有响应考虑在训练数据里对小缺陷做重加权。场景三指标都不低但产线测试误检率爆炸。这种情况下先别急着改模型检查一下测试数据分布和训练数据是否一致。真实产线光照变化、相机抖动、产品批次纹理差异这些都可能让指标“虚高”一旦现场数据分布偏移模型就失灵。6.2 常见问题速查表问题可能原因排查思路AUROC低于0.5标签正负搞反或pred_score方向反检查标签1代表异常score越大越异常PRO波动很大连通域数量太少或碎片噪点太多加面积过滤或确保标注质量稳定P-AUROC和PRO趋势相反大缺陷主导像素级指标辅助分析缺陷连通域面积分布同模型在不同数据上指标差异大数据域分布偏移可视化嵌入特征或重建误差找偏移维度报告里只给I-AUROC但没给PRO很可能没评估定位能力强制要求补测PRO6.3 如何构建一份可复现、可追溯的实验评价体系做异常检测的评测我强烈建议一开始就把代码、随机种子、数据集版本、推理预处理的参数全部固定下来。别看这只是工程习惯我见过太多因为“有人改了resize参数”导致结果无法复现、最后论文被质疑的案例。推荐的评测流程是先定义一个统一的evaluate.py脚本输入是真实掩码和预测分数输出I-AUROC、P-AUROC、PRO、FPRTPR0.95四项指标再附加打印出每个类别的指标明细。这样每次跑完实验只需要关注一页报告不用到处找散落的log。如果条件允许把指标计算的标准统一到与公开基准代码一致也是个很好的习惯。比如MVTec AD官方评测脚本的细节建议直接拿来做基准线。7. 相关热搜词里的“异常检测算法全景”浅谈最近的搜索词里混着很多异常检测算法名也有不少VMware、ArcGIS、Adobe等工具类搜索。行业热度这么高说明想入局这个方向的开发者越来越多。但我想提醒一下算法名称记再多不如先把“如何评价一个算法”这件事搞明白。因为所有算法、所有模型最终都要落到同一套评价体系里去分高下。你知道了I-AUROC和PRO哪怕换个全新的算法框架也还是可以用这套尺度去判断它的成色。关于变分自编码器、扩散模型等生成类算法在异常检测里的应用这几年也陆续刷出了新高度。但最后你会发现不管内部机制多花哨报告结果还是I-AUROC和PRO。这也侧面说明了这两个指标的生命力——它们不是在限制算法而是在帮我们抽象出“好算法”的本质判得准也定得准。8. 一些不容易在论文里看到的心得做了几年工业异常检测项目我最大的感受是评价指标是一面镜子既照模型也照数据。以前有个客户拿来的数据质量非常差标注掩码画得歪歪扭扭缺陷边界经常把正常纹理也圈进去。结果我们的模型再怎么调PRO都卡在0.8上不去。后来仔细一排查发现是标注本身就错了——模型在努力拟合一个错误的标准指标自然好看不了。所以在动手调模型之前我强烈建议大家先做“评价指标的可信度检验”。方法是找一个你肉眼能明显分辨出好坏的两组模型结果分别计算I-AUROC和PRO看它们是否真的能反映你看到的质量差异。如果指标和直觉对不上先排查数据、代码而不是急着优化网络结构。另一点心得PRO的计算里连通域分析的方式会直接影响数值。不同实现里可能用ndimage.label的4连通还是8连通结果就会有几个百分点的差异。发论文时必须注明连通域分析用的邻接方式否则其他人很难复现你的结果。最后再分享一个小技巧如果你在调阈值阶段总被“该设多少”困扰可以尝试直接画出TPR-FPR曲线其实就是ROC的另一种坐标系表现然后在曲线上找到离左上角最近的点或者找到TPR0.95时FPR最低的点。这个点在工业场景里通常就是性价比最高的报警阈值。与其盯着一个抽象的AUROC数字瞎猜阈值不如让曲线明确告诉你“在该误报率和该检出率之间你的系统能走到什么极限”。这套流程走下来你再去回答“这个模型能不能上线”这个问题就不再是拍脑袋说“感觉可以”而是有了实打实的指标支撑。
返回列表