基于生成模型特征处理的工业异常检测系统(全套源码+数据集)

本项目面向工业质检场景,以 Dinomaly(CVPR 2025)为核心算法,结合 DINOv2 视觉基础模型与 ViTill 线性注意力解码器,实现对工业产品的无监督异常检测与亚像素级缺陷定位。系统涵盖从数据集构建、模型训练调优,到 Web 可视化平台的完整工程链路。


数据集

MVTec Anomaly Detection(MVTec AD)

MVTec AD 是工业异常检测领域最权威的基准数据集,收录了 15 种工业产品类别,涵盖纹理类与物体类两大场景。训练集仅包含无缺陷的正常图像,测试集同时包含正常图像与多种缺陷类型的异常图像,并附带像素级缺陷掩码(ground truth mask),适合无监督异常检测方法的训练与评估。

数据集图像均为 RGB 彩色图,原始分辨率在 700×700 至 1024×1024 之间,本项目统一 resize 至 448×448 输入模型。

类别分布

类别 中文名 训练图像 测试图像
bottle 瓶子 209 83
cable 线缆 224 150
capsule 胶囊 219 132
carpet 地毯 280 117
grid 栅格 264 78
hazelnut 榛子 391 110
leather 皮革 245 124
metal_nut 螺母 220 115
pill 药片 267 167
screw 螺丝 320 160
tile 瓷砖 230 117
toothbrush 牙刷 60 42
transistor 晶体管 213 100
wood 木材 247 79
zipper 拉链 240 151
合计 3 629 1 725

数据集构建与预处理

训练阶段,对正常样本施加轻量数据增强——随机水平翻转(概率 0.5)与颜色抖动(亮度 ±0.1、对比度 ±0.1),以提升模型对光照变化的鲁棒性,同时避免破坏纹理结构导致语义失真。测试阶段仅做缩放,不做任何增强,保证评估的客观性。所有图像在归一化时采用 ImageNet 统计量(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),以兼容 DINOv2 预训练权重的输入分布。

异常掩码以最近邻插值缩放,避免引入中间灰度值而污染像素级二值标签;掩码像素值大于 0 的位置统一置为 1.0,与 MVTec 官方评估协议保持一致,确保微小缺陷区域不被截断。

本项目采用统一多类别训练策略,将 15 个类别的正常样本合并为一个 Dataset,让解码器在同一套参数下学习多类工业产品的正常特征分布,而非分别训练 15 个独立模型。这一策略显著降低了部署复杂度,同时在实验中验证了其泛化能力并不弱于单类模型。


模型架构

整体思路

Dinomaly 的核心假设是:当一个强大的视觉编码器提取到正常图像的特征后,一个容量受限且带有噪声的解码器能够"近似但不精确地"重建这些特征——对正常区域重建误差小,对异常区域(训练中从未见过)重建误差大。这个误差图即为异常分数图。

DINOv2 编码器

编码器采用 vit_base_patch14_dinov2.lvd142m(ViT-Base,patch size=14),通过 timm 加载预训练权重(约 330MB),参数量约 86M。在 448×448 输入下,图像被切分为 (448/14)² = 1024 个 patch token,每个 token 的特征维度为 768。

编码器参数全程冻结,不参与梯度计算。通过 register_forward_hook 钩子提取第 2~9 层(共 8 层)的 patch 特征,CLS token 被丢弃,只保留空间语义信息。将这 8 层特征分为两组(第 2-5 层为低语义组,第 6-9 层为高语义组),组内取均值融合,得到两个融合特征张量,供解码器使用。

ViTill 解码器

解码器是唯一需要训练的部分,参数量约 25M,包含以下三个关键模块:

Noisy Bottleneck(噪声瓶颈):将两组编码器融合特征拼接(维度翻倍),经过两层线性层压缩回 768 维,中间插入 Dropout(p=0.2)作为噪声注入。Dropout 在训练阶段随机屏蔽部分特征维度,强迫解码器不能逐位复制编码器的输出,从而避免退化为恒等映射。

线性注意力(LinearAttention):采用 ELU 核函数近似,将标准 Softmax 注意力的 O(N²) 复杂度降至 O(N)。公式为 φ(x) = ELU(x) + 1,先计算 KT·V(维度 D×D),再计算 Q·(KT·V),规避了 token 间两两交互的显存瓶颈。线性注意力天然无法精确聚焦于局部区域,这一"缺陷"在异常检测中反而有益:解码器很难对异常区域也做到精确重建。内部强制使用 float32 计算,防止 1024 个 token 累加时 fp16 溢出产生 NaN。

解码层堆叠:共 8 个 DecoderBlock(层归一化 → 线性注意力 → 残差;层归一化 → MLP → 残差),输出 8 层中间特征,再以相同的分组策略做均值融合,得到两个解码器融合特征张量。

损失函数

使用松散余弦重建损失(Loose Cosine Reconstruction Loss):

Loss = mean over groups of (1 - cosine_similarity(enc_fused, dec_fused))

对两组融合特征分别计算余弦相似度,取均值后取反。之所以称为"松散",是因为只对融合后的特征对齐,而非逐层逐点强制匹配,这给解码器更多弹性,避免过拟合到噪声细节。

异常分数推理

推理时将解码器的 dropout 关闭(eval 模式),对每个 token 位置计算编码器与解码器特征的余弦距离,得到 (B, 1024) 的异常分数图,再双线性插值上采样到 448×448 的像素空间。每张图像取分数图的最大值作为图像级异常分数,分数图本身作为像素级定位依据。


训练过程

硬件环境

针对 RTX 3060 12GB 显卡进行了专项优化,在官方 batch_size=16 的基础上降至 8,启用混合精度训练(AMP fp16)节省约 30% 显存,线性注意力内部强制 float32 防止数值溢出,最终训练峰值显存约 10GB。

优化器配置

优化器:AdamW
学习率:2e-4
权重衰减:1e-5
学习率调度:CosineAnnealingLR(T_max=200,eta_min=1e-6)
梯度裁剪:max_norm=1.0
混合精度:GradScaler(fp16=True)
随机种子:42

AdamW 的权重衰减对线性层参数起到正则化作用,防止解码器过度拟合正常样本。余弦退火调度让学习率在训练末期平滑衰减至接近 0,使模型在最优解附近精细收敛。梯度裁剪防止线性注意力累加运算导致的梯度突刺。

断点续训

每个 epoch 结束后将解码器权重与优化器状态保存为 last_checkpoint.pth(覆盖写,不累积体积)。下次启动时自动检测并从断点恢复,避免意外中断导致训练进度损失。

权重保存策略

每 10 个 epoch 评估一次,分别在图像级 AUROC 和像素级 AUROC 创新高时各保存一份最优权重(best_img_auroc.pth / best_pix_auroc.pth)。权重文件仅保存解码器参数,编码器权重在推理时由 timm 重新加载,因此单份权重文件体积约 100MB。


训练指标记录

每 10 个 epoch 完成一次全测试集评估,训练过程中的指标变化如下:

Epoch Loss Img-AUROC Pix-AUROC
10 0.0495 97.25% 96.68%
50 0.0293 98.23% 97.68%
100 0.0225 98.83% 98.03%
150 0.0193 99.20% 98.09%
200 0.0179 99.41% 98.12%

Loss 呈现平稳单调下降趋势,AUROC 随之持续提升,200 epoch 后未出现明显过拟合,表明余弦松散损失 + Noisy Bottleneck 的组合具有良好的泛化性。


评估指标说明

图像级 AUROC(Image-level AUROC):以每张图像异常分数图的最大值作为该图的异常分数,与图像级标签(0=正常,1=异常)计算 ROC 曲线下面积。反映模型"判断一张图是否存在缺陷"的能力,本项目最终达到 99.41%

像素级 AUROC(Pixel-level AUROC):将所有图像的像素级异常分数图展平,与 ground truth 掩码展平后计算 ROC 曲线下面积。反映模型"准确定位缺陷位置"的能力,本项目最终达到 98.12%

Per-Region Overlap(PRO):在 FPR ≤ 0.3 范围内,对预测缺陷与真实缺陷连通域的重叠率进行积分并归一化。PRO 对大小不均匀的缺陷区域更公平,避免大面积背景区域主导评估结果,适合精细定位场景的补充评估。


可视化图说明

异常热力图:将像素级异常分数图经 JET colormap 渲染为伪彩色图像(蓝→绿→红,分数由低到高),再以一定透明度叠加到原图上。热力图中红色区域对应高异常分数,代表模型判断该位置存在缺陷,蓝色区域为正常背景。

训练 AUROC 曲线:系统配置页中展示每 10 个 epoch 的图像级 AUROC、像素级 AUROC 与 Loss 的变化趋势。图像 AUROC / 像素 AUROC 对应左 Y 轴(单位 %),Loss 对应右 Y 轴(虚线),帮助判断训练是否正常收敛。

异常分数进度条:检测结果页面中,进度条以当前分数与阈值的比值表示异常程度——分数超过阈值则判为异常,进度条颜色由绿色变为红色,直观反映边界情况下的置信程度。

近期检测趋势图:结果分析页面展示最近 20 次检测的异常分数折线,阈值以红色虚线标注,异常点用红色散点单独标出,便于识别批量检测中的异常集中段。

各类别异常分布柱状图:以堆叠柱状图展示 15 个类别各自的正常与异常样本数量分布,帮助识别哪类产品缺陷率最高,辅助工程师进行产线针对性改进。


系统功能

数据管理:展示 MVTec AD 15 个类别的图标、名称、训练/测试图像数量,选中类别后可快速跳转至检测页面。

模型部署:自动扫描 dinomaly/checkpoints/ 目录下的可用权重文件,展示文件名与大小;支持通过滑块预设异常判定阈值后加载;展示加载后的模型详细信息(训练轮次、图像/像素 AUROC、推理设备)。

实时检测:支持点击选择或拖拽上传图像文件(JPG/PNG),选择检测类别后调用后端推理接口,返回异常分数、异常判定结果、异常热力图,同时以进度条可视化分数与阈值的关系。

结果分析:汇总展示检测总量、正常/异常样本数、异常率、平均分数等统计指标;提供趋势折线图、正常/异常占比饼图、各类别堆叠柱状图;历史记录表支持按类别筛选、分页浏览、单条删除、批量清空、一键导出 CSV。

系统配置:实时调节异常判定阈值与热力图叠加透明度;展示 GPU 显存用量与使用率;显示训练 AUROC/Loss 曲线(数据来源于 train_log.txt);提供快速阈值预设按钮(0.3~0.7)。

登录注册:内置管理员账号(admin/admin123),支持新用户注册,账号信息持久化存储于浏览器本地,已登录状态在关闭浏览器后仍保留。


技术栈

深度学习

  • PyTorch 2.x + CUDA — 模型训练与推理框架
  • timm — DINOv2 预训练权重加载
  • torchvision — 数据增强与预处理
  • scikit-learn / scikit-image — AUROC、PRO 指标计算
  • Pillow / NumPy — 图像读写与数值运算

后端服务

  • FastAPI — 高性能异步 Web 框架
  • Uvicorn — ASGI 服务器
  • Python 3.8+

前端

  • Vue 3(Composition API + <script setup>
  • Vite 4 — 本地开发服务器与生产构建
  • Element Plus 2 — UI 组件库
  • ECharts 5 — 数据可视化图表
  • Axios — HTTP 请求封装

项目结构

c177/
├── mvtec_anomaly_detection/          # MVTec AD 数据集(需自行下载)
│   ├── bottle/
│   ├── cable/
│   └── ...(共 15 个类别目录)
│
├── dinomaly/                         # 深度学习核心模块
│   ├── config.py                     # 训练超参与路径配置
│   ├── train.py                      # 训练主入口(断点续训、评估、保存)
│   ├── models/
│   │   ├── encoder.py                # DINOv2 编码器(hook 提取多层特征)
│   │   ├── decoder.py                # ViTill 解码器(线性注意力 + 噪声瓶颈)
│   │   └── dinomaly.py               # 编解码器组合 + 推理接口
│   ├── data/
│   │   └── mvtec.py                  # MVTec 数据集加载器
│   ├── utils/
│   │   ├── losses.py                 # 余弦松散重建损失
│   │   └── metrics.py                # AUROC / PRO 评估指标
│   ├── checkpoints/                  # 训练权重输出目录
│   │   ├── last_checkpoint.pth       # 断点续训文件(每 epoch 覆盖)
│   │   ├── best_img_auroc.pth        # 图像级 AUROC 最优权重
│   │   └── best_pix_auroc.pth        # 像素级 AUROC 最优权重
│   └── logs/
│       └── train_log.txt             # 训练指标日志(每 10 epoch 追加)
│
└── web/                              # Web 系统
    ├── backend/                      # FastAPI 后端
    │   ├── main.py                   # 应用入口,挂载路由与静态文件
    │   ├── schemas.py                # Pydantic 数据模型
    │   ├── api/
    │   │   ├── detect.py             # 检测接口(上传图像、返回热力图)
    │   │   ├── model.py              # 模型管理接口(加载、状态、阈值)
    │   │   ├── history.py            # 历史记录接口(列表、统计、删除)
    │   │   └── system.py             # 系统接口(GPU 状态、训练日志)
    │   └── core/
    │       ├── detector.py           # 检测器单例(加载模型、执行推理)
    │       └── database.py           # JSON 文件持久化历史记录
    ├── vue-frontend/                 # Vue 3 前端源码
    │   ├── package.json
    │   ├── vite.config.js
    │   ├── index.html
    │   └── src/
    │       ├── main.js
    │       ├── App.vue
    │       ├── api/index.js          # Axios 接口封装
    │       ├── composables/
    │       │   ├── useAuth.js        # 登录注册状态管理
    │       │   └── useModelStore.js  # 跨组件模型状态共享
    │       ├── constants/index.js    # 类别定义 + 演示数据
    │       ├── styles/main.css       # 全局样式变量
    │       ├── views/                # 页面组件
    │       │   ├── LoginView.vue
    │       │   ├── DataView.vue
    │       │   ├── ModelView.vue
    │       │   ├── DetectView.vue
    │       │   ├── AnalysisView.vue
    │       │   └── ConfigView.vue
    │       └── components/
    │           └── HeatmapModal.vue  # 热力图预览弹窗
    ├── frontend/                     # Vue 构建产物(由 npm run build 生成)
    └── data/
        └── history.json              # 检测历史持久化文件

启动教程

环境要求

  • Python 3.8 或以上,推荐使用 conda 管理环境
  • Node.js 16 或以上(前端开发构建需要)
  • NVIDIA GPU(推荐显存 ≥ 8GB);CPU 模式也可运行但推理速度较慢

第一步:安装 Python 依赖

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
pip install timm fastapi uvicorn pillow numpy scikit-learn scikit-image tqdm

第二步:准备数据集

MVTec 官网 下载 MVTec AD 数据集,解压后将 15 个类别目录放置到项目根目录下的 mvtec_anomaly_detection/ 文件夹中,确保路径为 mvtec_anomaly_detection/bottle/train/good/...

第三步:训练模型

cd dinomaly
python train.py

首次运行会自动从 timm 下载 DINOv2 预训练权重(约 330MB)。训练日志实时输出到控制台,每 10 个 epoch 将指标写入 dinomaly/logs/train_log.txt,最优权重保存至 dinomaly/checkpoints/。训练意外中断后重新运行 python train.py 即可从断点续训。

第四步:构建前端

cd web/vue-frontend
npm install
npm run build

构建产物会自动输出到 web/frontend/,FastAPI 会从该目录托管静态文件。

第五步:启动后端服务

cd web/backend
python main.py

服务启动后访问 http://localhost:8000 即可使用完整 Web 系统。

开发阶段也可以单独启动前端开发服务器(npm run dev,端口 5173),API 请求会自动代理到 8000 端口。


本项目为个人原创,结构清晰,功能完整,适合计算机视觉方向课程设计、毕业设计和项目演示使用。有定制化需求可以评论或私信作者。

作者原创项目地址:michael-jay.pages.dev/projects.html

posted on 2026-08-03 16:19  Jay8059  阅读(0)  评论(0)    收藏  举报

导航