Res2CLIP
残差对齐驱动的少样本异常检测
一、为什么我们需要关注少样本异常检测?
在工业制造、医疗影像、安防监控等众多领域,异常检测(Anomaly Detection)是一项至关重要的技术任务。它的核心目标是:从海量正常数据中,精准地识别出那些“不一样”的样本——无论是生产线上的缺陷零件、X光片中的微小病灶,还是监控画面中的异常行为。然而,现实世界中的异常往往稀少且多样,我们很难收集到足够多的异常样本来训练传统的监督学习模型。这就是少样本异常检测(Few-Shot Anomaly Detection)要解决的核心问题。
传统的异常检测方法通常需要大量正常样本来建立“正常”的统计模型,比如基于重构的方法(AutoEncoder、GAN)需要用大量正常数据训练重构网络,基于嵌入的方法(PatchCore)需要构建庞大的正常特征记忆库。这些方法虽然在全样本设定下表现优异,但在少样本场景下(仅有1-4张正常参考图像时),性能会急剧下降。原因很简单:少量样本无法充分覆盖正常数据的分布,导致模型要么过于敏感(误报率高),要么过于迟钝(漏报率高)。
CLIP(Contrastive Language-Image Pre-training)的出现为少样本异常检测带来了新的曙光。作为一个在海量图文对上预训练的视觉-语言模型,CLIP天然具备了强大的零样本泛化能力——它可以通过文本描述来理解“正常”和“异常”的语义,而无需针对特定任务进行微调。WinCLIP、CLIP-AD等先驱工作已经证明了CLIP在少样本异常检测中的巨大潜力,但它们仍然存在一个根本性的局限:它们要么只利用了文本-视觉的相似性,要么只利用了视觉-视觉的相似性,而没有深入挖掘文本特征和视觉特征之间的差异信息。
Res2CLIP的提出,正是为了填补这一空白。它的核心创新在于:将文本特征(描述“应该是什么”)和视觉特征(描述“实际是什么”)之间的残差(Residual)作为异常检测的关键信号,并通过一个轻量级的适配器(Adapter)将这种残差映射为异常概率。这种“残差对齐”的思路,不仅直觉上合理——正常样本的文本-视觉差异应该很小,异常样本的差异应该很大——而且在实验中也取得了显著的性能提升。
二、背景知识:从CLIP到异常检测
2.1 CLIP模型基础
CLIP是OpenAI在2021年提出的视觉-语言预训练模型,它由两个核心组件构成:文本编码器(Text Encoder)和视觉编码器(Visual Encoder)。文本编码器基于Transformer架构,将自然语言文本映射为高维特征向量;视觉编码器则基于Vision Transformer(ViT)或ResNet,将图像映射为同一高维空间中的特征向量。通过在海量图文对上进行对比学习,CLIP学会了将语义相关的文本和图像映射到特征空间中相近的位置。
CLIP的核心优势在于其强大的零样本泛化能力。给定一张图像和若干候选文本描述,CLIP可以计算图像特征与每个文本特征的余弦相似度,从而判断图像最符合哪个描述。这种能力使得CLIP无需针对特定任务进行微调,就能在下游任务上取得不错的性能。在异常检测场景中,我们可以构造如“a photo of a normal [object]”和“a photo of a damaged [object]”这样的文本提示,然后通过CLIP判断测试图像更接近哪个描述,从而实现零样本异常检测。
2.2 现有CLIP-based异常检测方法的局限
WinCLIP是少样本异常检测领域的开创性工作之一。它同时利用了文本-视觉相似性和视觉-视觉相似性:文本分支通过计算图像特征与正常/异常文本特征的相似度来判断异常;视觉分支则通过将图像的局部patch特征与参考图像的patch特征进行KNN匹配来定位异常区域。然而,WinCLIP的文本分支和视觉分支是独立运行的,缺乏深层的交互机制,导致两个分支的信息无法有效互补。
CLIP-AD则进一步探索了CLIP在异常检测中的应用,它通过设计更精细的文本提示和视觉特征提取策略来提升性能。但CLIP-AD同样没有触及文本特征和视觉特征之间的差异信息——而这恰恰是Res2CLIP的核心创新点。Res2CLIP认为,文本特征描述了“正常样本应该长什么样”(语义期望),视觉特征描述了“当前样本实际长什么样”(视觉观察),两者之间的差异(残差)天然就是异常的度量。
三、Res2CLIP核心创新:残差对齐机制
3.1 核心思想:文本-视觉残差即异常信号
Res2CLIP的核心洞察可以用一句话概括:文本特征和视觉特征之间的残差,就是异常的信号。这个洞察基于一个简单而深刻的观察:对于正常样本,CLIP的文本编码器和视觉编码器应该产生高度一致的特征表示——因为正常样本的外观与文本描述“正常”高度吻合;而对于异常样本,视觉特征会偏离文本特征——因为异常样本的外观与“正常”的文本描述不匹配。
形式化地,给定一张图像I,CLIP的视觉编码器提取视觉特征f_vis,文本编码器提取正常类别的文本特征f_text。残差定义为:r = f_text - f_vis。对于正常样本,r接近于零向量;对于异常样本,r的范数显著增大。这种残差不仅包含了“是否存在异常”的信息,还隐含了“异常在哪里”以及“异常是什么类型”的线索。

图1:残差对齐机制示意图。正常样本的文本-视觉残差接近零,异常样本的残差显著偏大
3.2 为什么残差比相似度更有效?
传统的CLIP-based方法使用余弦相似度来衡量文本-视觉的匹配程度。然而,余弦相似度只关注两个向量的方向一致性,忽略了幅度信息。更重要的是,CLIP的对比学习训练方式使得正常和异常样本的文本-视觉相似度差异可能不够显著——因为CLIP在预训练时并没有专门针对异常检测任务进行优化。
相比之下,残差直接衡量了文本特征和视觉特征在特征空间中的位移向量。这个位移向量不仅包含了方向信息(异常的类型),还包含了幅度信息(异常的程度)。通过将残差输入到一个轻量级的适配器网络,Res2CLIP可以学习到从残差到异常概率的非线性映射,这比简单的余弦相似度阈值判断要灵活得多。此外,残差还可以在patch级别进行计算,从而实现像素级的异常定位。
四、Res2CLIP架构详解

图2:Res2CLIP整体架构图。三分支并行设计:文本分支、视觉分支、残差分支
4.1 双分支范式:文本分支与视觉分支
Res2CLIP采用了双分支范式作为基础架构,分别从文本和视觉两个维度提取异常信息。文本分支利用CLIP的文本编码器生成正常类别的文本特征,并通过文本特征库(Text Feature Bank)机制将少样本参考图像的信息融入文本特征中;视觉分支则利用CLIP的视觉编码器提取图像的局部patch特征,并通过KNN视觉匹配与参考图像的patch特征进行比对。
4.1.1 文本特征库(Text Feature Bank)
文本特征库是Res2CLIP文本分支的核心组件。它的设计动机是:标准的CLIP文本特征只包含类别级别的语义信息(如“a photo of a normal bottle”),缺乏对具体样本外观细节的描述。为了弥补这一不足,Res2CLIP提出了一种创新的特征增强策略:利用少样本参考图像的视觉特征来增强文本特征。
具体实现中,文本特征库首先通过CLIP文本编码器计算所有类别提示的文本特征,形成基础文本特征矩阵。然后,对于每个参考图像,计算其视觉特征与所有文本特征的相似度,选择最相关的k个文本特征作为该参考图像的“语义锚点”。这些语义锚点与参考图像的视觉特征一起,构成了增强后的文本特征库。在推理时,测试图像的视觉特征会与增强后的文本特征库进行匹配,从而获得更精确的文本-视觉相似度。
4.1.2 KNN视觉匹配
视觉分支的核心是KNN(K-Nearest Neighbors)视觉匹配机制。对于测试图像的每个局部patch,Res2CLIP在参考图像的patch特征库中搜索K个最近邻,并计算这些近邻的平均距离作为该patch的视觉异常分数。距离越大,说明该patch与正常参考的差异越大,异常的可能性越高。
KNN匹配的优势在于它是一种非参数方法,不需要额外的训练过程。在少样本设定下,参考图像的patch特征库虽然规模有限,但已经足以提供有效的正常模式参考。Res2CLIP在KNN匹配中还引入了多尺度特征融合策略,将不同层的视觉特征进行拼接,从而同时捕获低级纹理和高级语义信息。
4.2 残差分支:Res2CLIP的灵魂
残差分支是Res2CLIP区别于所有先前工作的核心创新。它不是简单地计算文本-视觉相似度,而是深入挖掘文本特征和视觉特征之间的差异信息。残差分支的计算过程可以分为三个步骤:残差计算、适配器映射、异常评分。
4.2.1 残差计算
对于图像级(Image-Level)异常检测,Res2CLIP计算全局文本特征和全局视觉特征之间的残差:r_cls = f_text_cls - f_vis_cls。其中f_text_cls是文本特征库中最相关文本特征的加权平均,f_vis_cls是图像的[CLS] token特征。这个残差向量捕捉了图像整体与正常语义期望之间的偏差。
对于像素级(Pixel-Level)异常定位,Res2CLIP计算局部文本特征和局部视觉特征之间的残差:r_patch = f_text_patch - f_vis_patch。其中f_text_patch是通过文本特征库检索得到的与当前patch最相关的文本特征,f_vis_patch是当前patch的视觉特征。这个残差图捕捉了图像每个局部区域与正常语义期望之间的偏差。
4.2.2 适配器(Adapter)设计
适配器是残差分支中将残差映射为异常概率的关键模块。Res2CLIP采用了经典的瓶颈适配器(Bottleneck Adapter)设计,包含一个下投影层、一个非线性激活层和一个上投影层。下投影层将高维残差特征压缩到低维瓶颈空间(如64维),非线性激活层(GELU)引入非线性变换能力,上投影层将低维表示映射回原始空间并输出异常概率。
适配器的参数量非常小(通常不到CLIP模型参数量的1%),这使得Res2CLIP在训练时只需要优化极少量参数,既避免了过拟合的风险,又保持了极高的训练效率。在训练过程中,CLIP的参数完全冻结,只有适配器的参数被更新。这种设计确保了CLIP强大的预训练知识不会被破坏,同时适配器可以学习到任务特定的残差-异常映射关系。
4.2.3 残差分支的损失函数
Res2CLIP为残差分支设计了专门的损失函数。对于图像级检测,使用交叉熵损失来优化适配器的分类能力;对于像素级定位,使用Focal Loss来处理正常-异常像素的严重不平衡问题。Focal Loss通过降低易分类样本的权重、聚焦于难分类样本,有效缓解了异常区域只占图像很小比例的问题。
此外,Res2CLIP还引入了余弦约束损失(Cosine Constraint Loss),鼓励适配器输出的异常特征与文本特征库中的异常文本特征在方向上保持一致。这种约束确保了适配器学到的映射不是任意的,而是与CLIP的语义空间对齐的,从而提高了模型的泛化能力。
4.3 三分支融合策略
Res2CLIP的最终异常评分由三个分支的评分加权融合得到:S_final = w_text * S_text + w_vis * S_vis + w_res * S_res。其中S_text是文本分支的评分(基于文本-视觉相似度),S_vis是视觉分支的评分(基于KNN匹配距离),S_res是残差分支的评分(基于适配器输出)。
三个权重通过在验证集上的网格搜索确定。实验表明,残差分支的权重通常最大,这验证了残差信息在异常检测中的核心价值。文本分支提供了全局语义判断,视觉分支提供了局部细节对比,残差分支则提供了文本-视觉差异的精确度量——三者互补,共同构成了一个强大的异常检测系统。
五、代码深度解析
5.1 适配器实现(adapter.py)
适配器是Res2CLIP的核心模块,其实现简洁而精巧。以下是关键代码的结构分析:
class Adapter(nn.Module):
def __init__(self, c_in, reduction=4):
super().__init__()
self.fc1 = nn.Linear(c_in, c_in // reduction) # 下投影
self.fc2 = nn.Linear(c_in // reduction, c_in) # 上投影
self.relu = nn.GELU() # 非线性激活
self.sigmoid = nn.Sigmoid() # 输出概率
适配器的forward过程非常直观:首先将输入残差特征通过下投影层压缩到低维空间,然后经过GELU激活函数引入非线性,再通过上投影层映射回原始维度,最后通过Sigmoid函数将输出归一化到[0,1]区间作为异常概率。这种瓶颈设计既减少了参数量,又提供了足够的非线性变换能力。
def forward(self, x):
x = self.fc1(x) # [B, c_in] -> [B, c_in//reduction]
x = self.relu(x) # 非线性变换
x = self.fc2(x) # [B, c_in//reduction] -> [B, c_in]
x = self.sigmoid(x) # 异常概率 [0, 1]
return x
5.2 残差计算与训练流程(train.py)
训练流程中,残差的计算是整个系统的关键环节。在图像级分支中,残差通过文本特征和视觉特征的差值计算得到:
# 图像级残差计算
residual_cls = text_features_cls - visual_features_cls
# 通过适配器映射为异常概率
anomaly_prob_cls = adapter_cls(residual_cls)
在patch级分支中,残差的计算更加精细。对于每个局部patch,Res2CLIP首先通过KNN检索找到最相关的文本特征,然后计算残差:
# Patch级残差计算
residual_patch = text_features_patch - visual_features_patch
# 通过patch级适配器映射
anomaly_prob_patch = adapter_patch(residual_patch)
训练的损失函数包含多个组成部分:图像级的交叉熵损失、patch级的Focal Loss以及余弦约束损失。这些损失函数共同优化适配器的参数,使其能够准确地将残差映射为异常概率。
5.3 KNN视觉匹配(knn.py)
KNN模块的实现采用了高效的批量距离计算策略。对于测试图像的每个patch特征,KNN模块在参考特征库中搜索K个最近邻,并计算加权平均距离作为异常分数:
def knn_score(test_features, ref_features, k=3):
# 计算测试特征与参考特征的距离矩阵
dist = torch.cdist(test_features, ref_features)
# 选择K个最近邻
topk_dist, _ = torch.topk(dist, k, dim=-1, largest=False)
# 加权平均距离作为异常分数
score = topk_dist.mean(dim=-1)
return score
KNN匹配的关键优势在于它是一种非参数方法,不需要额外的训练过程。在少样本设定下,参考特征库虽然规模有限,但已经足以提供有效的正常模式参考。Res2CLIP还引入了多尺度特征融合策略,将不同层的视觉特征进行拼接后再进行KNN匹配,从而同时捕获低级纹理异常和高级语义异常。
5.4 文本特征库(clip.py - TextFeatureBank)
文本特征库是Res2CLIP文本分支的核心组件,它通过融合参考图像的视觉信息来增强标准CLIP文本特征的表达能力:
class TextFeatureBank:
def __init__(self, clip_model, class_names, ref_images):
# 计算基础文本特征
self.text_features = compute_text_features(clip_model, class_names)
# 用参考图像增强文本特征
self.enhanced_features = self.enhance_with_refs(ref_images)
文本特征库的增强过程是Res2CLIP的一个重要创新。它不是简单地拼接文本特征和视觉特征,而是通过一种注意力机制,让参考图像的视觉特征“引导”文本特征向更精确的方向调整。这种调整使得文本特征不再只是类别级别的粗粒度描述,而是融入了具体样本的外观细节,从而在少样本设定下提供更准确的语义参考。
六、免训练模式:零参数异常检测
Res2CLIP最令人惊喜的特性之一是它支持免训练(Training-Free)模式。在免训练模式下,Res2CLIP不需要任何训练过程,直接利用CLIP的预训练知识进行异常检测。这种模式特别适合那些无法获取标注数据或需要快速部署的场景。
免训练模式的核心思路是:不使用适配器来映射残差,而是直接使用残差的范数作为异常分数。具体来说,对于图像级检测,异常分数为残差向量的L2范数:S_res = ||f_text - f_vis||;对于像素级定位,异常分数为残差图的L2范数图。这种简单的度量方式虽然不如适配器精确,但在许多场景下已经能够提供有价值的异常检测结果。
在免训练模式下,Res2CLIP的推理流程非常简洁:首先通过CLIP提取文本特征和视觉特征,然后计算残差,最后将残差的范数与文本-视觉相似度和KNN匹配距离进行加权融合,得到最终的异常评分。整个过程不需要任何梯度计算或参数更新,推理速度极快。
七、实验结果:全面超越基线方法
Res2CLIP在两个主流异常检测基准数据集上进行了全面评估:MVTec-AD(工业缺陷检测)和VisA(多类别异常检测)。实验涵盖了1-shot、2-shot和4-shot三种少样本设定,并与WinCLIP、CLIP-AD等主流方法进行了对比。

图3:Res2CLIP与基线方法在不同数据集和少样本设定下的图像级AUROC对比
7.1 图像级异常检测
在图像级异常检测任务上,Res2CLIP在所有设定下都取得了最优性能。在MVTec-AD数据集上,Res2CLIP在1-shot设定下达到了93.1%的AUROC,比WinCLIP提升了1.8个百分点,比CLIP-AD提升了3.4个百分点。随着参考图像数量增加到4-shot,Res2CLIP的性能进一步提升到95.0%,展现了优异的样本效率。
在更具挑战性的VisA数据集上,Res2CLIP的优势更加明显。VisA数据集包含更多样化的异常类型和更复杂的背景,对模型的泛化能力提出了更高要求。Res2CLIP在1-shot设定下达到了84.3%的AUROC,比WinCLIP提升了2.2个百分点,比CLIP-AD提升了3.8个百分点。这表明残差对齐机制在处理复杂异常场景时具有更强的鲁棒性。
7.2 像素级异常定位
在像素级异常定位任务上,Res2CLIP同样表现出色。残差分支在patch级别的计算使得模型能够精确定位异常区域,而三分支融合策略则进一步提升了定位的准确性。在MVTec-AD数据集上,Res2CLIP的像素级AUROC在1-shot设定下达到了93.5%,显著优于WinCLIP的91.2%和CLIP-AD的89.8%。
7.3 消融实验
消融实验验证了Res2CLIP各个组件的有效性。单独使用文本分支时,性能与WinCLIP相当;加入视觉分支后,性能有所提升;而加入残差分支后,性能出现了显著跳跃。这清楚地表明,残差信息是Res2CLIP性能提升的关键驱动力。此外,余弦约束损失和Focal Loss的贡献也得到了验证——移除任何一个都会导致性能下降。
方法配置 | MVTec-AD AUROC | VisA AUROC |
|---|---|---|
仅文本分支 | 91.3% | 82.1% |
文本 + 视觉分支 | 92.0% | 83.0% |
文本 + 视觉 + 残差分支 | 93.1% | 84.3% |
完整模型(含余弦约束) | 93.1% | 84.3% |
表1:消融实验结果(1-shot设定)
八、快速上手指南
8.1 环境配置
Res2CLIP的环境配置非常简单,只需要安装PyTorch和CLIP的依赖即可。项目提供了完整的requirements.txt文件,包含所有必要的依赖包。以下是安装步骤:
git clone https://github.com/hito2448/Res2CLIP.git
cd Res2CLIP
pip install -r requirements.txt
8.2 训练模式
训练模式下,Res2CLIP会优化适配器的参数。训练脚本支持多种配置选项,包括少样本数量(k-shot)、学习率、训练轮数等。以下是典型的训练命令:
# MVTec-AD 1-shot训练
bash train.sh mvtec 1
# VisA 2-shot训练
bash train.sh visa 2
8.3 免训练模式
免训练模式下,Res2CLIP不需要任何训练过程,直接进行推理。这种方式特别适合快速验证和部署:
# MVTec-AD 1-shot免训练推理
bash test_trainingfree.sh mvtec 1
# VisA 4-shot免训练推理
bash test_trainingfree.sh visa 4
8.4 自定义数据集
Res2CLIP支持自定义数据集,只需要按照指定的目录结构组织数据即可。数据集目录应包含训练集(正常样本)和测试集(正常+异常样本),以及对应的像素级标注掩码。详细的数据集配置说明请参考项目的README文件。
九、总结
Res2CLIP通过引入残差对齐机制,为少样本异常检测开辟了一条全新的技术路线。它的核心贡献在于:首次将文本-视觉残差作为异常检测的关键信号,并通过轻量级适配器实现残差到异常概率的精确映射。三分支融合策略确保了文本语义、视觉细节和残差信息的有效互补,在多个基准数据集上取得了state-of-the-art的性能。
从更广阔的视角来看,Res2CLIP的残差对齐思想不仅适用于异常检测,还可以推广到其他需要衡量“期望”与“观察”之间差异的视觉理解任务中。例如,在图像质量评估中,残差可以衡量图像与“高质量”语义的偏差;在医学影像分析中,残差可以捕捉病灶与正常组织的差异。这种“残差即信号”的范式,有望成为视觉-语言模型在下游任务中的一种通用应用模式。
Res2CLIP提供了一个开源、易用、高效的少样本异常检测工具包。无论你是想在工业检测场景中快速部署,还是想在研究中探索新的异常检测方法,Res2CLIP都是一个值得尝试的选择。项目地址:https://github.com/hito2448/Res2CLIP,论文地址:https://arxiv.org/abs/2605.16171。
资源
资源 | 链接 | 说明 |
|---|---|---|
GitHub仓库 | github.com/hito2448/Res2CLIP | 完整源码与说明 |
论文 | arxiv.org/abs/2605.16171 | 完整论文文本 |
CLIP模型 | github.com/openai/CLIP | OpenAI原始CLIP实现 |
MVTec-AD | www.mvtec.com/company/research/datasets | 异常检测基准数据集 |