CLIP概要

自从CLIP被提出已经被用到各种领域当中,有分割l(seg,groupVit),目标检测(ViLP VLIP),视频中有video clip,语音粒度audio clip还有视觉语言方面。

简介

clip的迁移学习能力非常强,预训练好的模型可以在任意图片分类的模型下作的很好的效果,而且它是zero-shot的。clip在不适用image-net上训练集的情况下,直接zero-shot。达到了有监督的res50同样的效果。

大概流程,通过自然语言处理来的监督信号,可以训练一个迁移效果很好的视觉模型(多模态)。在训练的过程中,模型的输入是一个图片和文字的配对。

模型的输入是图片和文字的配对,上文的图像编码器可以是resnet也可以是vit。训练集中有n个这样的图片文本对。clip在这些特征上做对比学习。

对比学习Contrastive Learning是一种自监督学习方法,目的是学习表示embedding使得相似的数据点在表示空间中彼此靠近,而不是相似的数据点相隔较远。它构建正样本对(相似的数据对)和负样本对(不相似的数据对)来训练模型,让模型能够更好的区分不同类别的样本。

正样本对(Positive Pair):由同一类或相似的两个数据点组成。例如,图像领域中两张相同物体的图片,或在音频处理中的同一段音频的不同变换。

负样本对(Negative Pair):由不同类或不相似的两个数据点组成,目的是让模型学习到不相关的数据应在表示空间中距离更远。

这里的正样本就是配对的图片文本对。所以矩阵上沿着对角线的元素都是配对的。而不是沿着对角线的元素就都不是配对的。也就是说有n个正样本,有$n^2-m$个负样本。open ai收集了4亿个这样的数据集(清理的比较干净)

因为clip这个模型经过预训练之后,只能得到一些视觉上文本上的特征。没有做进一步的训练或者微调。所以说是没有这样一个分类头的。

这里做了修改,叫做prompt template。以imagenet为例,将单词变成了句子后(替换里面的object)。ImageNet有1000个类,这里就有1000个句子。之后就会得到1000个文本的特征,在推理的时候用图片的特征去和所有的文本特征去consine similarity。然后选择相似度最高的句子。真正使用的时候标签和图片都是可以修改的。可以给定任意的照片给定任意的文字,从而指导模型中有没有感兴趣的内容。

clip学习到的内容语义性非常强,迁移性也非常好。因为和自然语言处理的结合导致了clip处理出来的特征和我们语言描述的物体产生了很强的关联。

clip还能用来做物体检测和分割。就比如说进行检测的时候,不但能检测出物体是玩具,还能检测出物体具体是什么玩具

还有基于clip对视频进行检索:输入一个物体,检索视频中是否有出现过这个物体。

clip去掉补充材料都有30页(一共48页)2页引言,2页方法,6-18是实验。12个作者全部来自open ai

内容

最先进的视觉系统是通过学习提前定义好的物体类别集合。然后模型通过预测提前定义好的类别从而完成训练。

抽象

比如ImageNet 1000,手写数字识别10个类。因为采用了有限制性的监督信号,从而限制了模型本身的泛化性。特别是做新物体的时候。每次都要重新训练。于是就提出了直接从自然语言的文本中获得监督信号。这样只要是语言描述过的物体,就有可能让视觉模型识别到,而不仅仅是1000个类。可以通过一个预训练任务,进行自监督的训练。在预训练完成后,自然语言被用来引导视觉模型去做物体的分类。(prompt)其中分类也补单局限于学到的视觉概念,还能扩展到新的类别。直接进行zero-shot推理,甚至能够打平专门有监督训练的数据集,甚至更好。ImageNet 上128万个训练集和res50打平。open ai没有开源预训练的代码,但是开源了预训练的模型。

介绍

因为gpt的成功,作者引出了没有手动标注的数据集,反而比标注的数据集效果来的更好。但是在视觉领域还是在imagenet上来预训练。作者列举了相似的工作,如果自然语言处理中的监督信号是有力的方向,如果堆上模型和测试数据集可能能达到更好的效果。但是他们的模型需要精心设计切输出是固定的。作者采用了类似VirTex,ICMLM和ConVIRT的训练方式。但是进一步扩大的数据集。用了conVirt的简化版本,拿到了非常好的效果。(无论是微调还是zero-shot都很好,zero-shot还更加稳健)

方法

Transformer的出现大大提升了训练的效率,使用自监督的方式能用上各种各样的数据集。为什么要用自然语言的信号学习视觉模型呢?因为这样就可以不用再标注这些数据,如ImageNet需要提前标注和选择1000个类,这是一个非常复杂的过程。而寻找图片和文字的配对是更加容易的,模型输入输出自由度也大了很多。而且学习到的特征变成了一个多模态的特征,也因此方便去做zero-shot的推理。

论文中介绍了为什么不选择现有数据集,于是openai自己收集了4个亿数据集叫做WIT for webimage text数据集。

关于预训练方法,首先用了和vertext相似的方法。图像卷积,文本Transformer。然后拿图像预测文本。如果给定图片预测文本的话,这个任务就太难了,因为对于一张图有各种可能的文本描述。如果只取判断这个图片和这个文本是不是配对的,这个任务就简单了很多。经过实验发现把预测型函数换成对比型的目标函数,效率提高了4倍。

可以看出来对比学习的高效。

# image_encoder - ResNet or Vision Transformer
# text_encoder - CBOW or Text Transformer
# I[n, h, w, c] - minibatch of aligned images
# T[n, l] - minibatch of aligned texts
# 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
# extract feature representations of each modality
I_f = image_encoder(I) #[n, d_i]        从编码器得到特征
T_f = text_encoder(T) #[n, d_t]
# joint multimodal embedding [n, d_e]
I_e = l2_normalize(np.dot(I_f, W_i), axis=1)    #进行投射然后l2归一化
T_e = l2_normalize(np.dot(T_f, W_t), axis=1)    #算出他们的consine similarity
# scaled pairwise cosine similarities [n, n]
logits = np.dot(I_e, T_e.T) * np.exp(t)
# symmetric loss function    所有的正样本都在对角线上
labels = np.arange(n)
loss_i = cross_entropy_loss(logits, labels, axis=0)
loss_t = cross_entropy_loss(logits, labels, axis=1)
loss = (loss_i + loss_t)/2

它做的无非就是把单模态的正样本换成了多模态的正样本。因为收集的数据集比较大所以不太有过拟合问题。而最后进行投射的时候,使用了线性的投射层,而不是非线性的投射层。因为取得相似的效果。并且很少用数据增加,只用了数据裁剪。并且把temperature这个很重要的对比学习的值设置为了一个标量,在模型训练过程中就被优化掉了,不需要当成一个超参数。

在视觉中模型可以选择resnet也可以选择vit,文本用的是Transformer,模型的选择非常中规中矩,只有很小的改动以便训练的更高效。并且利用混精度训练。除此之外还用了一堆的优化技术。即便是相似度计算也是在不同GPU上做的。可以参考文章

How to Train Really Large Models on Many GPUs? | Lil'Log (lilianweng.github.io)

混合精度训练(Mixed Precision Training)是一种通过结合不同精度(通常是 16 位浮点数和 32 位浮点数)来加速深度学习模型训练的方法。其核心思想是在不显著影响模型精度的情况下,利用更低精度(如半精度浮点数 FP16)来减少计算量和内存占用,从而提高训练速度并减少显存使用。

其中vit的训练速度,要远高于resnet。而且因为vit表现最后,所以在之后的文章中都使用Vit来进行实验。

实验

之前自监督和无监督的方法是为了学习特征,但在应用到下游数据的时候还是需要有标签的任务去做微调。但zero-shot就可以训练完之后不做微调。

基于prompt(提示)的学习方法最近非常火,无论是NLP还是CN。他可以在做微调和直接做推理的时候使用的一种方法。而不是在预训练阶段(省资源效果好)。
如果在做文本和图片的匹配时,每次只用一个单词(标签对应)做特征抽取,就会遇到一个问题。 有些词会有歧义出现。比如crane,boxer之类的。此外,做预训练的时候匹配的都是一个句子,很少是一个单词所以做了提示的模板 a photo of a {label}。去除了歧义性的问题(因为标签里大概率是名词),同时将参与变成了句子。这个改动提升了1.3%的性能。此外还可以根据数据集的类型增加前后缀,比如如果是在预测一个全是动物的数据集,那么久加上后缀a type of pet。更容易得到正确答案。

之后作者在27个数据集上衡量它的结果。其中在16个模型上有所提高与res50。对于普通的对物体进行分类的数据集clip表现的都很好,比如车动物。但是对于DTD这样比较难的对于纹理进行分类的数据集就表现的没那么好。或者给图片中物体计数的任务也不好。作者指出对于更难的数据集,fewshot会比zeroshort更合理。并给出了few-shot模型和zero-shot的clip的对比。下面每条曲线都是20个数据集的合并。

之后是关于用下游的全部数据去做微调的内容,linear probe和fine tune。linear probe就是冻住预训练的模型,然后训练分类头(最后一层的FC),而fine tune是直接放开整个网络。一般来说在下游数据集足够大的情况下,微调的效果要来的更好。但是作者这里使用了linear probe,这是为了更好的确定预训练结果的好坏(fine tune会对整个模型带来更大的改变)。此外linear probe不需要太多的调参。要确定学习率之类的参数。

这是作者最后的结果

横坐标是计算量,纵坐标是准确度。也就是说越靠左上角越好。之后作者在ImageNet上。clip在27个数据集例超过了EfficientNet很多都是大比分超过。

当数据分布改变的非常厉害的时候,clip还能有非常好的训练效果。

和人进行对比

最终得出了结果对clip来说很难的任务对人来说也很难。

在之后作者还做了一些去重实验。

局限性

clip在很多数据集上是可以和res-50打平,但是不是SOTA的。和SOTA差了十多个点。但是如果想弥补上这个点,可能要在现在的基础上扩张1000倍的数据。此外CLIP在细分类的数据集上效果也并不是很好,clip无法处理抽象和更难的任务,或者进行异常检测。

此外如果训练的时候和推理的数据差的很远,效果也很差,比如在mnist上只有88%。因为这些数据都是在分布意外的数据集。

clip无法根据图像去生成文字。也许可以将对比学习的目标函数和生成式的目标函数合在一起。做到这点。

伪标签技术的核心思想是在无标签数据中找到一些具有代表性的样本,并为它们生成伪标签。这些伪标签是基于模型对无标签数据的预测结果生成的,通过将这些带有伪标签的数据用于训练,可以让模型更好地学习无标签数据的内在结构。

  1. 预训练:首先使用少量已标记的数据对模型进行预训练。
  2. 生成伪标签:在预训练的基础上,使用模型对无标签数据进行预测,并将预测结果中置信度较高的样本作为正样本,置信度较低的样本作为负样本,为正样本生成伪标签。
  3. 训练:将带有伪标签的数据用于训练,更新模型参数。
  4. 迭代:重复步骤2和3,直到模型收敛或达到预设的迭代次数。

### 伪标签的优势

  • 充分利用无标注数据:在有大量无标注数据但标注成本高的情况下,伪标签可以有效利用这些数据。
  • 提高模型性能:与仅使用少量标注数据相比,伪标签通过增强数据量,可以帮助提高模型的泛化能力。

### 伪标签的挑战

  • 错误累积:如果初始模型对无标注数据的预测不够准确,伪标签的错误可能会被进一步放大,导致模型性能下降。
  • 数据噪声:低质量的伪标签可能会引入噪声,影响模型的训练效果。

伪标签方法在图像分类、语音识别、自然语言处理等多个领域中被广泛应用,特别适用于标注数据稀少的场景。

clip的训练并不是很高效,可以用自监督的方式或者伪标签的方式提升效率。这都比监督学习数据利用效率更高。

clip每次训练的时候都用ImageNet的结果做了指导。

此外,许多文本图片都是网上爬的,很多没有清洗过,可能带有很多的偏见。会带来不当的使用。

而且目前clip没法在few shot下进行很好的工作(之内zero shot)。

结论

作者想把NLP的成功迁移到视觉当中,发现效果很好。结论:

用预训练阶段进行对比学习,利用文本提示进行迁移学习,在大规模的数据集,和大规模的双向之下,可以和有监督训练模型的结果相比较。

Last modification:November 14, 2024
如果觉得我的文章对你有用,请随意赞赏