CLIP和改进工作串讲(LSeg、GroupViT、VLiD、 GLIPv1、 GLIPv2、CLIPasso)
一、CLIP
1.1 简介
1.1.1 前言
CLIP是OpenAI在2021年2月发表的一篇文章,其全称为Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练方法。CLIP用文本作为监督信号来训练可迁移的视觉模型,使得最终模型的zero-shot效果堪比ResNet50,泛化性非常好,而且CLIP还有很多好玩的应用。
zero-shot就是直接推理,用见 过的图片特征去判断没见过的图片的类别,而完全不用下游任务训练集进行微调。(相当于把模型用作特征提取,但是没有分类头)作者在30多个不同的计算机视觉数据集上进行基准测试,(这些数据集涵盖了OCR、视频中的动作识别、地理定位和许多类型的细粒度对象分类等任务)
CLIP通常都能够与监督模型的baseline效果相媲美。例如在ImageNet数据集上,
CLIP模型在不使用ImageNet数据集的任何一张图片进行训练的的情况下,最终模型精度能跟一个有监督的训练好的ResNet-50打成平手(在ImageNet上zero-shot精度为76.2%,这在之前一度被认为是不可能的)。
1.1.2 模型结构
训练过程:
如下图所示,CLIP的输入是一对对配对好的的图片-文本对(比如输入是一张狗的图片,对应文本也表示这是一只狗)。这些文本和图片分别通过Text Encoder和Image Encoder输出对应的特征。然后在这些输出的文字特征和图片特征上进行对比学习。
假如模型输入的是n对图片-文本对,那么这n对互相配对的图像–文本对是正样本(下图输出特征矩阵对角线上标识蓝色的部位),其它 对样本都是负样本。这样模型的训练过程就是最大化n个正样本的相似度,同时最小化 个负样本的相似度。
Text Encoder可以采用NLP中常用的text transformer模型;而Image Encoder可以采用常用CNN模型或者vision transformer等模型。相似度是计算文本特征和图像特征的余弦相似性
cosine similarity为了训练
CLIP,OpenAI从互联网收集了共4个亿的文本-图像对,论文称之为WIT(Web Image Text。WIT质量很高,而且清理的非常好,其规模相当于JFT-300M,这也是CLIP如此强大的原因之一(后续在WIT上还孕育出了DALL-E模型)。

分类
CLIP可以直接实现zero-shot的图像分类,即不需要任何训练和微调,这也是CLIP亮点和强大之处。用CLIP实现zero-shot分类只需要简单的两步:
- 根据任务的分类标签构建每个类别的描述文本:
A photo of {label},然后将这些文本送入Text Encoder得到对应的文本特征。如果类别数目为n,那么将得到n个文本特征; - 将要预测的图像送入
Image Encoder得到图像特征,然后与n个文本特征计算缩放的余弦相似度(和训练过程保持一致),然后选择相似度最大的文本对应的类别作为图像分类预测结果。进一步地,可以将这些相似度看成logits,送入softmax后可以到每个类别的预测概率。
我们不再需要预先定义好的标签(类别)列表,直接将图片喂给不同的文本句子,就可以知道图片中是否有我们感兴趣的物体。即,CLIP的多模态特性(利用文本监督信号)为具体的任务构建了动态的分类器,使得模型不再受限于预先定义好的类别,更加具有通用性和可用性。
比如新增三轮车的图片时,只需要在文本部分也加上三轮车这个类别,模型很有可能直接
zero-shot推理出图片属于三轮车这个类。而之前的模型,是永远不会预测出ImageNet1000个类之外的类的,这也是CLIP最吸引人的地方。类别单词变成句子,有
prompt engineering和prompt ensemble两种方法,进一步提高模型准确率,在论文后面会讲到
1.1.3 模型效果
1.1.3.1 对自然分布偏移的鲁棒性
如下图所示,作者还比较了zero-shot CLIP与现有ImageNet模型在自然分布偏移上的性能来验证它的鲁棒性。

- 左图的横纵坐标是ImageNet的分布偏移。黑色虚线是理想的鲁棒模型,是线性的、正比例的。普通的模型无法达到这样的理想效果,画出来的曲线只会在黑色虚线的下面。但这里可以看出
zero-shot CLIP的鲁棒性比标准的ImageNet训练的模型更好。 ImageNetV2是从ImageNet数据集中筛选出新的数据集,其更接近原来的测试集。然而在ImageNet上预训练的模型,在ImageNetV2上的测试性能下降了不少(76.2→64.3)- 右图中
ImageNet Sketch都是素描的图片、ImageNet-A包含很多对抗样本
CLIP和基于ImageNet上有监督训练的ResNet101,在ImageNet验证集都能达到76.2%,但是在剩下的五个数据集上,ResNet101性能下降得非常厉害,但是CLIP能依然保持较大的准确度。比如在ImageNet-A数据集上,ResNet101精度只有2.7%,而CLIP能达到77.1%。
这也说明CLIP学习到的视觉特征,已经和语言产生了很强的联系。这也不论是自然的香蕉还是动漫里的香蕉、素描的香蕉、加了对抗样本的香蕉,CLIP都知道图片是对应香蕉这个单词。
1.1.3.2 StyleCLIP
顾名思义,这是一篇CLIP+styleGAN的工作,可以通过文字的改变引导图像的生成。比如下面例子中,输入“Mohawk hairstyle”,就能改变奥巴马的发型;输入“Without makeup”,就可以一键卸装了;输入“Cute cat”(可爱的猫),猫的眼睛就睁大了。CLIP 也能理解各种抽象妆容,比如烟熏妆,吸血鬼妆。
1.1.3.3 CLIPDraw
论文《CLIPDraw: Exploring Text-to-Drawing Synthesis through Language-Image Encoders》

这也是一个利用CLIP预训练模型指导图片的生成。 CLIPDraw不需要进行训练,通过在一组RGBA Béezier曲线上执行梯度下降,就可以从文本合成一些简笔画图像。(目标是最小化生成图像的CLIP encodings与文本提示之间的余弦距离)。
在普通GPU上生成一张简笔画通常不需要一分钟。最后一张图的self表示自拍照
1.1.3.4 zero-shot检测
论文《Open-vocabulary Object Detection via Vision and Language Knowledge Distillation》(ICLR 2022)
CLIP可以应用在目标检测任务上,实现zero-shot检测,即检测训练数据集没有包含的类别。比如在CLIP出现的一个半月之后,谷歌提出的ViLD(见本文3.1章节)基于CLIP实现了Open-vocabulary的物体检测,其主体架构如下所示,其基本思路和zero-shot分类相似,只不过这里是用文本特征和ROI特征来计算相似度。

下面的例子中,如果用传统的目标检测算法的话,模型只会判断这些物体都是玩具,也就是图中蓝色的基础类。使用CLIP之后,就可以摆脱基础类的限制(Open-vocabulary Object),可以检测出新的类(图中 红色标识),比如颜色和动物类别。

Meta AI的最新工作Detic可以检测2000个类,背后也用到了CLIP。
1.1.3.5 CLIP视频检索
github上johanmodin/clifs仓库,展示了使用CLIP视频检索的工作。可以通过输入文本直接找到视频中出现的对应物体。比如输入“一辆印有odwalla的卡车”,就真的在视频中找到了这辆卡车(CLIP把这句话变成文本特征,然后将视频中每一帧都当成视觉特征,然后一帧帧的去和文本特征做对比,然后挑出相似性最高的那一帧)。

1.1.4 导言
现有的CV模型基本都是基于人工标注的数据集进行训练的,然后用来预测一组提前定义好的物体类别。这种提前定义好的标签集合,会大大简化问题本身(比如ImageNet固定的1000个类,COCO数据集固定80个类等等)。但正因如此,这种受限的监督信号限制了模型的泛化性和可用性。比如大多数模型都只能预测已知的图像类别。对于没有见过的图像类别,需要额外的信息才能识别。这样每次新增一些类别,都需要重新收集数据,训练一个新的模型。
而且无论是有监督还是自监督方法(基于对比学习的方法如MoCo和SimCLR,和基于图像掩码的方法如MAE和BeiT),在模型迁移时都需要需要进行有监督微调,比如微调固定类别的softmax分类器,而无法实现zero-shot。
作者认为,直接从自然语言中得到监督信息是一个很有前途的选择,因为其涵盖的范围更广(只要是语言描述过的物体,都有可能让视觉模型去识别)。CLIP利用多模态的对比学习,使得自然语言可以引导模型学习到视觉概念,从而实现非常灵活的zero-shot迁移(把分类问题转化为了跨模态检索问题)。
使用自然语言监督进行图像表示学习的工作很少,并且效果往往不如有监督模型,主要有两个原因:
- 早期nlp模型不太好学。
比如早期的n-gram模型非常复杂,不好跨模态训练。但是随着transformer的兴起,像BERT和GPT这种具有上下文表示的自监督训练模型做的越来越好,nlp模型也终于有了取之不尽的文本监督信号,而且使用简单,泛化性好,为多模态训练铺平了道路。 - 数据集或模型的规模不够。
比如VirTex和ICMLM都只训练了十几万的图片;ConVIRT非常类似CLIP,但只在医疗图像上做了预训练。从本质上来讲,CLIP其实并没有太大的创新,它只是将ConVIRT方法进行简化,并采用更大规模的文本-图像对数据集来训练。也可以说,相对于之前的对比学习,CLIP只是将单模态的样本 ,换成了多模态的样本。
1.2 方法
1.2.1 自然语言监督的优势
使用自然语言监督信号来训练视觉模型,有两个最重要的优势:
-
不需要采用特别的标注数据,扩展性更强。
比如ImageNet需要先定义好1000个类,然后根据这些类去下载图片,清理数据集,再去标注所有图片,过程很复杂。而CLIP不要求这种经典的“”机器学习兼容“”的标注格式,只需要下载文字-图片对;且没有n选1的标签之后,模型的输入输出自由度大了很多。 -
CLIP学习到的是图像结合文字的多模态特征,从而实现灵活的zero-shot迁移。如果只是单模态的特征,无论是类似MOCO还是MAE,都很难做到这一点(zero-shot必须要加入文字特征才能做到)。
1.2.2 预训练方法(训练效率至关重要)
CV领域的模型都很大,训练起来也很贵。比如noise student之前在ImageNet一直霸榜,但是这个模型需要在一个 TPUv3上训练33 年,这还只是在包含1000类的ImageNet上预训练的,而且只训练视觉特征。
由于训练数据量和模型计算量都很大,训练效率成为一个至关重要的因素。作者做了很多尝试,最终选择了对比学习:
VirTex模型:预测文本,对应下图蓝色线Transformer Language ModelImage Encoder使用CNN模型,Text Encoder使用transformer模型,两个模型一起从头训练,任务是预测图片对应的文本(image caption)。- 这种方法的训练效率太慢,因为根据图片进行文本描述,可能性太多了,你可以从各个角度去描述一张图片。
Bag of Words Prediction(橘色线):不要求每个词都是按顺序的进行预测,所有词都预测出来就行。这样放宽了约束,训练速度提高了三倍。CLIP:简化版的ConVIRT,基于对比学习。- 只需要判断图文是否配对,进一步简化了训练任务,训练效率一下子提升4倍(绿色线)
- 训练任务更加合理。因为训练数据所包含的文本-图像对是从互联网收集来的,它们存在一定的噪音,二者并不完全匹配。适当的降低训练目标,反而能取得更好的收敛。

OpenAI是一家GPT化的公司,从GPT系列、DALL-E到Image-GPT等等都是基于GPT做的,唯有
CLIP因为效率的原因,选择了对比学习进行训练。
最终Text Encoder固定选择一个包含63M参数的text transformer模型,而Image Encoder采用了两种的不同的架构。因为CLIP虽然是多模态模型,但它主要是用来训练可迁移的视觉模型。
Image Encoder架构- ResNet:ResNet50,ResNet101,RN50x4,RN50x16和RNx64(后面三个模型是按照EfficientNet缩放规则对ResNet分别增大4x,16x和64x得到)
- ViT:ViT-B/32,ViT-B/16和ViT-L/14。
- 所有的模型都训练32个epochs,采用AdamW优化器,batch size=32768。
- 只在ResNet50上训练一个epoch进行超参搜索,没有进行进一步的调参
- 两个最大的模型RN50x64需要在592个V100卡上训练18天,ViT-L/14需要在256张V100卡上训练12天
- ViT-L/14效果最好,所以作者还将其在336的分辨率下额外finetune了一个epoch来增强性能,记为
ViT-L/14@336px。后面论文中没有特别说明的情况下,进行对比实验的CLIP模型都是指这个。

- 训练细节
- 数据集非常大,几乎不会出现过拟合,所以
Image Encoder和Text Encoder不需要提前进行预训练。 - 只使用线性投射层(线性非线性影响不大)。
- 数据增强只使用图片的随机剪裁,这是因为数据集非常大。
- 对比学习目标函数中的超参数
τ,设置成可学习的标量,在训练中自动优化,而不用慢慢调参(还是因为数据集太大,训练很贵)。
- 数据集非常大,几乎不会出现过拟合,所以
另外还有很多的训练细节,才使得CLIP真正能被训练出来。训练超大模型,可以参考来自OpenAI的博文:《How to Train Really Large Models on Many GPUs?》及对应的CSDN翻译。
1.2.3 伪代码
# image_encoder - ResNet or Vision Transformer
# text_encoder - CBOW or Text Transformer
# I[n, h, w, c] - 输入图片维度
# T[n, l] - 输入文本维度,l表示序列长度
# W_i[d_i, d_e] - learned proj of image to embed
# W_t[d_t, d_e] - learned proj of text to embed
# t - learned temperature parameter
# 分别提取图像特征和文本特征
I_f = image_encoder(I) #[n, d_i]
T_f = text_encoder(T) #[n, d_t]
# 对两个特征进行线性投射,得到相同维度的特征d_e,并进行l2归一化,保持数据尺度的一致性
# 多模态embedding [n, d_e]
I_e = l2_normalize(np.dot(I_f, W_i), axis=1)
T_e = l2_normalize(np.dot(T_f, W_t), axis=1)
# 计算缩放的余弦相似度:[n, n]
logits = np.dot(I_e, T_e.T) * np.exp(t)
# symmetric loss function
labels = np.arange(n) # 对角线元素的labels
loss_i = cross_entropy_loss(logits, labels, axis=0) # image loss
loss_t = cross_entropy_loss(logits, labels, axis=1) # text loss
loss = (loss_i + loss_t)/2 # 对称 式的目标函数
在MOCO中,真实标签都是0,因为其正样本都是放在第一位,所以正样本对应的索引永远是0;但是在CLIP中,正样本都是在对角线上,即(),所以真实标签为np.arange(n)。