CLIP(Contrastive Language-Image Pre-training,对比语言-图像预训练)是多模态领域的里程碑式模型,后来作为核心组件被广泛应用于DALL·E 2、Stable Diffusion等重要的文生图大模型中。可以说,它是跨模态理解与生成领域的一个关键枢纽。下面,我们将从原理层面详细拆解CLIP的核心设计思路。
原论文地址:https://arxiv.org/pdf/2103.00020.pdf
项目开源地址:https://github.com/openai/CLIP
核心思想
CLIP的训练过程可概括为三个循序渐进的阶段:
- 从训练集中随机采样一张图片及其对应的标签文本,分别送入图像编码器和文本编码器进行处理。其中图像编码器与文本编码器在主体结构上对称,但图像侧额外增加了patch embedding操作(将图片切分为小块并嵌入向量),后续会展开说明。
- 将文本编码器和图像编码器输出的embedding向量通过余弦相似度进行对比。这一步骤的目标是衡量当前随机选取的文本-图片对是否匹配。
- 根据计算得到的损失函数进行梯度反向传播,反复迭代优化模型参数。
训练完成后,对于配对的图片与文本,两个编码器会输出高度相似的embedding向量,余弦相似度趋近于1;而不匹配的组合,余弦相似度则趋近于0。在实际应用中,正是利用文本编码器和图像编码器的输出向量作为跨模态任务的沟通桥梁,实现了文本与图像之间的对齐。
CLIP损失函数
在CLIP的前向训练过程中,需要将N个标签文本与N张图片两两组合,计算所有可能的文本-图片对的余弦相似度,形成一个N×N的相似度矩阵。其中,矩阵对角线上的元素对应真正匹配的文本-图片对(即N个正样本),其余均为负样本。CLIP的训练目标十分明确:最大化正样本的余弦相似度(即对角线上的向量点积),同时最小化负样本的余弦相似度。
训练完成后,输入配对的图片和标签文本,两个编码器输出相似的embedding向量,余弦相似度接近1;不匹配的组合则接近0。以下是核心代码实现:
# cosine similarity as logits
logit_scale = self.logit_scale.exp()
logits_per_text = torch.matmul(text_embeds, image_embeds.t()) * logit_scale
logits_per_image = logits_per_text.t()
loss = None
if return_loss:
loss = clip_loss(logits_per_text)
if not return_dict:
output = (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs)
return ((loss,) + output) if loss is not None else output
总结
CLIP模型的突出优势非常明显:
- 多模态学习:能同时理解文本与图像,在多种跨模态任务上表现优异。
- 零样本学习能力:经过大规模预训练后,模型具备优秀的泛化能力,即使面对从未见过的类别也能有效识别。
- 语义理解:通过学习文本与图像之间的深层语义关联,CLIP能更精准地执行基于文本提示的图像相关任务。
当然,它也存在一些局限性:
- 计算资源需求高:模型规模大、复杂度高,训练和部署都需要大量算力与存储,成本较高。
- 数据依赖性:虽然效果惊艳,但性能仍然严重依赖预训练数据的质量与多样性,在某些特定领域或语言上泛化效果可能不够理想。
- 对抗攻击:和许多深度学习模型一样,CLIP对输入微小的扰动比较敏感,容易受到对抗性攻击,可能导致预测结果不稳定。
总体来看,CLIP依然是当前多模态领域的标杆之作。作为SORA、Stable Diffusion等模型的重要基础组件,值得花时间深入理解。
