VLM 系列——CLIP——论文解读

CLIP是一种基于对比学习的多模态模型,通过图文对进行训练,实现了在30多个计算机视觉任务上的优秀zero-shot性能。文章深入探讨了模型结构、训练策略、数据集特点以及模型在图像分类和文本理解上的表现,展示了对比学习的优势和潜在局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

1、是什么

    论文全称《Learning Transferable Visual Models From Natural Language Supervision》,是使用图文对(将图像表征与语言联系起来)使用对比学习(有的文章称为自监督,有的文章称为无监督)训练的多模态模型。从互联网上大量文本的监督(自然语言监督)中学习,要比传统的分类数据要大得多。

    可以用来图片zero-shot 分类(其实就是图-文检索,但是不同于以往的ImageNet预测一组固定的预定对象类别),文-图检索,图-图检索(文章没有提及,也没有测试);还有后面的整个AIGC 都有他的影子,比如Stable diffusion 的图像编码器、BLIP系列的图像编码都是使用的CLIP系列的预训练权重。

2、亮点

    *模型:作者提到整个模型的机构等都是有相似物的(VirTex),而batch 内将文本对的度量学习转化为分类是首次。

    *数据:使用互联网数据构建了一个400M的图文数据集,进行模型训练,但是没有开源。

    *结果:通过对30多个不同的现有计算机视觉数据集(集涵盖了OCR、视频中的动作识别、地理定位和许多类型的细粒度对象分类等任务)测试,zero-shot 通常与完全监督的基线相当,在ImageNet匹配原始ResNet-50的精度。

PS

   *难阅读:整片文章高达48页,无论学生还是工程人员很难抽出时间去阅读,但是不阅读会犯很多论文中提及的已经有的限制的错误。具体错误会在应用那篇文章中说。

    *论文没有提及图-图检索的方案。

    *建设性观点:文章中对很多问题都做了消融实验,并且整个测试非常全面,还是很建议去看相关部分。

    *zero-shot 定义:主要针对图片分类,给定类目闭集,在“a photo of []”的prompt []中填入各种类别名称,经过文字编码器编码得到对应的向量y1y2...yn。图片经过图片编码器得到向量x,用x跟所有的y对比,看哪个的cos距离最近(一般也可以乘以温度系数100后在经过softmax),就认为分到哪个类。

    *linear probe:冻结特征层前面的所有网络,只训练分类头(全连接层)。原因有两个:者本来就是想看看对比学习能学多好的,如果全局finetune了,本身性能不好都给微调好了,就比不出实际的对比学习的效果了。finetune 这种方式需要调的参非常多,根据每个数据集的大小不同,学习率步长都得去调,如果不finetune只linear probe就可以大大简化调参过程。

    *few-shot:等价linear probe 的方式,只是每个类别的数量更少,不是全量,而是1,2,4,8张这样。

    *finetune:训练网络所有参数。

二、模型

    1、模型结构

    整体有两个部分组成:Image encoder 和 Text encoder,并且每个encoder 都有一个投射层,将对应的特征投射到指定的相同维度。对于一个图文对,图像经过Image encoder(含投射层)变为一个向量In,文本经过Text encoder(含投射层)变为一个向量Tn。如下图左边是训练过程,右边是推理过程(zero shot)。

    训练过程:在一个batch 内,有n 个图文对,也就是n对正样本,其余(n方-n)是负样本。

    推理过程:这里主要是指图-文的zero-shot 分类过程,一张图片对应指定的n个类别,然后计算相似度。

    再具体的模型结构(Image encoder 以transformer 结构为例),如下

    然后作者尝试了2类结构共计9个模型:resnet 5个(其中有三个是直接缩放resnet 50 得到)、transformer 4个,但是有些许改动(我也还没看源码):

    *resnet:将全局平均池化层替换为注意力池化机制,是个单层的 transformer多头QKV注意力,其中Q以图像的全局平均池表示为条件。

    *Vision Transformer:对transformer之前的patch 和位置嵌入添加了额外的层规范化,并使用略有不同的初始化方案。

    *文本编码器:是一个Transformer,base model,使用一个具有8个注意头的63m参数的12层512宽模型。49,152词汇表,位置编码(BPE),最大序列长度被限制在76。序列用[SOS]和[EOS token括起来,[EOS] token处transformer最高层的激活被视为文本的特征表示,文本被层归一化,然后线性投影到多模态嵌入空间中。

    *模型缩放:使用一个简单的基线resnet,平均分配额外的计算来增加模型的宽度、深度和分辨率。对于文本编码器,只缩放模型的宽度,使其与ResNet宽度的计算增量成正比,而根本不缩放深度,因为发现CLIP的性能对文本编码器的容量不太敏感。具体如下:

    2、模型亮点

    使用图文对比学习的方式,训练更快;尝试多种结构。   

    

    PS

    *早在CLIP其实Open AI已经尝试过直接采用生成的方法,但是限于当时的计算能力,采用了折中的对比学习的方式。

    *后面还是证明:模型越大拟合能力越好(算法工程人员亚历山大)、VIT在数据足够和同计算量下性能就是好于resnet(all transformer了)。

三、数据

    1、数据标签

    就是图文对,不是传统的分类标签,其中文理论小于76token(文本编码器的最大长度)。

    2、数据构成

    训练集

    自己收集的400M的互联网数据,称为WebImageText 简称 WIT,应该并未开源。

    验证集

    高达36个数据集,如下为其中的27个。    

    3、数据清洗

    覆盖尽可能广泛的视觉概念,我们选择500,000个文本,然后使用文本搜索(图像,文本)对,为了平衡其中每个文本对应的图文对最大限制在20,000个。

   500,000个文本如何获得:在英文版维基百科中出现至少100次的所有单词,以及所有维基百科文章的名称超过一定的搜索量,最后添加查询列表中未包含的所有词的WordNet同义词集。

四、策略

    1、训练过程

    单阶段训练,所有网络均训练,初始化为随机初始化不使用任何预训练权重。

    训练过程如网络结构章节的左图。收集了大量匹配的图像和文本对,然后分别走各自的编码器得到各自的特征,再计算特征两两之间的cos相似度,让配对的特征相似度越近越好,不配对的相似度越远越好。这样就可以完成了CLIP的与训练。整个过程的伪代码如下:

  

    训练超参数:

    *数据增强:只从resize的图像中随机裁剪(由于预训练数据集很大,过度拟合不是主要问题)。

    *softmax 的超参数τ:变为可训练参数,始化为0.07,并被截断以防止对数缩放超过100(防止训练不稳定)。

    *投影层:使用线性投影从每个编码器的表示映射到多模态嵌入空间。

    *训练参数:bs=32,768、所有模型训练32 个epoch、Adam优化器、余弦调度衰减学习率。初始超参数在基线ResNet- 50模型训练为1 epoch时综合网格搜索、随机搜索和手动调整,然后,超参数被启发式地适应于更大的模型(由于计算约束)。

    *加速:混合精度、梯度检查点半精度亚当统计和半精度随机四舍五入文本编码器权重。单个gpu只计算其局部批次嵌入所需的成对相似度的子集。

    *训练时长:最大的ResNet模型RN50x64在592个V100 gpu上花了18天,而最大的Vision Transformer在256个V100 gpu上花了12天。

    *finetune:对于viti - l /14,以更高的336像素分辨率fitune 一个 epoch,将此模型记为vitl /14@336px。除非另有说明,本文报告的所有结果该模型。

    *CLIP预训练的每一步都可以看作是优化随机创建的计算机视觉数据集的性能,该数据集每个类包含1个示例,通过自然语言描述定义了32,768个类,他应该是大于500,000个文本,所以理论冲突不大。一定好好好理解这里,所以那些fitune几个指定类目的,简直不懂原理啊。

    

    2、推理过程

    如网络结构章节的右图,这里主要就是图文zero-shot 学习,而且这图文一般为闭集(就是图像和文本都是限定类别)。

    对于每个数据集,使用数据集中所有类的名称,把类别名填到“A photo of a {object}.”里面然后编码,同样图像也做编码,编码完成后拿图像特征跟文本特征比cos相似度,通过温度参数τ缩放,并通过softmax归一化为概率分布,那个概率大,我们就认为模型把这张图分到了哪个类别里。

五、结果

1、多维度对比。

*zero-shot clip 对比Visual N-Grams

效果好很多,但是不太公平,因为:数据集大了10倍,用的模型比之前多100x计算量(Visual N-Grams 发布的时候还没有出现transformer结构,在模型基础结构上也吃了亏。)综合下来多了100x的资源来训练。

*clip zero-shot 对比 resnet linear probe

给物体分类的任务,CLIP做的都比较好(比如车、食物、宠物、ImageNet等等),对纹理分类、或者图片里目标计数这种任务CLIP就做的不太好,不如ResNet50。但是这里我不太明白,CLIP 的模型是vit L 336? Resnet 的预训练权重是CLIP还是ImageNet,看着像ImageNet。

*CLIP zero-shot 对比 CLIP few-shot 

20个数据集上的精度合并。可以得到几个结论:

1)CLIP(紫色线)超过了BiT-M模型(蓝色线),再次证明了文本引导的多模态学习非常强大;

2)对CLIP来说,Few-Shot为1、2、4的时候,Few-Shot还不如Zero-Shot;

3)随着Few-Shot数量的增加,CLIP 精度不仅超过了以前的模型,还超过了它自身,说明对难一些的样本,有些few-shot还是很有必要的。

* CLIP few-shot 何时达到CLIP zero-shot 性能

在每个测试集上标注样本,看看多少的few-shot 性能能等价zero-shot,需要注意为什么有小数,是因为这个数字是换算来的(1,2,4,8,16 shot)。

*CLIP zero-shot 和 Linear probe相关性 

Clip zero-shot 的性能和linear probe 是正相关,但是弱于linear probe。

*CLIP zero-shot 模型大小相关性 

模型越大,性能越好,算法开发人员笑死,算法工程部署人员哭死。蒸馏能挽救多少?

*CLIP linear probe 和 sota 模型 比较 

CLIP 好于所有模型。vit 同计算量让然好于resnet。

*CLIP linear probe 和 最大的EfficientNet L2 NS  linear probe 比较 

在 27 个数据集中,CLIP 在其中 21 个数据集都超过了 EfficientNet,而且很多数据集都是大比分超过,少部分数据集也仅仅是比 EfficientNet 稍低一点点。

*鲁棒性

数据集换了分布之后,表现依然很好(比如素描物体分类,ResNet101精度骤降,CLIP还是保持在比较高的水平)。

2、消融实验

*Prompt 工程对性能的提升

prompt工程的意思是,分类的时候不是直接把一个“dog”标签喂给文本编码器让它编码,而是搞一个prompt做成“A photo of a dog.”再进行编码。原因有二:

1)词汇有很多意思,每次只用一个单词做标签提取就很容易有歧义,比如remote即可以是“远程的”又可以指遥控器,编码器不太好确认是哪个意思。如果做成“A photo of a remote.”就很明显是遥控器的意思了;

2)训练的时候文本编码器编的是句子,推理测试的时候如果只用单词的话,会产生数据分布gap,可能会影响性能;

基于上面这两个原因,作者就做了prompt工程。也就是直接做prompt template:“A photo of a {label}”。实验验证了有prompt比只用单个词汇编码,准确率能提升1.3%;

另外如果是做 Oxford-IIIT Pets 这种数据集,提前知道了这里面都是宠物,就还可以把prompt写成“A photo of a {label}, a type of pet.”同理食物和飞机的数据集也可以加上先验prompt,效果会进一步提高。

对于OCR这种数据集,如果我想找包含某些字样的图片,给这些字样打上引号会提升准确率,比如“A car with the words' hello 'written on it”。

六、使用方法

见官方git:https://github.com/openai/CLIP?tab=readme-ov-file

使用CLIP 进行图像分类——有没有戴眼镜(但是其实对这种否定词官方说表现并不好):CLIP:创建图像分类器

七、待解决

文章提到的局限性:

1)文中对比的ResNet-50不是ImageNet最强的模型,最强的已经能做到90%了而CLIP只能做到76.2%。如果进一步提高数据和模型的规模,还会长点,但如果想做到90%估计得再加1000倍得数据量。

2)在细分类数据集上低于ResNet-50;图片异常方面的判断就不如ResNet-50,因为模型不知道什么叫异常。所以在很多很多很多领域里CLIP肯定跟瞎猜一样。

3)如果数据完全超出了训练集数据,也会表现很差,例如CLIP在MINST手写数字数据集上表现只有80%多。研究了一下发现训练集里真的没有类似这样的数据。DTD(纹理分类)和CLEVRCountS(给图中物体计数)这两个数据集,都是相对抽象的任务,在这方面CLIP的表现明显不如ResNet。

4)CLIP做分类依然需要用文本给出固定的类别,然后模型告诉你图片跟这些类别哪个最接近,类别数量依旧有限。理想状态是模型直接给出类别的文字标题。所以未来可能会把对比学习和生成学习的loss结合起来,既有对比学习的高效性又有生成学习的灵活性。

5)对数据的利用并不是很高效,如何高效呢?可能数据增强,也可以自监督或伪标签的方式。

6)实验过程中每次都在用所有数据集做测试,无形中已经用ImageNet作为验证集了。另外所用的27个数据集不一定具有代表性。如果有专门的数据集来测试Zero-Shot Transfor能力就好了。

7)数据都是网上爬的没有清洗,可能会学到有害的信息,隐藏着偏见。

8)zero-shot和小few-shot反而下降了,跟人的学习截然不同。怎么能让它zero-shot好,one-shot更好。

我自己的待解决:

看代码具体resnet 改了哪类。

八、参考链接

神器CLIP:连接文本和图像,打造可迁移的视觉模型 - 知乎

https://www.cnblogs.com/lxmj/p/15945772.html

CLIP 模型解读 - 知乎

多模态超详细解读 (一):CLIP:大规模语言-图像对比预训练实现不俗 Zero-Shot 性能

### 关于视觉语言模型 (VLM) 的研究论文 以下是几篇与视觉语言模型 (VLM) 相关的研究论文,涵盖了不同的应用场景和技术细节: #### 1. **MResT: Multi-Resolution Sensing for Real-Time Control with Vision-Language Models** 这篇论文探讨了如何通过多分辨率感知技术实时控制视觉语言模型的应用场景。文中提到的扩散策略学习(Diffusion Policy Learning)是一个重要的组成部分[^1]。这种技术能够帮助模型更好地理解复杂的环境并作出相应的决策。 #### 2. **Robot-Action Fine-tuning** 此部分讨论了基于视觉语言模型的动作微调过程。具体来说,文章提到了两种预训练的视觉语言模型——PaLI-X 和 PaLM-E,并将其扩展为 RT-2-PaLI-X 和 RT-2-PaLM-E 版本。这些模型被用来解决广泛的视觉解释和推理任务,例如推断图像组成以及回答关于对象间关系的问题[^2]。 #### 3. **Moonshot: A New Video Generation Model Handling Both Images and Text as Inputs** Moonshot 是一种新型视频生成模型,支持同时处理图像和文本输入。它的核心组件是多模态视频块(Multi-modal Video Block, MVB),其中包含了用于表示视频特性的时空层和专门设计来应对外观调节需求的分离交叉注意层。此外,该模型还具备与预先训练好的图像 ControlNet 集成的能力,从而实现几何视觉条件下的高效适配[^3]。 #### 4. **Stimulating the Diffusion Model for Image Denoising via Adaptive Embedding and Ensembling** 虽然主要关注点在于图像去噪领域内的扩散模型改进方案,但它同样涉及到了一些可用于增强视觉语言建模效果的技术手段。比如自适应嵌入和集成方法可以提升模型对于噪声数据的理解能力,进而间接促进 VLM 性能优化[^4]。 ```python # 示例代码展示如何加载一个简单的视觉语言模型框架 import torch from transformers import CLIPProcessor, CLIPModel model_name = "openai/clip-vit-base-patch32" processor = CLIPProcessor.from_pretrained(model_name) model = CLIPModel.from_pretrained(model_name) image_path = "./example_image.jpg" text_input = ["A photo of a cat", "A photo of a dog"] def process_and_predict(image_path, text_input): image = processor(images=image_path, return_tensors="pt")["pixel_values"] inputs = processor(text=text_input, images=None, return_tensors="pt", padding=True) outputs = model(**inputs) logits_per_image = outputs.logits_per_image probabilities = torch.nn.functional.softmax(logits_per_image, dim=-1).tolist()[0] result_dict = {t:p for t,p in zip(text_input,probabilities)} return sorted(result_dict.items(), key=lambda item:item[1], reverse=True) predictions = process_and_predict(image_path, text_input) print(predictions) ``` 上述代码片段展示了如何使用 HuggingFace 提供的 `transformers` 库中的 CLIP 模型来进行基本的图文匹配预测操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TigerZ*

你点滴支持,我持续创作,羞羞

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值