CLIP 对比语言-图像预训练
CLIP(Contrastive Language-Image Pre-training)是 OpenAI 提出的多模态预训练模型,通过对比学习将图像和文本映射到共享的语义空间,实现了强大的零样本迁移能力,成为多模态 AI 的基础范式。
核心架构
CLIP 由双塔结构组成:
- 图像编码器:支持 ViT 和 ResNet 两种架构,将图像编码为固定维度向量
- 文本编码器:基于 Transformer 的文本编码器,将文本编码为同维度向量
- 对比学习目标:最大化匹配图文对的相似度,最小化不匹配对的相似度
python
import torch
import torch.nn as nn
import torch.nn.functional as F
class CLIPModel(nn.Module):
def __init__(self, image_encoder, text_encoder, embed_dim=512, temperature=0.07):
super().__init__()
self.image_encoder = image_encoder
self.text_encoder = text_encoder
self.image_proj = nn.Linear(image_encoder.dim, embed_dim)
self.text_proj = nn.Linear(text_encoder.dim, embed_dim)
self.logit_scale = nn.Parameter(torch.log(torch.tensor(1/temperature)))
def forward(self, images, texts):
# 编码图像和文本
image_features = self.image_proj(self.image_encoder(images))
text_features = self.text_proj(self.text_encoder(texts))
# L2 归一化
image_features = F.normalize(image_features, dim=-1)
text_features = F.normalize(text_features, dim=-1)
# 计算相似度矩阵
logit_scale = self.logit_scale.exp()
logits = logit_scale * image_features @ text_features.T
# 对称对比损失
labels = torch.arange(logits.shape[0], device=logits.device)
loss_i2t = F.cross_entropy(logits, labels)
loss_t2i = F.cross_entropy(logits.T, labels)
return (loss_i2t + loss_t2i) / 2训练数据与策略
CLIP 的训练数据规模是其成功的关键因素:
- WIT 数据集:4 亿图文对,从互联网公开数据中收集
- 数据过滤:去除低质量、重复和不当内容
- 批量大小:使用 32768 的超大 batch size,确保每个 batch 中有足够的负样本
零样本分类
CLIP 的零样本分类流程:将类别名填入模板(如 "a photo of a {class}"),用文本编码器编码所有类别描述,计算图像特征与所有文本特征的相似度,取最高相似度的类别作为预测结果。
CLIP 的应用场景
CLIP 的共享语义空间使其在多种下游任务中表现出色:
- 零样本图像分类:无需微调即可在新数据集上分类
- 图文检索:跨模态检索(以文搜图、以图搜文)
- 图像描述生成:作为视觉编码器接入语言模型
- 文生图引导:为 Stable Diffusion 等模型提供文本理解能力
- 视觉问答:结合 LLM 实现开放域视觉问答
CLIP 的局限性
- 细粒度识别弱:对细小差异(如车型、物种亚类)区分能力有限
- 合成理解差:难以理解空间关系和数量(如 "方块在球上面")
- 偏见问题:训练数据中的社会偏见会被模型学习
- OCR 能力弱:对图像中的文字识别能力有限
后续工作
CLIP 开创的对比学习范式催生了大量后续模型:
| 模型 | 改进方向 | 核心贡献 |
|---|---|---|
| OpenCLIP | 开源复现 | 完全开源的 CLIP 实现 |
| EVA-CLIP | 训练优化 | 更好的训练策略和更大模型 |
| SigLIP | 损失函数 | Sigmoid 损失替代 Softmax |
| Chinese-CLIP | 中文适配 | 中文图文对预训练 |