基本信息

项目 内容
论文标题 Learning Transfferable Visual Model From Natural language Supervision
作者 Alec Radford, Jong Wook Kim, Chris Hallacy, Aditya Ramesh, Gabriel Goh, Sandhini Agarwal, Girish Sastry, Amanda Askell, Pamela Mishkin, Jack Clark, Gretchen Krueger, Ilya Sutskever
作者单位 OpenAI
时间 2021
发表会议/期刊 International Conference on Machine Learning (ICML)
论文别名 Contrastive Language-Image Pre-training对比式语言-图像预训练

方法概览

特点 文章性质
输入
输出
所属领域 多模态学习:理解图像和文本之间的对应关系

创新点

  1. 给定一张图像和一组文本描述,CLIP 能判断哪个描述最匹配图像。无需微调,即可实现:零样本图像分类,图文检索,开放词汇目标检测与分割
  2. 对比学习(Contrastive Learning):
  3. CLIP 由两个主要部分组成:一个图像编码器和一个文本编码器。
    1. 图像编码器:可以是 Vision Transformer(ViT)或传统的卷积网络(如 ResNet)。它将输入图像转换为一个固定长度的向量表示。
    2. 文本编码器:通常是一个 Transformer 模型,将输入的文本(比如一句话)也编码成一个同样维度的向量。
    3. 这两个编码器是独立的,但它们输出的向量被设计为在同一个语义空间中。也就是说,语义上相似的图像和文本在向量空间中会靠得很近。
    4. 如果是图像文本对,那么使两个向量相近,向量点积取loss使其变小,然后不是同一个文本图像对就让两者loss大。
  4. 在一个训练批次中,假设有 N 个图像和 N 个文本(一一对应),模型会:
    1. 分别用图像编码器和文本编码器得到 N 个图像向量和 N 个文本向量。
    2. 计算所有图像和文本之间的相似度(通常用点积)。
    3. 使用对比损失函数,使得每张图像与其对应文本的相似度尽可能高,与其他文本的相似度尽可能低。
    4. 这个损失函数叫做 InfoNCE loss,它的作用是拉近正样本对,推开负样本对。

如何使用CLIP

  1. 零样本图像分类 (Zero-Shot Image Classification)
    1. 准备候选类别文本:列出所有你希望图像可能属于的类别,并为每个类别编写一个或多个描述性文本。例如,对于动物分类:
      ["a photo of a dog", "a photo of a cat", "a photo of a bird", "a photo of a car", "a photo of a tree"]
    2. 编码文本: 使用CLIP的文本编码器将这些候选文本描述转换为一组文本向量(Embeddings)。
    3. 编码图像:使用CLIP的图像编码器将你想要分类的输入图像转换为一个图像向量。
    4. 计算相似度: 计算这个图像向量与所有文本向量之间的余弦相似度 (Cosine Similarity)。
    5. 预测类别:相似度最高的文本描述所对应的类别,就是图像的预测类别。
  2. 图像-文本检索 (Image-Text Retrieval)
    1. 将一个文本查询(如 “a red sports car on a mountain road”)用文本编码器编码成向量。
    2. 将图像数据库中的所有图像用图像编码器编码成向量。
    3. 计算文本向量与所有图像向量的相似度。
    4. 返回相似度最高的图像。
  3. Stable Diffusion等扩散模型: 在文本到图像生成过程中,CLIP的文本编码器(或其变体)被用来将用户的文本提示(Prompt)编码成条件向量,指导图像生成。同时,CLIP的图像特征也常用于计算生成损失(如CLIP Loss)来提升生成图像与文本的匹配度。
  4. 使用Hugging Face Transformers库 (最常用):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from PIL import Image
import requests
from transformers import CLIPProcessor, CLIPModel

# 加载预训练模型和处理器
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

# 准备图像和文本
image_url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(image_url, stream=True).raw)
texts = ["a photo of a cat", "a photo of a dog"]

# 处理输入并进行推理
inputs = processor(text=texts, images=image, return_tensors="pt", padding=True)
outputs = model(**inputs)

# 获取相似度得分
logits_per_image = outputs.logits_per_image # 图像到文本的相似度
probs = logits_per_image.softmax(dim=1) # 转换为概率
print(probs) # 例如: [[0.99, 0.01]] 表示图像极可能是猫