CLIP(Contrastive Language-Image Pre-training)是OpenAI(因为推出ChatGPT而广为人知的一个组织)所发布的一个文本与图像匹配模型。
它的原理很简单,它是把句子和图片都表示为向量,计算向量的相似度,比如余弦相似度,向量的相似度就代表文本和图片的匹配程度,数值为1则两个向量同向,代表图文十分匹配,数值为-1则两个向量反向,代表图文差异非常大。
OpenAI利用从网上收集的亿级的图文对数据来训练CLIP模型,图文对就是一张图片和它的描述,比如一般图片下方会有一段描述信息,这些数据经过清洗再拿去训练模型,否则像文不对图、文本缺失、图片模糊等等质量差的数据会严重影响模型能力。
CLIP模型由两部分组成,一个是将图片编码成向量的图片编码器,一个是将文本编码成向量的文本编码器,训练时就是训练这两个编码器。训练好的文本和图像编码器就可以拿去做各种事情,例如:
-
零样本(zero-shot)图像分类。比如一张“金毛猎犬在草地上奔跑”的图片,尽管训练模型时没有直接描述金毛猎犬这样信息的图文对样本(也就是对于这样的类别是零样本),但是可能有“一只金毛猫躺在草地上”、“一只奔跑的猎犬”等这样的样本,所以模型就间接学会了“金毛猎犬在草地上奔跑”这样的信息
-
文本到图像检索
-
图像到文本检索
-
作为文生图模型的一部分
那么这两个编码器用什么实现呢?
参考前面的大模型系列文章讲解的内容我们就可以得到这两个编码器:
- 将Transformer的encoder部分拿来提取文本特征,CLIP原论文是拿文本的结束标记EOS的输出特征作为整个句子的特征表示
- 利用ViT对图片进行特征提取,最终得到一个特征向量
- 图片和文本向量当然要映射到同一长度,才能够计算相似度
到了文本和图片的向量表示以后,就可以计算损失值了,图文匹配的作为正样本,图文不匹配的作为负样本,比如三个图文对,那就有三个正样本,6个负样本。如下图n张图片向量和对应文本描述向量就会构成n个正样本(对角线部分)和剩余负的样本。这被称为对比学习(Contrastive Learning),我们通过样本间的相似与否或者说匹配与否来定义正负样本,而不用手工标注正负样本。
那么训练模型,就是要让正样本余弦相似度尽可能大一些,负样本余弦相似度尽可能小一些,通过CLIP使用的infoNCE(Noise Contrastive Estimation)损失函数可以直观表现出这一点,如下:
- 上式即是一个批次N个样本总的损失。
- log部分是softmax函数,结合提到整个公式最前面的负号,就表示一个样本的损失。
- 分母是一张图片与一个批次的N个文本的相似度的总和(当然包含了与它匹配的那个文本),分子是该图片与它匹配的文本的相似度。这就照应了“让正样本的相似度更大一些,负样本的相似度更小一些”,因为这样的话损失函数的值就更小。
同样是负样本,它们和正样本的相似度还是有区别的。
这个很好理解,毕竟图文描述即便不匹配,也有描述的语义和内容上与正样本接近程度的区分,这种区分应该让模型能够感知,这样模型才能够有更强的图文理解能力嘛。
所以现在来重点介绍上式中的温度系数τ。温度系数用于调整对比学习中相似度的尺度,影响了模型对相似和不相似样本的区分能力。
我们知道,softmax函数中用到了指数函数,指数函数是很陡峭的函数,自变量的一点变化会导致函数值很大的变化,那么引入温度系数就可以利用指数函数这个特点,温度系数使得原来的相似度值被缩放了,因为温度系数在分母上,所以大于1时则是缩的效果,小于1时则是放大的效果,那么再经过指数运算,就可以实现使相似度值的差异被扩大或者被缩小的效果。
温度系数较小时:
- 当温度系数τ较小(小于1)时,softmax函数的输出分布更加尖锐。
- 模型对相似度的微小变化变得非常敏感,InfoNCE损失函数会放大正负样本对之间的差异。
- 特别是对困难负样本(即与正样本相似度较高的负样本),由于其相似度分数很高,经过softmax函数后会得到一个更大的loss,使得模型对困难负样本更为敏感,即模型会更加关注于将正样本与最相似的负样本区分开来。
- 然而,过分强迫与困难样本分开可能会破坏学到的潜在语义结构,因为困难样本往往是与本样本相似程度较高的样本,如同一个类别的不同实例。
温度系数较大时:
- 当温度系数τ较大(大于1)时,softmax函数的输出分布更加平缓。
- 这导致模型对不同正负样本对相似度的区分能力降低,模型对正负样本变得不太敏感。
- 特别是会对所有的负样本一视同仁,使得困难负样本的影响降低,这可能导致模型更难学到有意义的区分。
- 在极端情况下,当τ趋于无穷大时,无论正负样本对之间的相似度如何,它们产生的loss都相同,此时模型完全失去了对正负样本的区分能力。
所以在对比学习中温度系数值的选择是很重要的。下面展示看一个CLIP进行图文匹配的例子,在Hugging Face上我们可以搜索一个CLIP模型,比如openai/clip-vit-base-patch32(意思是openai出品的clip,图片编码使用的是vit,模型大小是base级别,图片编码时每个patch是32x32):
笔者上传了一张图片,给了三个描述,模型计算出三个描述和图片的相似度,结果是“一碗樱桃”最相似,有0.999的概率。除了直接调用API接口,还可以通过代码使用huggingface的CLIP模型,非常简单,我们可以将其用于图片过滤、图片搜索等开发任务:
像国内阿里的魔搭社区(modelscope)也提供了类似的服务。