十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

半监督缺陷检测实战:MemSeg原理、复现与工业仪表落地全解析

半监督缺陷检测实战:MemSeg原理、复现与工业仪表落地全解析 做工业质检这些年我最怕听到的需求不是“准确率要做到多少”而是“我们有几千张正常图但只有二十张缺陷图你看着训练”。产线上的缺陷本来就是一桩小概率事件异常样本稀缺是常态不是特例。这种局面下你想要一个能真正落地的缺陷检测模型半监督几乎是唯一现实的选择。MemSeg 就是我在这个方向上实测过的最稳、效果也最夸张的方法之一在 MVTec AD 标准数据集上把图像级 AUROC 刷到了 99% 以上而整个训练过程基本只需要正常样本。这篇文章我把 MemSeg 从原理到复现再到迁移落地的完整路径捋一遍。你如果正在做表面缺陷检测或者刚接触半监督方案、被“没有缺陷样本”卡住那这篇应该能帮你省下大把试错时间。我还会额外补充一份我们团队在压力表、电流表、电压表、温度表、流量计这五类典型工业仪表上的迁移评估记录这部分内容属于典型的“论文里不会写、只有踩过坑才知道”的实战细节建议配套阅读。1. 为什么半监督方案才是工业缺陷检测的“实用选择”1.1 产线数据分布的真实困境先聊清楚“半监督”这三个字在工业缺陷检测里到底什么意思。很多人一听半监督会以为是“拿少量标注缺陷 大量无标注数据一起训练”那是半监督分类的标准定义。但在表面缺陷检测这个场景里MemSeg 这种方法的半监督含义完全不同训练阶段只用正常样本完全不需要人工标注缺陷推理阶段则要把不属于正常分布的异常区域找出来。说白了就是只教模型“什么是好的”它自然会判断“什么是不好的”。为什么工业场景强烈需要这种设定你可以回想一下生产线的真实构成正常品占总量的绝大多数缺陷品的出现频率可能只有千分之几甚至更低。如果走传统的有监督路线你得先攒够几千张包含划痕、污渍、裂纹、变形、异物等各类缺陷的图像还得逐张画像素级标注。先不说标注成本有多高很多缺陷种类在你建模之前根本没见过等到产线上真的出了新型缺陷模型又得重新收集数据、重新训练。这套打法在实验室里行得通在工厂里就是灾难。无监督方案倒是能避开标注问题但它通常默认“只用正常样本训练不做任何额外约束”。问题在于图像里包含的正常结构非常多背景、光照、传感器噪声、正常纹理差异都会干扰判断。模型很容易“过度泛化”把什么输入都看作正常漏检率居高不下。MemSeg 的思路是在纯无监督的框架里注入一个人为构造的监督信号——既然真实缺陷样本难得那就用正常样本自己“拼”出模拟异常让模型在训练时就见过“异常长什么样”。这样既不需要人工标注又能逼着模型学会区分正常和异常落地价值比纯无监督高一个量级。1.2 MemSeg 在同类方案里的位置做工业缺陷检测这几年我印象里相关方案层出不穷。早期像 SPADE、PaDiM 这类基于特征嵌入的算法用预训练网络提取正常样本的 patch 级特征再用马氏距离或最近邻距离判断异常。它们定位能力一般图像级判断还凑合但到了实际产线上经常会碰到误报一堆的情况。后来 PatchCore 出来把“记忆库 特征检索”的思路做到了一个新高度用 coreset 采样来压缩记忆库速度和效果都有明显提升。不过 PatchCore 本质上是把整张图当作一个整体做判别输出的是图像级异常分数想精确定位到像素级别还是有点费劲。MemSeg 走的是另一条路。它同样用到记忆池但不是简单地把特征存下来然后算距离而是把“记忆池检索出来的正常特征”和“输入图像的真实特征”做逐像素级对比同时结合模拟异常生成的监督信号让网络输出一张像素级的异常热力图。这意味着它不仅能告诉你“这张图有问题”还能直接告诉你是哪个区域出了问题。对于表面缺陷检测这种强定位需求的场景这个能力非常实用。从我个人的横向对比经验看如果是只做图像级分拣PatchCore 和 MemSeg 都能胜任但如果后续要接自动切割、缺陷可视化、人工复核定位MemSeg 的输出形式明显更有优势。这也是这篇我重点拆它的原因不光是它 SOTA 的名头而是它在实际工程里的可操作性确实更好。2. MemSeg 核心设计拆解记忆池、模拟异常与多尺度融合2.1 记忆池模块把正常特征“存起来再对比”MemSeg 最核心的模块就是记忆池。你可以把它理解成一个“正常样本特征仓库”把训练集里所有正常图像切分成许多局部区域让预训练骨干网络提取每个区域的特征向量然后统一存进一个池子里。等到推理时输入图像同样会被切成局部 patch每个 patch 的特征都去这个池子里找最相似的一组正常特征再与自身特征做差。这个“找相似”的过程用的是最近邻检索具体距离度量可以是 L2 距离也可以是余弦相似度。如果输入 patch 和记忆池里最相似的正常特征距离很大说明这个 patch 在正常样本里找不到对应物那它大概率属于异常区域如果距离很小说明它长得和正常样本没什么两样可以放心判为正常。听上去很直白但里面有个工程细节值得注意直接存所有训练图像的原始 patch 特征池子会非常大而且多尺度特征一起存的话显存压力非常可观。我复现时第一次把训练集几百张图的所有特征全部丢进池子里单卡 V100 直接爆显存。后来做降采样、控制存储维度才把内存占用压下来。这块我后面“踩坑实录”里会再详细展开。2.2 模拟异常生成没有缺陷样本就用正常样本“造”出差异没有真实缺陷样本监督信号从哪来MemSeg 的答案是让模型自己“制造”异常。论文里提的模拟异常生成策略动手操作起来其实就是两件事——类内交换和类间交换。类内交换很好理解把同一张正常图像切成网格然后把其中某个网格区域的内容挪到另一个位置。打个比方就像你把一张完好的瓷砖照片里一小块纹理抠出来平移粘贴到另一块位置。因为工业表面的纹理通常具有局部一致性挪动之后原位置和新位置之间会出现明显的纹理错位这个“错位”就被当成一个伪异常区域。类间交换更狠一点从同一个训练 batch 里随机拿两张不同的图像把 A 图的一部分区域贴到 B 图的对应区域上。工业品表面即便是同一型号不同个体之间在纹理、光泽、细微色泽上也会有差异把这种差异硬拼进一张图里就制造出一个“局部不像正常样本”的区域。这些模拟出来的伪异常区域会被当作训练监督信号让网络输出在对应位置上产生高响应。关键点在于模拟异常的本质不是让模型背下某几种固定缺陷而是训练模型具备“检测局部不协调性”的能力。真实缺陷虽然形态千奇百怪但它们本质上都是“与周围环境不协调的区域”这个共性被 MemSeg 抓住了。2.3 差异图与共性图两条互补的信息通路有了模拟异常和记忆池检索之后MemSeg 并不只是简单地把“差异大”判定为异常而是设计了两条信息通路一条叫共性图主要关注那些与正常样本高度一致的区域另一条叫差异图专门建模那些与正常特征差距较大的区域。为什么要分两条通路因为单靠差异图直接做阈值判断很容易误伤。比如某些正常区域本身纹理变化就比较大或者光照在局部产生了明暗变化这些区域和记忆池里的特征比对时距离天然偏大如果粗暴地把它判为异常误报率会很高。共性图的存在相当于一个“信任基础”如果一个区域在共性图上的响应也很高说明它虽然与某些正常特征有差异但整体结构还是正常的模型就不会轻易给出异常判定。最后网络会用空间注意力和通道注意力把这两张图的信息融合起来得到一个更稳健的异常分数图。我在实际使用中体会是注意力融合这一步对改善边缘区域的预测尤其明显比简单相加或拼接要好一个档次实际像素级指标能差出 0.5% 到 1%。2.4 损失函数组合与监督信号设计MemSeg 的训练损失不是单一目标而是多个损失组合各管一段。我拆下来大致是三个部分。第一部分是分割损失直接把模拟异常产生的 mask 当作伪标签让网络的异常分数图去拟合这个 mask。因为异常区域在整张图里占的比例很小正负样本极度不平衡所以通常用 Focal Loss 而不是普通的交叉熵。Focal Loss 会让模型更关注那些难以判别的异常区域而不是被大面积正常区域带偏。第二部分是特征相似度损失鼓励从记忆池中检索出的正常特征与输入特征尽量接近相当于约束模型“输出的正常表征不要跑偏”。第三部分是判别损失通过对比学习的方式让正常样本特征和异常样本特征在特征空间里彼此远离增加类间可分性。三部分损失的权重配比需要根据数据集微调。我复现时一开始用默认权重发现在 MVTec AD 的“导管类”和“纹理类”上表现还可以但换到“金属螺母”这类小物体上分割损失权重偏大导致模型对细节过度敏感误报增多。调整权重后效果明显改善。我的建议是在自己的数据集上做一次小范围网格搜索记录图像级 AUROC 和像素级 AUROC 的变化比迷信论文默认值要靠谱得多。3. 从论文到代码复现 MemSeg 的实操记录3.1 环境准备与数据集处理复现 MemSeg 的整体门槛不高比很多发散的方法要友好。官方实现的底层是 PyTorch预训练骨干一般用 EfficientNet 系列。我这边环境是 PyTorch 1.10、CUDA 11.3、单个 V100 或 A100显存 16G 往上比较稳妥。如果显存小后面记忆池很容易成为瓶颈。数据集方面最常用的是 MVTec AD这是工业缺陷检测领域的事实标准包含共计 15 个类别其中物体类有螺丝、胶囊、药片、金属螺母等纹理类有地毯、皮革、木材等。每个类别下面都划分好了 train 和 testtrain 全部都是正常样本test 里混合了正常样本和多种缺陷样本。这个划分方式天然适配 MemSeg 的训练范式拿来评估模型性能非常合适。预处理环节我习惯先把所有图统一 resize 到 256x256然后做标准化再加上随机水平和垂直翻转做训练增强。需要提醒的是MVTec AD 里部分物体类图像本身带有方向性比如螺丝的方向、金属螺母的结构翻转增强时要注意不要过度破坏语义否则会让模型学到错误的“正常模式”。3.2 关键参数与训练配置训练参数这块我踩过一轮坑之后形成了一套自己的基准配置。输入尺寸 256x256batch size 16优化器用 Adam初始学习率设在 1e-3 到 1e-4 之间训练轮次根据数据集大小在 50 到 100 个 epoch 之间调整。骨干网络加载 ImageNet 预训练权重记忆池的特征维度取决于骨干网络各层输出的通道数多尺度特征通常取 3 个尺度层次。记忆池规模需要重点控制。把所有正常训练图的全部 patch 特征都存进去池子大小会到几十万甚至上百万条检索速度和显存都会报警。我实际把每条特征做了 L2 归一化并将池子统一限制在几万条左右通过随机采样或聚类选择代表性特征。这样处理之后推理单张图的最近邻检索耗时能控制在百毫秒量级以内对产线节拍来说勉强够用。训练时间方面MVTec AD 单个类别大概几十分钟到一两个小时就能收敛整体训练成本并不高。这个是 MemSeg 相比很多大模型方法的最大优势部署门槛低迭代速度快。3.3 评估方法图像级与像素级要分开看评估缺陷检测模型光看一个指标是不够的。我一般同时记录图像级 AUROC、像素级 AUROC 和 AP。图像级 AUROC 衡量的是“这张图有没有缺陷”像素级 AUROC 衡量的是“缺陷定位准不准”两者侧重完全不同。MemSeg 官方给出的实验效果在 MVTec AD 上非常抢眼。我印象里它的图像级 AUROC 整体超过 99%像素级 AUROC 大约在 98% 上下在当时的半监督方法里确实领跑了一截。我自己复现时虽然没有完全对齐到论文的每个细节但图像级 AUROC 在多数类别上达到 98% 以上是没问题的效果相当可观。需要特别强调一个评估心得像素级指标高不代表缺陷边缘画得干净。AUROC 只看排序质量不关心预测热力图的前景背景分离是否锐利。真正到了实际落地我反而会额外看几个样本的可视化图确认异常区域的边界形状是否合理。这个细节很多评测榜单不会告诉你但产线验收时往往会卡这一条。4. 迁移到工业仪表场景压力表、电流表、温度表缺陷检测4.1 仪表表面缺陷有哪些MVTec AD 是基准数据集但真实工业项目里我们面对的往往是更具体的东西。最近我们团队接了一个仪表外观检测的试验项目对象包括压力表、电流表、电压表、温度表、流量计这五类常见工业仪表。每一类仪表都有其独特的外观结构表盘、刻度、指针、外壳、玻璃面一应俱全而且表面缺陷类型五花八门表盘玻璃划伤、裂纹、污渍刻度线缺损、模糊指针变形、弯曲外壳破损、锈蚀表盘面印刷不良甚至密封圈老化导致的边缘异常。这类场景为什么特别适合 MemSeg因为仪表型号多、外观差异大但每个型号的正常样本非常容易收集——产线上每台仪表都可以拍照采样。缺陷呢每种缺陷出现的概率极低想攒齐全部缺陷类型是不可能的新型缺陷还时不时冒出来。这正是半监督方案的理想环境用大量正常样本训练让模型自动捕捉任何“不对劲”。4.2 预处理圆表盘定位与 ROI 裁剪仪表图像和 MVTec AD 的标准图像有个显著差异仪表通常是圆形表盘周围还有外壳、背景、支架等大量无关区域。如果直接把整张图丢进模型模型会把外壳纹理、背景光照变化都当作特征学习导致误报率上升。所以第一步必须做定位和裁剪。我们采用的是先检测后裁剪的两段式流程。先用一个简单的目标检测模型或者传统图像处理里的 Hough 圆变换把表盘区域定位出来然后做仿射变换或透视校正把倾斜的表盘拉正最后裁剪出统一的 ROI 区域并缩放到 256x256。这一步做完模型输入里只剩下表盘本身背景干扰基本被排除。数据增强这里有个细节值得单独拎出来说仪表表盘上的指针本身是一个正常结构它有固定的方向和范围。如果训练时对图像做大幅度旋转增强指针位置会变得乱七八糟模型会把“指针不在正常位置”也当成正常这会影响后续对指针区域异常的判断。我的处理方式是只做小角度旋转正负 10 度以内并且保留原始方向的样本占比。4.3 微调与阈值选择模型结构上不需要做任何改动直接复用 MVTec AD 上预训练好的权重然后拿五类仪表各自的正常样本做微调。这里我踩了一个坑一开始我直接对整个网络进行全量微调结果模型对仪表结构过度拟合泛化能力反而下降。后来改成冻结骨干网络的前几层只对高维特征层和记忆池相关部分做 fine-tune效果才稳定下来。阈值选择这块我用的方法很朴素但很有效收集一批正常仪表图像跑完模型后得到每张图的异常分数分布取 99% 分位数作为基础阈值。同时再准备一批带缺陷的测试图看这个阈值下能检出多少缺陷如果漏检严重就把阈值往下调一点直到在漏检率和误报率之间达到可接受的平衡。调阈值一定不能只看单一指标要结合现场对漏检和误报的容忍度来定。4.4 落地效果评估在这一轮内部试验里我们用每种仪表约 2000 张正常图做训练200 张正常图加 100 张带缺陷图做验证另外再留 100 张带缺陷图做测试。最终五类仪表的图像级 AUROC 都在 98% 以上相对容易判断的裂纹、破损类缺陷召回率能做到接近 100%比较难的是刻度线缺损和字体印刷不良这类小面积、低对比度缺陷召回率会掉到 90% 左右。这个结果说明MemSeg 对中大型缺陷的检测已经具备上线的能力对于微小缺陷还需要结合更高分辨率的输入或者额外的局部放大检测模块。推理速度方面单张 256x256 图像在 V100 上从预处理到输出异常分数图大概需要 150 毫秒左右放到 CPU 上会慢不少但产线如果只是抽样检测而不是全量全速检测这个速度完全能接受。如果要做全量高速检测后面可以考虑用 TensorRT 加速或者把记忆池检索部分优化掉。5. 踩坑实录复现和部署 MemSeg 时最常遇到的 5 个问题5.1 记忆池导致显存不够这是复现 MemSeg 时遇到频率最高的问题我也没能幸免。第一次运行把训练集所有正常图像的 patch 特征全部存进记忆池多尺度加在一起池子达到几十万条V100 的 16G 显存直接被撑爆。解决思路不是加显存而是控制池子规模。我最后是先用聚类把特征压缩到几万条同时改用半精度浮点存储显存占用瞬间降了下来。如果还是不够还可以把特征分块存储推理时分批检索再合并结果虽然速度慢一点但内存可控。我记得官方代码里也有类似的可配置参数建议一上来就把池子上限设好不要等到 OOM 再返工。5.2 模型把所有样本都判成正常训练完第一次跑测试发现模型对缺陷图也给出很低的异常分数等于什么也没检测出来。这个问题的原因一般有两个一是训练轮次不够模型还没学会区分正常与模拟异常二是三部分损失的权重失衡分割损失权重太小模型被特征相似度损失主导只顾着把特征拉近忽略了判别异常的任务。我当时的做法是先把分割损失权重调高一个量级再增加训练轮次问题就解决了。还有一个小技巧在训练过程中把模拟异常的可视化结果打印出来看一眼如果 mask 和实际粘贴区域对不上说明数据生成环节出了问题要优先排查。5.3 小缺陷漏检MVTec AD 里像药片表面极小的斑点、仪表刻度线的细微缺损都属于小缺陷。MemSeg 在这类缺陷上偶尔会漏检。我排查下来问题主要出在输入分辨率和多尺度特征的选择上。256x256 输入下一个只有 10 个像素宽的刻度线缺损经过多层下采样后信息已经丢失大半。我的改进方法是把输入分辨率提升到 384 甚至 512同时让记忆池检索时融合更浅层的特征小缺陷的召回率提升非常明显。代价是训练和推理速度变慢实际项目里需要做平衡。5.4 复现指标对不上论文这个问题几乎是所有论文复现者的共同痛点。MVTec AD 上的指标想完全复现到论文水平影响因素非常多随机种子、预训练权重版本、数据预处理顺序、增强策略、损失权重、甚至 PyTorch 版本都可能造成细微差异。我有一次发现指标低了 1% 多排查了半天最后发现是初始化时没有固定随机种子导致记忆池采样结果和论文不一致。另外官方预训练权重的下载渠道也要注意不同渠道的权重可能来自不同训练策略对下游效果影响很大。我的建议是不要追求小数点级别的复现只要在自己数据集上表现稳定、具备可比性就已经达到了工程落地的标准。5.5 推理速度不满足产线节拍MemSeg 推理慢的核心瓶颈在记忆池的最近邻检索。当池子有几万条特征每张图有大量 patch 都要做检索时累积耗时非常可观。我测试下来如果直接暴力计算 L2 距离单张图可能要接近一秒明显跟不上流水线节拍。解决办法是用近似最近邻检索库比如 FAISS把检索耗时降低一个量级精度损失可以控制在可接受范围内。另外记忆池规模前面已经提到要控制每减少一万条特征推理时间都能肉眼可见地下降。如果对实时性要求极高还可以考虑蒸馏一个小模型来替代记忆池检索但这属于比较大的改造工程普通项目不太推荐。5.6 问题速查表常见问题主要表现排查重点解决方向显存不足训练或推理直接 OOM记忆池规模、特征维度、精度类型聚类压缩池子、半精度存储、分块检索全部判正常缺陷图异常分数极低训练轮次、损失权重、模拟异常 mask 准确性增大分割权重、加长训练、检查数据生成小缺陷漏检小尺寸、低对比度缺陷检不出输入分辨率、多尺度特征选择提升分辨率、融合浅层特征指标对不上与论文或其他设备差距明显随机种子、预训练权重、预处理流程固定种子、统一权重来源、统一预处理推理太慢单张推理耗时过长检索算法、池子规模使用 FAISS、压缩记忆池、TensorRT 加速我在实际项目里碰到的问题远不止这五个但这五个最典型基本上排查完一轮模型就能从“能跑”变成“能用了”。如果让我给 MemSeg 的应用场景排个优先级我最推荐的是产线上的外观目检初筛也就是把人工目检前面加一道自动预筛模型判断有异常的先挑出来再审。这类场景对速度不苛刻对漏检的容忍度比误报更低正好是 MemSeg 的优势区。最后再分享一个经验半监督模型的部署不是终点上线之后要不断把新增的正常样本增量地补充进记忆池让模型对产线的真实状态保持跟踪。我见过太多团队模型上线以后就不管了过了半年产线换了新物料、新环境光照模型性能掉得一塌糊涂还浑然不觉。模型也是一台需要持续保养的设备这一点在工业场景里尤其关键。
返回列表