首页 / 资讯中心 / 文章详情

去掉语言约束:纯视觉基础模型如何撑起通用异常检测

去掉语言约束:纯视觉基础模型如何撑起通用异常检测 ★ FEATURED ARTICLE
先说个背景。这两年视觉异常检测领域几乎被“多模态语言”的思路统治了。大家默认用CLIP那类图文模型把类别标签文本和图像特征对齐借此实现少样本甚至零样本的异常检测。这套玩法确实有效尤其在人脸、工业零件、医疗影像几个典型细分上但代价是你不仅要选对文本模板、调提示词还要承受语言分支带来的训练开销和推理延迟。我心里一直有个疑问——这些多模态方案里视觉分支到底贡献了多少如果彻底丢掉语言拿一个纯视觉基础模型硬扛效果会差多少这个项目正是冲着这个问题去的。标题很直接一个去掉语言约束的基础模型One Language-Free Foundation Model就足以支撑通用视觉异常检测。换句话说不看标题里的形容词这个工作的核心其实是一道比较题在COCO类别的通用异常检测任务上纯视觉方案和语言条件方案谁更可靠答案是前者不但没输还在pixel级别和几个少样本设定下有明显优势。下面我把这个项目的思路、实验设计、关键实现和踩坑记录完整复盘一遍供同样想做通用视觉检测或者基础模型应用的朋友参考。1. 项目定位与技术背景1.1 为什么“语言条件”成了主流却未必是真需求先说清楚一个问题为什么视觉异常检测领域会这么依赖CLIP这类多模态模型。核心痛点在于“类别迁移”。传统监督方案训练一个检测器只能管死一类目标换了产品型号、换了纹理你得重新标注、重新训练。零样本场景下人没法标注怎么办CLIP给了个巧妙的路径——把“正常的类型”用自然语言描述出来比如“这是一颗没有划痕的螺丝”然后拿图像特征和文本特征做相似度匹配低于阈值就算异常。文本天然能泛化到没见过的类别概念上确实优雅。但这个优雅背后有坑。文本输入不是免费的。你换一个类别就要重写提示模板分类越细词表越长推理时就得做一整套文本编码器的前向计算显存占用直接翻倍。更要命的是CLIP的视觉特征天生被图像级对齐任务引导过像素级别的细节定位往往不够锐利做pixel级异常分割时总差一口气。所以这个项目的第一层意图很纯粹把语言分支这个“拐杖”拿掉看看纯视觉基础模型能否直接继承CLIP在这类任务上的优势。它的潜在假设是——异常检测本质上靠的是视觉分布偏移而不是语义理解。你不需要模型“认识”这个物体叫什么只需要它知道“这个区域和它见过的正常区域不一样”。而基础模型在大规模无标签图像上预训练之后本身就对分布外特征高度敏感这正是异常检测需要的底层能力。1.2 “一个就够”的含义标题里的One Language-Free Foundation Model有三种理解方式建议看实验时对号入座第一种只用单模型的主干特征不做多模型集成。这在工程部署上最友好一个backbone走到底。第二种在特定设定下比如few-shot只需要一个特征尺度不需要把多层特征全都拉进来照样能打。第三种训练阶段只学一个轻量分类器或度量头不需要额外训练分割网络或生成模型。后面实验设计里这三种含义都有对应验证。理解这一点再看对比表格思路会顺很多。1.3 基准任务的选择逻辑项目没有直接套用常规的工业质检数据集而是把战场设定在了“通用视觉异常检测”上用某通用分割数据集的物体类别当作正常类人工构造类型丰富的异常模式。这样设计的好处是类内形态差异够大同一类别有多张不同视角和背景的图异常的类型覆盖了局部破损、纹理污染、结构置换、遮挡等常见干扰而不是工业场景里单调的划痕或污点。这更贴近“通用”两个字——模型不能靠记忆一条纹理模式来偷鸡。另外base-to-novel类别划分也是这个基准的关键。某个类别一部分样本用于训练/支持另一部分完全不可见用来测试模型能否从见过的类别迁移到没见过的类别。这样才测得出“异常检测能力”本身而不是“对训练集的记忆能力”。2. 核心设计拆解四层实验框架2.1 两个backbone阵营的对比构造整个实验的核心是构造语言条件和纯视觉条件的同台PK变量要尽量控制到单一。项目方案分成了两个阵营方案阵营代表思路语言/文本依赖训练开销多模态基线文本编码器 图像编码器利用提示模板对齐分类语义强依赖换类别就得换描述高需额外维护文本分支纯视觉基线图像特征 线性层或近邻度量只依赖底层统计分布零依赖调类别只换支持集图像低训练一个线性头即可两个阵营在“骨干网络”这一层做了严格统一多模态基线里拆掉文本分支只保留图像塔纯视觉方案也使用同样的图像塔。这样能直接回答一个问题文本分支的引入到底是帮助还是拖累。实验里有几个值得留意的对照组同一骨干开语言条件 vs 关语言条件不同骨干之间语言条件自有的性能差异用零样本 vs few-shot vs 半监督 vs 无监督四个维度分别测。这四组对照跑下来结论会非常立体。只看一个设定下谁高谁低没太大意义关键是看趋势语言条件在哪个设定下增益最大又在哪个设定下失效甚至反噬。2.2 四种设定各自测什么zero-shot正常类和异常类都没见过端到端硬扛。测的是特征本身的通用性和底层分布对齐能力。few-shot每类给少量正常样本如1/2/4张用某种度量方式判断测试样本是否落在正常分布内。贴近真实落地现场没法给太多标注只能拍几张正常品。半监督正常样本充足异常样本缺失或极稀少。这是传统异常检测的经典设定。无监督完全没有正常参考样本纯靠主干网络自身对特征的先验判断。这个最苛刻多数模型在这项上会掉很多分。值得注意的是项目并非只调一个大头而是在四种设定下分别做了完整实验。当前很多零样本异常检测论文只在zero-shot或few-shot上刷分对无监督和半监督一带而过。这套full-stack实验的好处是能清楚看到模型在不同数据条件下的能力边界这对工程选型非常关键——毕竟到了实际项目里你很多时候连“正常样本”都不一定拿得全。2.3 为什么用“线性可分性”来验证骨干特征质量该项目有一个很提气的细节在选择骨干模型之前先做了一个特征质量预筛判断方式是线性探测linear probing。逻辑很简单——如果一个backbone的特征足够好那么正常和异常样本在特征空间里应该是线性可分的不需要复杂的分割网络或密度估计器来弥补特征本身的不足。如果线性分类器在这个特征上已经能跑出不低的分说明特征本身携带了足够多的判别信息如果线性分很低那就算后面接再复杂的头也大概率是费力不讨好。这个预筛思路值得所有人抄作业。很多同学做异常检测上来就堆逻辑复杂的模型不太看特征本身质量。我用类似方法测过几个常见骨干差异非常明显同一个数据集上不同backbone的线性探测结果可能差10个点以上。特征先不行后面全是占用显存的装饰。3. 模型选型分析与关键对比3.1 参评骨干型号及选型原因用于对比的基础模型有好几类这里我挑几个有代表性的展开多模态基础模型X代表CLIP那一路操作含文本和图像双塔。实验时拆成纯视觉来使用验证“去掉语言分支”对同一套视觉塔是损失还是增益。自监督视觉模型Y基于全局-局部特征互信息约束训练的ViT对比学习式的代表。以细粒度局部特征见长。视觉基础模型Z面向密集预测任务设计特征图保留空间细节更充分在小物体和边缘纹理上优势明显。老牌卷积骨干W传统ImageNet预训练的ResNet类特征作为经典基线帮大家锚定“现代基础模型到底进步了多少”。为什么选这几个目的是拉开特征类型差异多模态对齐特征、自监督全局特征、密集预测特征、传统分类特征。一个方案在不同性质的特征上表现如何直接反映它对骨干的依赖度。如果一个方案只能在自家调过的骨干上有效换个backbone就崩那论文价值和落地价值都得打折扣。3.2 跑分结果里的三个重要信号我根据项目公开的对比数据整理了一张简化版结果对照表分数做归一化处理值越高越好骨干类型Zero-shot检测Few-shot4-shot像素级分割语言分支额外增益多模态模型纯视觉塔高中高中有但不明显自监督ViT中高高中高无纯视觉本身更强密集预测型ViT高高高几乎为负传统卷积低中低有但依赖提示词从这张表能拎出三个关键信号第一个信号在强视觉骨干上加文本分支不总能带来正收益。某密集预测型ViT在加入文本条件后部分类别上反而下降了1~3个点。我估计原因在于CLIP的文本对齐过程会把视觉特征往“语义中心”方向拉这个拉拽过程会导致边缘细节和异常局部模式的丢失。纯视觉特征没有这层约束反而保留了更完整的低频和高频信息。第二个信号像素级异常分割场景里语言分支的增益弱到可以忽略。原因很好理解文本标签是图像级的要拿图像级监督去指导像素级任务中间隔着一道鸿沟。而纯视觉骨干的特征图天然保留空间位置信息做pixel级判别时天然更顺。第三个信号few-shot场景下近邻度量类方法在纯视觉特征上表现尤其好。因为自监督模型的特征空间本身就具备聚类性正常样本之间靠得近异常样本自然离得远不需要再学一个复杂的距离度量。3.3 这组结果说明了什么结论直接去掉语言约束的纯视觉Foundation Model在通用视觉异常检测任务上完全够用部分场景更强。这不是说多模态没用而是提醒我们多模态方案的优势是有适用边界的——它对“类别语义”的先验有帮助但异常检测本质上更需要“像素级分布偏移感知”后者的核心能力在视觉塔内部而不是在文本分支里。这也是这个项目标题最扎实的地方One Language-Free Foundation Model Is Enough观点鲜明但不靠嘴硬靠实验范围和统计趋势撑起来。4. 实操复现要点与关键配置4.1 面向复现的完整流程如果想把方案跑在自己的数据上我建议按以下步骤来这条路我跑通过第1步骨干特征抽取输入图像先统一做尺寸归一化短边至少256长边不超过512然后经过主干网络取最后一层CLS token或空间特征图。注意不同骨干的输出结构不同ViT类骨干取[CLS] token做图像级异常得分取最后一层patch token做像素级得分。卷积类骨干取最后一层feature map做全局池化后得到图像级特征。第2步图像级异常得分计算拿测试图像特征和正常参考特征做余弦相似度得分取“1 - 最大相似度”值越高越异常。正常参考特征怎么构建如果在zero-shot设定下直接拿骨干在某个通用正常类别集上得到的特征均值或特征集合当参考锚点如果在few-shot设定下就是当前类别的那几张支持图的特征。第3步像素级异常图生成把test图像的patch token拽出来和所有正常支持图的patch token做逐位置比对每个patch位置取最近邻距离得到一个空间距离图。然后把这个距离图上采样回原图尺寸用高斯模糊稍微平滑一下得到异常热力图。第4步评估与阈值选择图像级AUROC和像素级AUROC都会用到。大部分情况下像素级AUROC更能反映真实工业误检情况。选阈值时别直接套0.5推荐用验证集拟合最佳F1对应的阈值或者按业务可容忍的误检率反推。4.2 backbone选择的实操清单使用场景推荐骨干类型理由通用物体、类别跨度大密集预测型ViT空间细节保留好像素级分割强工业质检、纹理类异常自监督ViT聚类性好few-shot下近邻度量可靠类别语义强、需要快速部署多模态模型纯视觉塔预训练语料丰富零样本泛化在线资源受限、推理延迟敏感传统卷积轻量版部署生态成熟但性能确实有上限我的个人经验是如果任务没有强语义需求默认先跑自监督ViT和密集预测型ViT别一上来就上多模态全家桶。省下的显存和时间足够你把数据侧做扎实。4.3 一套默认参数配置参考下面给一组我调通实验时的默认配置属于中等偏保守的参数# 数据相关 image_size: 384 batch_size: 32 normal_ref_num: 8 # 每类正常参考图数量 # 骨干网络相关 backbone: dino_v2_base # 替换成你自己的骨干即可 feature_layer: last # 取最后一层特征 pooling: cls_token # 图像级特征用CLS # 度量相关 metric: cosine_similarity pixel_metric: knn_distance knn_k: 3 smooth_sigma: 4 # 训练相关如果涉及线性层 epochs: 50 lr: 0.001 optimizer: adamw这里唯一需要你根据数据调的是image_size和normal_ref_num。图像里目标占比小就把尺寸调大文本类纹理异常占比高就适当减少参考图数量因为参考太多会把正常分布的边界撑宽导致漏检。4.4 训练阶段的一个重点坑我在复现时踩到过一个经典坑特征图直接用原分辨率做最近邻显存直接爆炸。比如说384×384输入patch size 14特征图是27×27×768单张图就有729个patch。few-shot下还得分Batch计算一个Batch 16张图就是11664个patch再算KNN距离矩阵显存很容易扛不住。解决办法很简单先对patch token做空间降维。直接对特征图做一次2×2平均池化patch数缩到四分之一异常定位精度几乎不掉但显存占用直接减半。工业场景里异常区域通常也不至于小到一个patch都覆盖不到除非你的异常就是几个像素级别的针孔那另说。5. 实验中的关键技术点拆解5.1 线性可分性为什么值得单独说话上面提到线性探测预筛这里展开讲一下。普通分类头在特征后面接非线性MLP多层非线性激活网络能强行记住训练集里的分布模式但你不好判断到底特征是真好还是头在硬凑。线性探测相当于把复杂头摘掉只留一层线性变换这个条件下模型还能有高准确率才能说明特征本身干净、线性可分程度高。这个项目里骨干特征的好坏直接决定后续方案上限。我后来在自己的一个工业检测场景里也套了这套预筛流程拿到一批候选骨干后先跑linear probe效果差的直接踢掉节省了大量训练时间。5.2 近邻度量 vs 密度估计方案里用的核心度量思路偏向“匹配/近邻”不是学一个概率密度模型。这点也可以展开说远一点——我们为什么会选匹配而不是密度估计。概率密度估计的常规做法是拟合正常样本的分布函数比如高斯混合模型、归一化流等然后对测试样本算概率密度密度低于阈值判异常。这个方法理论优美但有几个现实问题特征维度一高密度估计就困难ViT特征动辄768维甚至1024维在这个维度上算密度样本量不够时结果方差极大。近邻度量则不需要假设分布形式直接在特征空间里量距离简单、稳、调参少reset条件也特别快。代价是它不是参数化的没法显式建模“正常”的边界只能靠参考样本的分布密度间接体现。但这在实际工业质检项目里反而够用——你总是能先拍一批正常品照片当参考集这比收集异常样本容易太多了。5.3 像素级 vs 图像级谁先谁后项目里给出的实验顺序非常明确先验证图像级检测稳定后再扩展到像素级。这个次序在工程落地时很有指导意义。图像级得分异常往往是因为整张图像里有大块结构变化遮挡、替换、大面积纹理断裂而像素级得分异常通常是局部小缺陷划痕、脏污、边缘破损。如果项目只做“有没有问题”的粗筛图像级够了如果还要给现场工人指出来“问题在哪里”就得上像素级。两者背后的特征依赖不同图像级对全局语义更敏感像素级对局部细节更敏感。这也是为什么同一骨干在不同设定下会拉开差距——部分骨干的CLS token空间细节保留不足但patch token足够锐利。5.4 类别迁移的验证方式该项目在评估时留了一个重要的操作训练/支持集只包含部分类别测试时加入没见过的类别。实际实现方式是在每轮实验前把类别集合按一定比例划分成base集合和novel集合。比如190个类别其中150类作为base40类作为novel。然后有两种评测base类别的异常检测训练时有参考观察常规设定下的性能novel类别的异常检测训练时没有参考观察零样本泛化的能力。如果模型在novel类别上的得分不掉说明骨干特征是通用模式而不是记住了base类的表面纹理。这也是区分“记忆”和“能力”的试金石。我个人跑下来观察到一个规律特征通用性越强novel类别的表现和base类别表现差距越小。那些在base上刷到很高分但novel上掉很多的模型往往是靠高频纹理记忆硬刚等换一个表面材质就露馅。6. 常见问题与排查实录6.1 异常分数在正常样本上也偏高现象正常测试样本的异常得分和异常样本的异常得分没有拉开差距。排查路径先检查特征预处理顺序图像是否归一化通道顺序是否一致训练和推理时的尺寸是否统一。再检查参考集是不是误把异常样本混进了参考集。参考集只用正常样本这是铁律哪怕混入一张带轻度污染的图整个特征空间的中心都会被带偏异常得分分布直接毁了。最后检查骨干是不是特征层选错了。部分骨干前几层特征是通用边缘纹理后几层才具备较强的语义聚类度。取错层区分度会直线下降。6.2 小目标异常检测不出来现象像素级热力图在大面积异常上有效但小面积缺陷漏检严重。排查后的解决方案很简单提高输入分辨率。384→512甚至640对小目标改善极明显别暴力resize先做保持长宽比的resize再padding到目标尺寸。否则细长型目标的比例形变会导致特征失真融合多层特征。底层特征分辨率高但语义弱顶层特征语义强但分辨率低两层特征按通道concat或用加法融合能取长补短。6.3 同类别内正常样本形态差异太大现象同一类别的正常样本之间差异很大比如不同姿态、光照下的同一种零件模型把很多正常样本判为异常误检率高。这个问题很难直接靠调参解决。我建议从数据侧下手按拍摄角度或光照条件把正常样本分成几个子簇每个子簇单独建参考集测试时先判断样本属于哪个子簇再对子簇内部算异常得分。这类“参考集聚类”操作对缓解类内差异非常管用而且实现成本很低用KMeans聚类特征即可不需要额外训练。6.4 分数阈值怎么定才合理经验做法是不要用固定阈值。先做一个小的验证集里面正常和异常各一半异常可以就用公开数据合成一部分在这个验证集上扫一遍阈值画出PR曲线或者ROC曲线选目标误检率对应的阈值点。部署时再按这个阈值做判断。如果项目处于零样本设定没法拿验证集那就只能按业务侧的需求来——宁可误检率高一点也要保证漏检率足够低。这时候把阈值往“更宽松”的方向调让更多样本落入异常判定区间人工二次确认兜底。这个思路在生产环境里很常见。7. 基于复现经验的方法论沉淀7.1 给想复现这个方案的人一份路线建议如果想完整复现这个项目我建议按时间线分三步第一步花1到2天跑通骨干特征与近邻度量的最小流程先别管像素级只算图像级AUROC目标是达到项目论文里同协议下基准分数的九成。这一步能验证你的环境、数据、评估代码对不对。第二步接入像素级评估。准备带像素级标注的测试集计算patch级距离图生成热力图跑AUROC。注意不需要把热力图做得太好看评估指标才是唯一质量标尺。第三步跑对比实验。把多模态模型加入对照组用相同特征和相同评估协议看实验结果是否和论文趋势一致。这一步不仅为了验证也为了让你自己的项目心里有底知道该押注哪条技术路线。7.2 对“基础模型选型”更长线的思考说句可能会被吐槽的话——我觉得异常检测这个任务未来两三年的主线未必是继续堆模型组合和复杂逻辑而是把基础模型本身的先验能力用透。语言条件在多模态场景里确实是优秀的外挂但它不等于异常检测的充分条件。这个项目用实验把这件事说清楚了价值在于帮大家省掉很多无效调参和算力浪费。挑基础模型时我现在的判断标准很简单就三条特征在“语义上有聚类度”同类正常样本要聚拢特征在“空间上有保留度”patch级特征不能丢掉边缘和纹理细节特征对分布外数据要“敏感”这在预训练阶段就基本注定了后期不太能训出来。这也是自监督密集预测类模型在这个场景里脱颖而出的原因。它们往往同时满足这三条而传统分类模型通常只满足第一条。7.3 一个小成本、高回报的扩展方向如果把这套方案往业务里推我建议优先加一个轻量级的东西异常类别聚类。就是拿异常分数高的样本特征再做一次无监督聚类按失败模式分组。工业项目里这个功能价值巨大——很多缺陷类型你事前根本想不到聚类之后直接得到“哪类缺陷发生最多”的分布方便指导产线提前做干预。做法也不复杂测试时把判为异常的样本保存下来攒一批后提取特征跑KMeans或HDBSCAN然后把每个簇的代表图打印出来给现场人员看。这个“自动失败模式分组”能力可能是整个方案里最让业务方眼前一亮的功能。8. 写在最后的几句实在话我自己复现这个方案的过程中最深的一个感受是——很多视觉任务的瓶颈不在模型设计而在对基础模型能力的理解和评估方式。这个项目最大的价值不是创造了一个新网络结构而是用一套严谨的对比实验帮大家确认了一件事纯视觉基础模型已经足够撑起通用视觉异常检测语言分支是锦上添花不是雪中送炭。如果你正在做零样本或少样本异常检测相关的调研我建议你直接把这套“线性探测预筛近邻度量评估多设定交叉验证”的路子当成自己的标准流程。先不看模型的工程复杂度先看特征质量再决定要不要上复杂结构。这套方法论至少能帮你砍掉一半不必要的对比实验并且更容易找到真正有效的方案。
阅读完成 · 觉得有帮助?
咨询建站