CLIP 论文逐段精读【论文精读】
00:06 评价
评价:方法出奇的简单,但效果出奇的好。比如:迁移学习的能力非常好,预训练好的模型能在任意一个视觉分类的数据集上,取得不错的效果;而且还是zero-shot的,就是没有在这些数据集上做训练,也能取得很好的效果。

01:31 CLIP的模型总览图
CLIP如何做预训练:
- 输入:图片+文字的配对
- 输入encoder,生成特征
- 在特征上做对比学习
- 特征矩阵里获得正负样本,正样本就是匹配的图文对(矩阵对角线),负样本则是所有不匹配的图文对
训练集:4亿个图文对,数据质量高
CLIP如何做zero-shot推理:
一、预训练之后的CLIP只获得了图像和文本的特征,需要分类头才能做推理
引出Prompt template,以ImageNet为例
1、输入:CLIP先把ImageNet的1000个类,用于生成一个object作为替换位的句子,1000个句子
2、预训练好的文本encoder,生成1000个文本特征
为什么要Prompt template?为什么不直接抽取文本特征?
因为预训练的时候使用的是图像文本对,训练的时候为了保持一致,也要让encoder看到的是一个句子
还有另外两种生成句子的方法,Prompt engineering和Prompt ensemble去进一步提高模型的准确率,而不需要重新训练这个模型
二、zero-shot分类
输入:任意图片
图片encoder,生成图片特征
图片特征与所有文本特征做余弦相似性衡量
输出:最相似的文本特征对应的句子,完成分类
06:03 摆脱基础类的限制
CLIP,对于任意的图片和文本,都可以通过算相似度的方式,判断图片中的物体。
换句话说,任意给CLIP一张图片,都可以通过给模型不同的文本句子,从而知道图片中是否有我感兴趣的物体。
标题:利用来自nlp的监督信号去训练一个迁移效果很好的视觉模型。利用NLP的信号摆脱了基础类的限制,使图像和文本建立了强联系。
07:21做到了把视觉和文本的语义建立起了联系,所以学习到的特征语义性非常强,迁移效果非常好。因为和nlp的结合,CLIP学习到的视觉特征和语言所描述的物体产生了强烈的联系。
09:11 基于CLIP的有趣的应用
图像生成、物体检测(摆脱基础类限制体现)、视频检索(可以OCR)
14:13 整体架构

16:02 精读开始
标题:利用来自nlp的监督信号去学习一个迁移效果很好的视觉模型
方法:利用nlp的监督信号
目的:迁移性,学习泛化性好的特征
16:59 摘要
目前最先进的视觉系统:固定的提前定义好的物体类别集合,模型通过预测提前定义好的类别完成模型训练。这属于有限制性的监督信号,这也限制了模型本身的泛化性,尤其是要识别新类别物体的时候,就需要新的数据去训练新的模型。
本文:从文本中获得监督信号,也就是只要用语言描述过的物体,就有可能让视觉模型能识别到。
证明:用一个很简单的预训练任务,就能非常高效的、可扩展的去学习最好的图像表征
预训练任务:配对任务,给定一张图片和一些句子,模型需要判断哪个句子和图片是配对的
数据集: 4亿的图文数据集
自监督的训练方式:多模态的对比学习来完成模型训练
预训练完成之后,自然语言就被用来引导视觉模型做物体分类,也就是Prompt,而且Prompt不局限于学到的视觉概念,还能扩展到新的类别,从而,学到的这个模型可以直接用在下游任务上去做zero-shot推理
20:52 引言
NLP效果非常好的框架:文本进文本出+利用自监督信号训练整个模型+原始数据
直接从原始的文本数据中去预训练一个模型已经在过去几年里在nlp领域取得了革命性的成功(bert gpt t5等模型)
不论是完形填空还是自回归预测的方式,都是一种自监督的预训练方式,所以目标函数是与下游任务无关的,只是想通过预训练得到非常好非常能泛化的特征。
随着计算资源、模型变大、数据增多,模型的能力也会稳健的提升。这就是一套文字进文字出,并不是在做什么特殊的分类任务。模型架构也是和下游任务无关的,那么在直接用在下游任务上的时候,就不用费尽心思去研究针对任务的输出头或者针对数据集的特殊处理了。这里面最厉害的就是OpenAI自己的gpt3模型了,什么任务都能做,而且不需要特定数据或者只需要一点点数据做微调就可以和之前精心设计的模型取得差不多的结果
这些鼓舞人心的结果证实了,这种文本进文本出,利用自监督的信号去训练整个模型的框架下,这种大规模没有标注的数据是要比那些手工标注质量非常高的数据集,反而是要更好用的。但是在视觉领域,大家一般还是在imagenet这种数据集上去预训练一个模型,这就会让预训练好的模型有诸多的限制。
NLP这套效果非常好的框架能不能用在视觉里?根据过去的工作看,是没问题的
方式:zero-shot的迁移学习
局限:模型和数据上都没有很大的规模,所以效果没有非常拔群
- virtex:用自回归的预测方式做模型的预训练
- ICMLM:用完形填空的方式做预训练
- Convirt:只在医疗图像上做了实验
为什么利用自然语言那边的监督信号是一个很有前途的方向,那为什么在视觉里这一系列的工作那么少呢
- 没有大的数据集
- 没有大模型
- 没有大算力
- 没有这么好的自监督训练方式
所以效果没有那么好。
很好的标注数据预训练出来的模型有局限性;原始文字预训练出来的模型性能太低;所以用文本带来的弱监督信号去帮助有监督的模型取得更好的效果,但是虽然这种折中方法效果很好,但还是有很大局限性:之前的工作需要精心设计,而且监督信号只有1000个或者18000个类,并不能做到真正的随心所欲的去检测到任何想检测到的类,而且Mahajan et al. (2018) and Kolesnikov et al.(2019)这两种方式都是固定用一个softmax分类头去做分类的,所以输出都是固定的,对于新类别无能为力,也就是没有灵活的做zero-shot的能力。
如Mahajan et al. (2018) and Kolesnikov et al.(2019)等,之前的弱监督方法和如VirTex, ICMLM借助自然语言处理去学习图像表征的方法,他们最大区别在规模上(数据上和模型上)
CLIP解决了规模问题:超大的图文对数据集,超大的模型
作者发现,迁移学习的效果和模型大小正相关
如何证明迁移效果:刷更多的榜。
CLIP能和有监督训练的数据集打成平手,甚至效果更好
用linear probe证明CLIP学到的特征的有效性。
CLIP比imagenet训练出来的模型效果更好,计算上也更加高效
zero-shot的clip模型更加稳健:当效果和之前有监督imagenet上训练好的模型效果持平的时候,泛化性能却远远好于imagenet上有监督训练好的模型
CLIP:想法简单,实现高效,性能在各个数据集上都非常好,而且泛化和稳健性都不错,全面碾压之前的方法。
33:37 方法
CLIP怎么预训练的?
利用自然语言的监督信号,去训练一个比较好的视觉模型
总结(统一)之前的工作+把规模做大看看效果
之前的工作:想用文本做监督信号。为什么以前做不好呢?因为NLP那边的模型也不是很好学,Topic models和n-gram的形式都很复杂,不好做跨模态的训练,但是随着transformer和自监督的训练方式兴起,NLP那边彻底革命了:deep contextual representation,就是具有上下文语义环境的学习方式,比如bert用的完形填空。
在自监督的学习范式下,现在nlp模型终于可以用这种取之不尽用之不竭的文本监督信号了,所以训练出来的模型又大又好,不仅简单而且泛化的也好,这就为多模态的训练铺平了道路。
我们为什么非要用这种自然语言的监督信号来训练一个视觉模型呢?
因为好处实在是太多了,其中两个最重要的:
- 不用再标注数据了,很容易提高数据的规模,而且因为现在的监督信号是一个文本,而不是文中说的n选1的标签了,那模型的输入输出自由度就大了很多
- 因为在训练的时候把文字和图片绑定在了一起,那么学到的特征就不再单单是一个视觉特征了,而是一个多模态的特征,当和语言联系在一起以后,就很容易去做zero-shot的迁移学习了。如果只是做单模态的自监督学习的话,无论是用单模态的对比学习(MOCO),还是单模态的掩码学习(MAE)都只能学到视觉特征,而无法和自然语言联系到一起,那还是很难去做zero-shot的迁移
结论:用文本的监督信号帮助去训练一个视觉模型是很有潜力的。
1、要做图片和文本配对的学习,就需要有一个足够大的数据集,里面有很多很多图片文本对。
过去的数据集都不够大,质量不够好,所以自己造一个数据集wit,4亿个图文对
2、预训练的方法,以及如何选择预训练的方法39:19
视觉这边的模型都非常大,训练起来都非常贵。过去的方法只是训练区预测仅仅1000个类,就已经需要训练数年。
现在数据集更大,任务更难(从自然语言处理里直接去学open set of visual concepts,要去学开放世界里所有的视觉概念)
训练效率对于多模态预训练的成功至关重要,作者做了一些尝试:图像CNN,文本transformer,从头开始训练,任务是给定图片 要预测图片所对应的文本。
为什么要用对比学习?
如果给定一张图片,要去预测它对应的文本,是需要逐字逐句去预测文本的,这个任务就太难了。因为对于一张图片来说,可以有很多很多不同的描述,文本之间的差距是非常巨大的,如果用预测型的任务去预训练模型的话,就有太多的可能性了,模型训练的就非常慢。作者发现,如果把训练任务变成一个对比的任务,也就是说,只需要判断这个图片和这个文本是不是一个配对,这个任务听起来就简单了很多,因为不再需要逐字逐句的去预测文本了,只需要图片和文本是配对的就行,这个约束一下就放宽了很多。这个监督信号其实也更合理。

如图2,仅仅把预测型的对比函数换成对比型的目标函数(黄线→绿线),训练效率一下就提高了四倍;训练效率随着约束逐渐放宽在成倍的提高,也就说明基于对比学习的训练方法,训练效率是非常高的。
- 蓝线:基于transformer做预测型的任务
- 黄线:词袋预测,不再逐字逐句的预测文本,文本已经全局化的抽成了一些特征,所以相应的约束被放宽了
- 绿线:对比学习,进一步放宽约束,不再预测单词,只需要判断是不是图文匹配对
3、伪代码认识CLIP方法43:39 伪代码

CLIP的伪代码真的很简单,和之前的对比学习没有什么区别,无非就是把单模态的正样本换成了多模态的正样本。
46:23 一些有意思的细节
- 因为收集的数据集太大了,所以模型的训练不太会有overfitting的问题,所以实现起来就比之前的工作简单很多。比如训练CLIP的时候,对应的文本编码器和图片编码器都是不需要提前进行预训练的
- 在做最后的投射的时候,没有用非线性的投射层,而是用了一个线性的投射层。SImCLR moco这一系列论文的时候,证明非线性的投射层会比用线性的投射层,带来将近10个点的性能提升。但是作者在本文中说,在他们多模态的预训练过程中,他们发现线性非线性没什么大关系,他们怀疑:这种非线性的投射层non-linear projections只是适配纯图片的单模态学习的
- 因为数据集太大了,所以也不需要做太多的数据增强,本文中唯一做了的数据增强就是随机裁剪
- 因为模型实在是太大了,数据集也实在是太大了,训练起来太耗时,所以不太好去做调参的工作,所以在算对比学习的超参数的时候,温度这个超参数(非常重要,稍微调一调最后的性能就会有很大的改变)但本文作者实在是不想调,于是就设置成了一个可以学习的标量,所以这个参数直接在模型训练过程中就被优化了,而不需要当做一个超参数,最后再去调参
怎么训练这些模型48:35 训练
视觉这边:训练了5个resnet,3个vit
ResNet-50, a ResNet-101, and then 3 more which follow EfficientNet-style model scaling and use approximately 4x, 16x, and 64x the compute of a ResNet-50
ViT-B/32, a ViT-B/16, and a ViT-L/14
第二章总结:
- CLIP模型是如何预训练的
- 作者为什么用对比学习来预训练CLIP
实验52:21 实验
1、什么是zero-shot transfer
动机:
之前的自监督或者无监督的方法,主要研究的是特征学习的能力,目标是去学一种泛化性比较好的特征。但即使学到了很好的特征,如果想应用到下游任务上,还是需要有标签的数据做微调,所以还牵扯各种各样的问题:下游任务不好收集数据,分布偏移(Distribution shift) 【分布偏移在监督学习中一般指的是训练分布与测试分布不同,在离线强化学习中指的是训练策略与行为策略不一致。】那么如何能够训练一个模型,接下来就不在训练或者不再微调了呢?
一旦借助文本训练好了这个又大又好的模型,然后就可以用这个文本作为引导,去很灵活的做zero-shot的迁移学习,至少在分类上效果都非常好。
怎么用CLIP做zeroshot的迁移呢?

- 当CLIP预训练好之后,其实就有两个编码器:图像和文本,都已经训练好了
- 这时候任意给一张图片,通过图片编码器,就会得到一个图片特征,
- 文本输入:一些感兴趣的标签单词,通过prompt engineering就会得到对应数量的句子,然后通过文本编码器,就会得到相应的文本特征
- 所有文本特征和图片特征算余弦相似度,得到的相似度还会通过一层softmax,得到一个概率分布
- 哪个概率最大,也就是哪个相似度最高,大概率就是在描述这张照片。此时句子中包含的物体就是图片中的物体了
如果给imagenet里所有的图片去做zeroshot的推理,去测试模型的效果如何,那么1000个类应该生成1000个句子,如此去与图像特征算相似度,得到结果。当然,这个过程是可以分批次进行的,所以CLIP的推理还是非常高效的,不会非常慢。
对比结果55:57
57:09 提示工程
基于prompt的学习最近非常火,无论是在CV还是NLP都非常火
主要是在做微调或者直接做推理的时候用的一种方法,而不是在预训练阶段,所以不需要那么多的计算资源,而且效果好,所以影响力非常大。
在这里,prompt指的是文本的引导作用。
为什么要做prompt engineering和prompt ensembling?
- polysemy歧义性:一个单词可以同时有很多含义。在做图文匹配的时候,如果每次只用一个单词(标签对应的一个单词)去做文本的特征抽取,就可能会面临这种问题。比如在imagenet数据集里同时包含两个类:construction cranes and cranes that fly,在不同的语境下crane的含义是不同的,建筑环境中指的是起重机,作为一个动物指的是鹤。这个时候就会出现歧义了,算得很有可能就是错的。别的数据集也可能有这种问题。
- distribution gap:做预训练的时候,匹配的文本一般都是一个句子,很少是一个单词。可是在推理的时候,如果每次都进来的是一个单词,那么可能就会存在distribution gap的问题,抽出来的特征可能就不会很好。
基于上面两个问题,作者就想了一个很简单的方式:做了一个提示模板prompt template “A photo of a {label}.”把标签变成一个句子。已经是个句子了就不会出现distribution gap的问题。因为这个模板的含义是:这是一个什么的图片,所以这个标签多指的是名词,就能解决歧义性的问题了。
作者发现用了这个提示模板之后,准确度提高了1.3%。
prompt engineering不光可以做提示模版,还可以做很多事情:如果提前知道一些信息,这对zeroshot的推理是非常有帮助的。For example on Oxford-IIIT Pets, using “A photo of a flabelg, a type of pet.” to help provide context worked well. Likewise, on Food101 specifying a type of food and on FGVC Aircraft a type of aircraft helped too. For OCR datasets, we found that putting quotes around the text or number to be recognized improved performance. Finally, we found that on satellite image classification datasets it helped to specify that the images were of this form and we use variants of “a satellite photo of a flabelg.”.
prompt ensembling,多用一些提示的模板,做多次推理然后把结果综合起来,ensemble一般都会得到更好的结果。论文中显示用了80个提示模板做ensemble。
方法部分总结:
- 数据集
- 怎么选择模型
- 怎么做预训练
- 怎么做zeroshot推理
到这里,结果已经很好了,加上点讨论,加上个结论就是个八页的中规中矩的论文投稿,但是作者又做了十页的效果展示:
在27个数据集上,衡量了CLIP做zeroshot的迁移的效果,如图所示:

Zero-Shot CLIP
Linear Probe on ResNet50作为基线:冻住预训练好的模型的主干,只用它抽特征,就训练最后一层的FC分类头层去做有监督的分类任务。这里的res50是用有监督的方式训练好的一个模型,从中去特征,然后在这些下游任务上去添加新的分类头,然后在这个新的分类头上去做linear probe的微调
绿色的都是相比于基线的提升
蓝色的是相比于基线的性能降低
- 证实了zeroshot的这种迁移,也是有效的,是可以广泛进行应用的,而不是光在imagenet或者某些数据集上有用
- 对于普通的给物体进行分类的数据集来说,CLIP一般都表现的比较好。因为图片中有可以描述的物体,那么对应的文本中应该也有这个物体的描述,所以图文就会匹配的非常好,CLIP模型也会对这些物体非常敏感。但是对于更难的一些任务,更难的一些数据集,比如DTD这种对纹理进行分类的数据集对于CLIP来说就非常难,非常抽象了,所以CLIP的表现就不好,因为对于难的任务来说,如果不给任何标签信息,这也有点强人所难了。文中讲到,对于特别难的任务,如果只做zeroshot的迁移,可能不太合理,有可能做fewshot的迁移会更合理,难任务比如给肿瘤分类,这种需要特定领域知识的任务,即使是对于人来说,如果没有先验知识,人类也是没法分类正确的。
证明对于更难的数据集,fewshot会比zeroshot的衡量更合理01:06:25 few shot

- 横坐标表示每个类别里用了多少训练样本
- 纵坐标是平均的分类准确度(27个数据集的其中20个数据集上的平均)
zeroshotCLIP:0个训练样本,别的方法因为没有和NLP结合所以没法做zeroshot,所以最低也得从oneshot开始
fewshotCLIP:预训练之后冻住模型参数,只从里面抽特征做这种linear probe,训练最后的分类头,所以需要下游数据集里有这种有标签的数据
1、linear probe CLIP:把CLIP的图片编码器冻住做linear probe
2、之前的方法:BiT-M、SImCLR、resnet50。
观察到的几个有趣的结论:
- 蓝色曲线:BiT是为迁移学习量身定做的,算是迁移学习或者说fewshot迁移学习里,表现最好的工作之一,也是在很大的数据集imagenet21k上做的预训练,是一个很强大的baseline。但是我们可以看到zeroshotCLIP,不用任何训练样本,直接和最好的bit达成平手,可见利用自然语言的威力。
- 紫色曲线:对CLIP的图片编码器,做fewshot的linear probe。我们可以发现,当训练样本只有1、2、4的时候,这种用了训练样本的fewshot方式还不如直接zeroshot的CLIP。也再次证明了用文本做引导的多模态学习是多么的强大。
- 随着训练样本的增加,fewshot学习的CLIP模型效果最好。不仅超过了之前的方法,验证了CLIP模型的强大,同时还超越了zeroshotCLIP,验证了作者的说法:对于难的数据集来说,有一些训练样本还是非常有必要的。
下游任务用全部的数据,CLIP的效果会如何?01:09:49
3.2节做了这个实验,之所以命名为表征学习,因为之前不论是无监督还是自监督的表征学习,都是先预训练一个模型,然后在下游任务上用全部的数据去做微调的。所以如果这里用上了全部的数据,那么就可以和之前特征学习的方式去做公平对比了。
如果下游任务用全部数据,那就用很多方式去衡量模型学到的特征好不好,最常见的两种方式:
- linear probe:把预训练好的模型冻住,在上面再训练一个分类头,
- finetune:把整个网络都放开,去做端到端的学习。微调一般是更灵活的,而且在下游任务数据集比较大的时候,微调往往是比linear probe的效果好很多的
在本文中,作者选用了linear probe而不是微调,原因如下:
- CLIP这种工作就是为了研究和数据集无关的预训练方式的,如果下游数据集足够大,整个网络放开在这个数据集上做微调的话,很有可能预训练的模型并不好,但是在微调的过程中经过不断地优化,最后的效果也很好,这样就不能判断预训练的模型到底好不好了。而linear probe的方式就不太灵活,整个网络大部分是冻住的,只有最后一层fc可以训练,可学习的空间就比较小,所以如果预训练的模型没有训练好,即使在下游任务上训练的再久,也很难优化到一个特别好的结果
- 因为linear probe不太需要调参,CLIP这篇论文做了大量的实验,涉及了大量的数据集,如果做端到端的微调,就会有太多可以调的超参和设计方案了。比如如果下游数据集特别大,而且数据标注质量也比较高的话,就会希望学习率大一点,因为想要这个预训练模型尽可能的去拟合下游的数据集;如果下游任务的数据集特别小,可能就需要特别特别小的学习率,因为可能稍一学习模型就过拟合了。总之就是要为每个数据集量身定做,得在各个数据集上去搜集超参数,才能在各个数据集上表现好一点。如果是linear probe因为模型主体已经冻住了,只是抽特征,唯一要学习的就是最后的分类层,所以可以调的参数非常少,所以不论是什么数据集什么任务,只要是分类,整个测试的流程就是一个正规化的流程。