☰
QualityInspector 无监督异常检测(UAD)实战指南:PaDiM / PatchCore / STFPM 训练、评估与预测
2026/9/25 15:01:47 网站建设 项目流程
  • 人工智能
  • 计算机视觉
  • 预训练

【免费下载链接】PaddleSeg

Easy-to-use image segmentation library with awesome pre-trained model zoo, supporting wide-range of practical tasks in Semantic Segmentation, Interactive Segmentation, Panoptic Segmentation, Image Matting, 3D Segmentation, etc.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleSeg
点击查看免费下载

QualityInspector 是 PaddleSeg 仓库中的一个工业质检子项目,内置了一套完整的**无监督异常检测(Unsupervised Anomaly Detection, UAD)**方案,覆盖 PaDiM、PatchCore、STFPM 三种基于表示的算法,配套 MVTec AD 数据集的训练、评估、预测工具与 YAML 配置体系。本文以contrib/QualityInspector/docs/uad/README.md为主线,结合contrib/QualityInspector/qinspector/uad/与tools/uad/下的源码实现,完整讲解算法原理、数据集组织、命令行操作与配置文件逐项解读,读者可据此在自有缺陷检测场景中直接落地。

1. 无监督异常检测算法原理

无监督异常检测(UAD)的核心假设是:工业场景中缺陷样本稀少且形态未知,难以收集,而正常(OK)样本充足。因此算法只使用正常样本建模"正常分布",推理时凡是偏离该分布的图像区域即判定为缺陷。技术方向可划分为两类:

  • 基于表示的算法:通过某种映射将输入图片映射到特征空间,在该空间中正常样本与异常样本更容易区分。特点是推理速度快,但一般只能实现patch 级(区域级)的分割;
  • 基于重构的算法:仅用正常样本训练的重构模型只能很好地重构正常样本,无法准确重构缺陷样本,通过对比重构误差检测缺陷。特点是能够实现像素级分割,但速度较慢。

在具体实现上,基于表示的算法通常采用 ImageNet 预训练 backbone 提取特征,推理时对比正常样本与异常样本的特征差异完成缺陷的分类与分割;基于重构的算法通常以自编码器为重构模型,推理时对比重构前后图像的差异完成分类与分割。

目前 QualityInspector 的 UAD 方案支持三种基于表示的算法,其中 PaDiM、PatchCore 无需训练网络:

算法论文思想训练阶段推理阶段
PaDiMPatch Distribution Modeling用预训练 CNN 提取多尺度特征,随机降维后逐位置拟合多元高斯分布用马氏距离衡量每个特征位置的异常分数,分数越高异常可能性越大
PatchCoreKNN Greedy CoreSet 采样提取多尺度特征,经 KNN Greedy CoreSet 采样最具代表性的特征点,构建特征向量记忆池比对测试特征与记忆池的距离得到每个特征位置的异常分数
STFPM师生特征金字塔匹配学生网络将自身特征与冻结的教师网络逐尺度匹配,学习正常样本分布对比教师、学生各尺度特征,差异越大异常分数越高

从源码结构看,PaDiM/PatchCore 属于"训练即特征统计"的范式(backbone 全程no_grad),而 STFPM 的配置中带有epochs/lr/momentum/weight_decay等真实训练超参,是需要训练网络参数的算法,三种算法互补覆盖不同精度与成本需求。

1.1 PaDiM 源码级实现

PaDiM 的模型定义在 contrib/QualityInspector/qinspector/uad/models/padim.py 中,ResNet_PaDiM直接复用 Paddle 视觉库的resnet18 / resnet50 / wide_resnet50_2,前向时在paddle.no_grad()下依次取出layer1 / layer2 / layer3三个尺度的中间特征作为嵌入来源:

with paddle.no_grad(): x = self.model.conv1(x) x = self.model.bn1(x) x = self.model.relu(x) x = self.model.maxpool(x) x = self.model.layer1(x) res.append(x) x = self.model.layer2(x) res.append(x) x = self.model.layer3(x) res.append(x) return res

训练脚本 contrib/QualityInspector/tools/uad/padim/train.py 中体现了完整的建模流程:

  1. 收集训练集所有正常样本的layer1/layer2/layer3特征,将后两层上采样到与layer1相同分辨率后沿通道拼接(embedding concat);
  2. 从拼接特征中随机选取 d 个通道降维(fins表中resnet18对应原始维度 448,降维到 100);
  3. 对每个特征位置计算均值与协方差,拟合多元高斯分布,协方差矩阵加入0.01 * I正则项保证数值稳定;
  4. 将{mean, cov}分布参数与 backbone 权重一起以.pdparams保存。

推理时用马氏距离衡量测试特征与训练分布每个位置的偏离程度。正因网络不参与梯度更新,文档特别说明:执行 PaDiM/PatchCore 训练命令时log 中 loss 恒为 0 是正常现象。

1.2 数据集加载与数据增强

数据集读取逻辑在 contrib/QualityInspector/qinspector/uad/datasets/mvtec.py 中,MVTecDataset按train/test阶段扫描{class_name}/train与{class_name}/test下的所有缺陷子目录与good目录,对非good样本再关联ground_truth/{defect_type}/{name}_mask.png标签图。图片与标签使用相同管线处理:Resize(resize)→CenterCrop(cropsize)→ToTensor(),图片额外做 ImageNet 均值的Normalize(mean[0.485, 0.456, 0.406],std[0.229, 0.224, 0.225])。训练阶段只返回图片,测试/预测阶段返回(x, y, mask)三元组用于计算 AUROC 与可视化。

2. 数据集准备(MVTec AD 格式)

QualityInspector 的 UAD 工具以 MVTec AD 数据集为例。首先下载数据集并保存在QualityInspector/data中,目录结构如下:

data/mvtec_anomaly_detection/ | |--bottle # 某类产品 | |--ground_truth # 标签图 | |--broken_large # 某类缺陷标签图 | |--000_mask.png | |--001_mask.png | |--... | | |--broken_small # 某类缺陷标签图 | |--... | | |--contamination # 某类缺陷标签图 | |--... | |--test # 测试样本 | |--good # 正常样本测试图 | |--000.png | |--... | |--broken_large # 某类缺陷测试图 | |--000.png | |--... | |--broken_small # 某类缺陷测试图 | |--... | |--contamination # 某类缺陷测试图 | |--... | |--train # 训练样本 | |--good # 正常样本训练图 | |--000.png | |--... ...

MVTec AD 数据包含结构和纹理类型的零件共计 15 类,其中训练集只包含 OK 图像,测试集包含 NG 和 OK 图像。从 contrib/QualityInspector/qinspector/uad/datasets/mvtec.py 可见 15 类的完整划分:

  • 纹理类(textures):carpet, grid, leather, tile, wood
  • 物体类(objects):bottle, cable, capsule, hazelnut, metal_nut, pill, screw, toothbrush, transistor, zipper

如果希望使用自己的数据集,请组织成上述 MVTec AD 格式,将自定义数据集作为 MVTec AD 中的一个 category,即路径设置为QualityInspector/data/mvtec_anomaly_detection/{category}/...;标签文件为灰度图,缺陷部分像素值为 255。

3. 训练、评估、预测命令

以 PaDiM 模型为例,训练、评估、预测脚本存放在tools/uad/padim/目录下(PatchCore、STFPM 对应tools/uad/patchcore/、tools/uad/stfpm/)。通过--config参数传入对应模型 YML 配置文件,通过--category参数指定 MVTec AD 中的某个类别:

  • 训练:
python tools/uad/padim/train.py --config ./configs/uad/padim/padim_resnet18_mvtec.yml --category bottle

说明:由于 padim 和 patchcore 的网络不参与训练,执行上述命令时若 log 产生 loss 为 0 是正常现象。

  • 评估:
python tools/uad/padim/val.py --config ./configs/uad/padim/padim_resnet18_mvtec.yml --category bottle
  • 预测:
python tools/uad/padim/predict.py --config ./configs/uad/padim/padim_resnet18_mvtec.yml --category bottle

从 contrib/QualityInspector/tools/uad/padim/train.py 的 argparse 定义看,--category除单个类别外,还支持textures、objects、all三个聚合取值,分别批量处理纹理类、物体类或全部 15 类,并自动将逐类 Image_AUROC / Pixel_AUROC 结果写入{save_path}/{backbone}/{category}_seed{seed}.csv,最后输出 mean 平均行。因此若配置category: all,一条命令即可完成全数据集训练与评估。

3.1 各算法在 MVTec AD 上的实验结果

三个算法目录下的 README 记录了以 resnet18 为 backbone、在 MVTec AD 上的图像级与像素级 ROCAUC 指标:

PaDiM(resnet18)

指标AvgCarpetGridLeatherTileWoodBottleCableCapsuleHazelnutMetal NutPillScrewToothbrushTransistorZipper
Image-level0.9180.9960.9281.0000.9650.9810.9990.8760.8750.7600.9840.8440.7740.9690.9720.850
Pixel-level0.9620.9900.9440.9870.8940.9310.9790.9490.9800.9700.9630.9230.9750.9850.9740.981

PatchCore(resnet18)

指标AvgCarpetGridLeatherTileWoodBottleCableCapsuleHazelnutMetal NutPillScrewToothbrushTransistorZipper
Image-level0.9790.9920.9711.0000.9900.9901.0000.9790.9820.9990.9970.9390.9470.9420.9930.971
Pixel-level0.9780.9910.9780.9990.9370.9420.9820.9850.9890.9880.9840.9760.9940.9910.9570.987
PRO_score0.9320.9610.9230.9710.8480.8930.9470.9430.9370.9350.9390.9280.9710.9180.9100.957

STFPM(resnet18)

指标AvgCarpetGridLeatherTileWoodBottleCableCapsuleHazelnutMetal NutPillScrewToothbrushTransistorZipper
Image-level0.9480.9880.9941.0000.9880.9940.9790.9290.9791.0000.9780.8160.8500.8750.8960.956
Pixel-level0.9620.9900.9860.9950.9710.9551.0000.9370.9540.9860.9610.9050.9850.9900.8300.984

整体来看,PatchCore 的 Image-level 平均 ROCAUC 最高(0.979),STFPM 与 PaDiM 的像素级表现接近(均为 0.962),而 PatchCore 额外提供 PRO_score 指标(0.932)用于评价缺陷区域定位质量。

4. 配置文件解读

无监督异常检测(UAD)模型的参数可以通过YML 配置文件和命令行参数两种方式指定,如果 YML 文件与命令行同时指定同一个参数,命令行指定的优先级更高。这一优先级由 contrib/QualityInspector/qinspector/cvlib/uad_configs.py 中的ConfigParser实现(如--device、--category、--resize等均可覆盖 YML 默认值),便于不修改配置文件的临时实验。

4.1 PaDiM 配置(padim_resnet18_mvtec.yml)

配置文件位于 contrib/QualityInspector/configs/uad/padim/padim_resnet18_mvtec.yml,主要参数如下:

# common arguments device: gpu seed: 3 # 指定numpy, paddle的随机种子 # dataset arguments batch_size: 1 num_workers: 0 category: bottle # 指定MVTecAD数据集的某个类别 resize: [256, 256] # 指定读取图像的resize尺寸 crop_size: [224, 224] # 指定resize图像的crop尺寸 data_path: data/mvtec_anomaly_detection # 指定MVTecAD数据集的根目录 save_path: output/ # 指定训练时模型参数保存的路径和评估/预测时结果图片的保存路径 # train arguments do_eval: True # 指定训练后是否进行评估 backbone: resnet18 # 支持resnet18, resnet50, wide_resnet50_2 # val and predict arguments save_pic: True # 指定是否保存第一张评估图片/预测图片的结果 model_path: output/resnet18/bottle/bottle.pdparams # 指定加载模型参数的路径 # predict arguments img_path: data/mvtec_anomaly_detection/bottle/test/broken_large/000.png # 指定预测的图片路径 threshold: 0.5 # 指定预测后二值化异常分数图的阈值

参数说明与源码对照:

  • seed:同时作用于random、numpy、paddle三个随机源(见train.py中random.seed / np.random.seed / paddle.seed),保证特征降维的随机通道选择等步骤可复现;
  • resize与crop_size:分别对应MVTecDataset中的T.Resize与T.CenterCrop,PaDiM 默认 256 缩放到 224 中心裁剪,PatchCore 默认crop_size: [256, 256](即不裁剪);
  • category:除单类别外,配置值支持textures、objects、all(见 contrib/QualityInspector/qinspector/uad/datasets/mvtec.py 的CLASS_NAMES划分),all时自动遍历全部 15 类并输出汇总 CSV;
  • backbone:PaDiM/PatchCore 支持resnet18 / resnet50 / wide_resnet50_2(与padim.py中models字典一致),STFPM 支持resnet18 / resnet34 / resnet50 / resnet101;不同 backbone 的嵌入维度不同,train.py的fins表记录了各 backbone 的特征通道数(resnet18 为 448,resnet50 / wide_resnet50_2 为 1792);
  • model_path:评估/预测时加载的权重路径,需与backbone、category、save_path组合保持一致,如 PaDiM 训练保存路径为output/{backbone}/{category}/{class_name}.pdparams(见train.py的save_name拼接逻辑),PatchCore 则保存为output/coreset_resnet18_10/bottle.pdparams形式;
  • threshold:预测时对异常分数图做二值化的阈值,PaDiM/PatchCore 默认 0.5,STFPM 默认 0.01,具体取值应结合验证集 AUROC 曲线与缺陷率调节。

4.2 PatchCore 特有参数

contrib/QualityInspector/configs/uad/patchcore/patchcore_resnet18_mvtec.yml 在公共参数之外新增:

method: coreset # projection method, one of [sample, ortho, svd_ortho, gaussian, coreset] k: 10 # using feature channels
  • method:特征记忆池的构建/投影方式,可选sample / ortho / svd_ortho / gaussian / coreset,默认coreset(KNN Greedy CoreSet 采样,与论文一致),相关实现位于 contrib/QualityInspector/qinspector/uad/utils/k_center_greedy.py 与 contrib/QualityInspector/qinspector/uad/utils/random_projection.py;
  • k:使用的特征通道数,默认 10,直接影响记忆池规模与推理开销。

4.3 STFPM 特有参数

contrib/QualityInspector/configs/uad/stfpm/stfpm_resnet18_mvtec.yml 是三个算法中唯一需要真实训练网络的配置,包含完整训练超参:

# train arguments epochs: 100 do_eval: True # After training, whether to eval model; backbone: resnet18 # Support resnet18, resnet34, resnet50, resnet101 lr: 0.4 momentum: 0.9 weight_decay: 1.0e-4 # val arguments compute_pro: False
  • lr: 0.4、momentum: 0.9、weight_decay: 1.0e-4:SGD 优化器参数,用于学生网络向冻结的教师网络逐尺度特征匹配学习;
  • compute_pro:是否额外计算 PRO(Per-Region Overlap)指标,默认False,开启后评估耗时增加但可获得更全面的定位质量评估(PatchCore README 中已给出 PRO_score 参考值 0.932)。

5. 使用流程小结与注意事项

  1. 数据:按 MVTec AD 目录格式准备数据(训练集仅 OK 图,测试集含 OK/NG 图,ground_truth为缺陷像素值为 255 的灰度图),放入QualityInspector/data/mvtec_anomaly_detection/;
  2. 选型:对精度要求高且推理资源充足可选 PatchCore(Image-level 平均 ROCAUC 最高),追求更细粒度像素定位可关注 PaDiM/STFPM,需要可训练网络则选择 STFPM;
  3. 执行:分别调用tools/uad/{padim|patchcore|stfpm}/{train|val|predict}.py,通过--config指定对应 YML、--category指定类别,命令行参数可覆盖 YML 中同名项;
  4. 注意:PaDiM/PatchCore 训练日志中 loss 恒为 0 属正常现象(backbone 不参与训练,仅统计特征分布/构建记忆池);评估与预测前务必确认model_path指向正确权重,STFPM 的阈值默认值(0.01)明显低于 PaDiM/PatchCore(0.5),按需基于验证集调整threshold以平衡误报与漏检。

6. 相关资源索引

  • UAD 总览文档:contrib/QualityInspector/docs/uad/README.md
  • 算法配置与结果:PaDiM README / 配置、PatchCore README / 配置、STFPM README / 配置
  • 核心实现:padim.py、patchcore.py、stfpm.py、mvtec.py
  • 工具脚本:tools/uad/padim/train.py、tools/uad/padim/val.py、tools/uad/padim/predict.py(PatchCore/STFPM 结构相同)
  • 参数解析:contrib/QualityInspector/qinspector/cvlib/uad_configs.py
  • 人工智能
  • 计算机视觉
  • 预训练

【免费下载链接】PaddleSeg

Easy-to-use image segmentation library with awesome pre-trained model zoo, supporting wide-range of practical tasks in Semantic Segmentation, Interactive Segmentation, Panoptic Segmentation, Image Matting, 3D Segmentation, etc.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleSeg
点击查看免费下载

相关推荐

上一篇:Cloudflare Docs 风格指南审查规则编写指南:从规则分类到接线与评估的完整实践
下一篇:终极Windows防撤回解决方案:RevokeMsgPatcher完整使用指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询