CLIP模型基本原理

arxiv:Learning Transferable Visual Models From Natural Language Supervision

CLIP是Contrastive Language-Image Pretraining的简称,即对比语言-图像预训练模型,这里的contrastive指的是对比学习(contrastive learning)的训练策略,language-image指的是模型处理的是文本-图像多模态数据,pretraining表示该算法用于预训练,可以为下游任务提供泛化能力和增益。

要解决的问题

CLIP涉及的问题领域还是如何获得更好的图像视觉表示,即如何获得更好地语义信息并用于分类等下游任务。通常的分类任务的模式都是在密集标注的数据集上进行训练(类别种类和数量受限,比如ImageNet的1k类)。指定标注数据集上训练的图像模型在开集上通常泛化受限,因此也难以直接zero-shot地迁移到下游任务。

鉴于文本任务上可以通过大量数据的预训练对于各类任务获得增益,那么是否可以对图像表示(或者说图像的语义理解、图像-文本相关性)用类似的操作实现预训练,然后迁移到下游任务?这就是CLIP要解决的主要问题。

CLIP采用策略

为了可以更好地实现大数据量上的预训练,闭集人工密集标注的数据集显然已很难满足要求,因此,CLIP采用了新的采用多模态的方式,将传统的分类策略(预测指定闭集中的one-hot向量并argmax取出最大可能类别)转换为图文匹配问题,即给定一张图像,筛选与之最接近的文本表述。这个新策略的优势在于:

  1. 实现方式自然直接,因为将分类设计成1 vs N的向量预测问题本身是对问题的一个简化,通常我们看到图像并不是简单的指认一个类别(通常图像中有很多类别),而是自然地会对其进行语言的描述。而且这种方式数据来源广泛,由于网络中已经存在了大量的配对的图文数据,因此不需要预先划定类别打标。CLIP即利用web数据中的大量的图文配对(400M image-text pairs),通过对比学习的进行预训练。
  2. CLIP可以直接得到图文关系,便于下游任务使用。这也是之所以称为pretrain的原因。通过大量数据预训练,CLIP可以获得很好的zero-shot的能力,即直接将其应用到图像或者图文多模相关的任务中。现在的很多场景和新的模型都将CLIP作为一个沟通文本信号和图像信号的基础模块直接plug-and-play地使用,并取得了很好的效果。

实现方法

实现方法如图所示:

CLIP基本流程

简单来说,CLIP采用了对比学习的思路,对于一系列对,将正确关联项之间的图-文表示的cos相似度提升,而误匹配的cos相似度降低。具体操作如下述伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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)
T_e = l2_normalize(np.dot(T_f, W_t), axis=1)
# 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

可以看到,CLIP的思路非常简洁,首先,将图像和文本分别经过各自的encoder进行编码,图像通常用ResNet或者ViT作为encoder编码,而文本可以用CBOW或者Transformer编码。然后通过线性映射将得到的编码结果分别映射到多模态的embedding空间中,即joint multimodal embedding。这时相当于将文本和图像映射到了同一个隐空间(空间维度相同),这个空间中两者可以直接做交互(即计算相关性、内积)。具体方式和self-attention结构中计算attention map的方式类似,即batch内的样本的embedding向量之间两两计算内积,代码实现即对I_e # shape: [n, d_e]T_e.T # 转置后shape: [d_e, n]做矩阵乘,得到一个[n, n]大小的矩阵,其中的每个元素表示对应行列上的embedding的内积(由于前面已经normalize过,因此这个内积就相当于cosine相似度)。

得到内积矩阵后,通过乘以一个标量np.exp(t)来控制logits的范围,这个t参数称为temperature,也是作为可学习的参数在训练过程中自动学习得到。损失函数为横向/纵向两个方向对logits矩阵计算CE loss,然后取均值。这相当于说:最终正确的匹配如果记为,那么是一个文本查找所有图片中匹配最好的图片,同时也是一个图片查找多个文本,找到的最匹配的文本。由于一个minibatch中的文本和图像是已经对齐的,因此正确的label就是labels = np.arange(n),即[1, 2, 3, ...] (对于axis=0和1两个方向都成立),从相似度矩阵来看,就是对角线为1,其他为0的单位阵。

按照上述训练方法得到的CLIP可以用于对一张图片找到合适的匹配文本,或者反之。在将CLIP应用到分类问题时,由于文本通常是句子,而分类类别为物体名称,因此需要把类别名称放在 "a photo of {object}" 这种格式中,与图像计算相似度来实现分类(在这里可以明显看到,这样处理分类任务只是CLIP任务向下兼容的一个特例,CLIP的形式决定了它可以应用到更加复杂的图文多模态问题场景中)。

version1 : 2024年01月10日08:50:04