工业视觉异常检测:PatchCore与EfficientAD实战一、引言:工业质检的痛点与机遇在电子制造、汽车零部件、纺织品等产线上,缺陷检测一直是最耗费人力的环节。传统机器视觉依赖手工特征(边缘检测、纹理分析、模板匹配),面对以下场景时力不从心:缺陷形态不可预知:划痕、凹坑、毛刺、色差,种类繁多且持续新增正样本极度不平衡:产线上 99.9% 是良品,缺陷样本稀缺背景纹理复杂:金属拉丝、皮革纹路、织物纹理,正常方差本身就大传统做法是收集大量缺陷样本训练分类器,但在工业现场这几乎不可行。异常检测(Anomaly Detection)另辟蹊径:只学"什么是正常的",凡是偏离正常分布的都视为异常。这一范式让工业视觉质检从"缺陷分类问题"转变为"分布偏离检测问题",大幅降低了对标注数据的依赖。本文将深入剖析两个工业级异常检测算法——PatchCore和EfficientAD,并提供可运行的实战代码。方法核心思想推理速度适用场景PatchCore局部特征记忆库 + 最近邻中等逻辑型缺陷(缺失、错位)EfficientAD师生网络 + 自编码器蒸馏快表面纹理缺陷(划痕、污渍)二、核心原理2.1 PatchCore:局部记忆,全局感知PatchCore(2022, Roth et al.)的核心直觉非常朴素:把正常图像的所有局部特征存下来,检测时查最近邻距离。三步走架构:正常图像 → 预训练Backbone(WideResNet-50/101)→ 提取中层特征图 → 局部感知聚合(AvgPool → Neighborhood Aggregation) → Coreset 采样(贪心降采样至 1%~10%)→ 记忆库 M ↓ 测试图像 → 同样提取特征 → 对每个 patch 在 M 中找最近邻 → 距离热力图 → 分割 + 图像级异常分数关键技术点:中层特征提取:不取最后一层(太抽象,丢失空间信息),取 ResNet 的 layer2/layer3 输出,保留局部纹理和结构信息。局部感知聚合(Local Patch Aggregation):对特征图每个位置,聚合其p × p邻域的特征,增强对局部上下文(如纹理连续性)的建模。Coreset 子采样:完整记忆库可能包含数百万个特征向量,推理太慢。用贪心算法(minimax facility location)采样,保留 1% 的点仍能保持 98%+ 的检测性能。异常评分:对测试图每个 patch 计算到记忆库最近邻的距离,得到像素级异常热力图。取 top-K 最大距离的均值作为图像级异常分数。2.2 EfficientAD:蒸馏出来的异常感知EfficientAD(2023, Batzner et al.)是目前工业异常检测领域推理最快的方案之一(单张图像 2ms 在专用硬件上)。它同时用到了两个互补的"教师-学生"蒸馏架构:双通道架构:┌─→ 教师网络 T(固定,训练好的特征提取器) 输入图像 ──┬───────┤ │ └─→ 学生网络 S(训练中模仿 T 的特征输出) │ 异常 = ||T(x) - S(x)|| │ └─→ 自编码器 AE(重建输入) 异常 = ||x - AE(x)|| 最终异常分数 = 逻辑异常分数 + 纹理异常分数两个互补的异常信号:师生网络(STPM):教师已经见过海量正常数据,知道"正常长什么样"。当学生无法复现教师对异常区域的特征表示时,差异(||T(x) - S(x)||)就是异常信号。擅长检测逻辑结构异常(如零件缺失、位置偏移)。自编码器(AE):AE 被训练只重建正常图像。异常区域的纹理在重建时会被"抹平",重建误差(||x - AE(x)||)定位表面纹理异常(如划痕、油污)。混合推理:两路异常分数逐像素加权融合,覆盖更多异常类型。关键设计:教师网络用预训练的轻量模型(如轻量 WideResNet),推理不参与梯度计算学生网络结构远小于教师(防止完美模仿),强制其学习压缩表示自编码器瓶颈层极窄,确保异常纹理无法通过三、实战代码:基于 Anomalib 训练与部署Anomalib 是 Intel 开源的异常检测工具库,内置 PatchCore、EfficientAD 等多种算法。以下使用 MVTec AD 数据集(工业异常检测标准基准)进行实战。3.1 环境准备pipinstallanomalib[full]openvino3.2 PatchCore 训练与推理""" PatchCore 在 MVTec AD 上的完整训练与推理流程 数据集结构: mvtec_ad/ bottle/ train/good/ ← 仅正常样本 test/good/ test/broken_large/ test/broken_small/ test/contamination/ """importtorchfromanomalib.dataimportMVTecfromanomalib.modelsimportPatchcorefromanomalib.engineimportEnginefromanomalib.deployimportOpenVINOInferencerfrompathlibimportPath# ─── 1. 数据加载 ───# MVTec AD 数据集:15 个类别,训练集仅含正常样本datamodule=MVTec(