image.png

CLIP沟通文本和图像的桥梁。
SOTA的视觉任务模型需要固定的监督数据对,比如049EB466.png-大象,049ECC72.png-兔子。这种方式在特定数据集上能够拥有很好的性能,但是在其他未知类别上的性能就会急剧下降。这种监督形式限制了模型的通用性,因为需要额外的数据来重新训练模型。一个识别04A07E39.png04A09AD9.png的模型并不能识别04A0B72B.png04A0CE6C.png
传统的图像任务都是使用one-hot编码进行,每一类都有其独特的数字标签,比如背景为0,04A2A34C.png是1,04A2B84B.png是2,计算机只需要将像素分类成0,1,2。CLIP则是直接从图像的文本描述中进行学习,“a photo of rabbit”,“a photo of elephant”。只需要为每一幅图提供一些文本描述,即可进行CLIP的模型预训练。在一个数百万的大型数据集上进行预训练后,CLIP能取得十分惊艳的泛化性能,以适应任何下游任务,识别、分割、追踪等等。

Background

在NLP中,text-to-text 的预训练方法已经十分成熟,使得大型的预训练模型能够 zero-shot 迁移到下游任务中,也就是现在最热门的 GPT 系列。GPT 的成功也引起了思考,是否可以通过 text-to-image 的方法来预训练大型视觉模型?早在 2016 年就有人尝试用 CNN 模型来预测图像的标题和短语,并证明这种训练方式可以提高模型的 zero-shot 的迁移能力。但这种方式的性能仍会低于标准视觉模型,其中原因之一是**数据集规模。(毕竟大力出奇迹,力大砖飞)。**ChatGPT 已经证明,超大数据集能提高性能和泛化能力。因此 CLIP 选择在一个大规模的自然语言监督的视觉数据集上进行训练。

Highlights

  1. A sufficiently large dataset

    MS-COCO、YFCC100M 是目前常用于视觉训练的大型数据集。CLIP 在这些数据集中进行过滤,大致得到了 15million 的图像数据,与 ImageNet 相当。
    此外,还爬取了互联网中的图像数据,包括 400 million 个图像对,并尽可能让类别平衡。

  2. An efficient pre-training method

    一个足够大型的数据集能让猪飞起来,那么一个足够好的方法就能让猪变成歼-20。
    CLIP最开始使用类似于VirTex的方法,使用CNN来识别图像特征,使用Transformer来处理文本特征,并直接预测图像标题,结果可想而知,猪还是猪,只不过飞的高一点。直接预测标题存在一定困难,并且难以扩展和效率低下。
    解决方法就是预测一个整体文本与哪一个图像配对,而不是确切的单词。也就是一句话是一个整体,而不是单词的排列组合。毕竟“一张狗的图像”、“一只狗一样的动物的图像”和“一只动物是狗的图像”在某些意义上是一样的,模型到底怎么理解这句话呢,这增加了复杂度。那么要是把这些文本作为整体,那Transformer模型从中提取特征,这几句话就变成整体的一类“狗”。想要实现这一功能就需要设计一个精妙的模型和损失函数。
    image.png
    给定一个批次的N个图像对(image,txet),那么CLIP就需要预测N×N个配对可能。CLIP从image encoder和text encoder中分别学习到图像表示(image embdding)和文本表示(text embedding),并计算两者的cosine similarity,以最小化cosine similarity损失。(这里称为对比学习)

# 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)  # 有N个图像-文本对;每一张图像、文本都有1个label, 一共N张图像、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 # 将两者损失平衡。这一流程称为对比学习。
  1. Choose and scale a model

对于image encoder:CLIP考虑并使用了两个经典模型:ResNet50和Vit,并做了一些修改。

  • ResNet50:使用了antialiased rect-2 blur pooling来代替原始的pooling函数;使用attention pooling mechanism来代替global average pooling layer,其中QKV中的Q为global average-pooling的输出。
  • Vit:在Vit的Transformer中,改变了Layer Norm的位置。(Vit的论文图片中LayerNorm和代码中的位置貌似有争议,未求证)。

对于text encoder:则选择了Transformer。在文本编码器中使用了mask self-attention。

在模型规模的选择上,CLIP在image endcoder模型深度和宽度上进行同时扩展;在text encoder上则只缩放宽度。

  1. prompt engineering

提示工程同样重要,CLIP将文本规范化后,能够得到好几个点的提升。
比如“a photo of xxx, a type of xxx";
image.png

Methods

image.png

Discussion

  1. ViT的计算效率高于CLIP ResNet。在足够大的数据集上进行训练时,Vision Transformer会比CNN更快。

思考

  1. 为什么CLIP要进行L2归一化?
    不同模态的特征在数值范围上可能差距很大,直接计算内积可能导致绝对值过大影响梯度。
    通过L2归一化后,可以使特征都落在单位球面上。保证两者的余弦相似度在[-1., 1.]之间。
    其次,对比学习的本质是让两个向量方向一致。让训练目标变成方向匹配。
    最后是稳定梯度,避免梯度爆炸。
  2. 为什么需要投影层?
    1是对齐维度;2是增加可训练的变换参数,毕竟不同模态的空间分布差异很大,Projection层可以学习到一种跨模态映射,使得两种特征更容易在共享空间内对齐。3是降低过拟合风险,提升泛化能力。投影层相当于一个neck。
  3. 为什么先投影后归一化?
    投影会改变向量的尺度和分布。先归一化再投影会导致投影结果失去单位范数的性质。
    先投影再归一化能保证最终计算相似度是纯余弦距离。
  4. 温度参数是什么
    在计算相似度时,CLIP提供了一个可学习的温度参数𝜏。
    𝜏 越小,softmax 输出的分布越尖锐,让模型更关注相似度差异。
    𝜏 越大,分布越平滑,鼓励模型在多个匹配样本之间分散注意力。
Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐