Skip to content
🔗 分享本题
查看我的学习进度 →

CLIP 零样本分类图解:把类别写成文本提示形成类别原型,与图像向量比较相似度后直接分类

🧠 图解记忆:CLIP 把类别名称包装成提示词并编码为类别原型,再与图像向量比较相似度,因此能在不做任务微调的情况下分类新类别;点击图片可查看原图。

💡 答案要点

Zero-shot = 不需要训练,直接分类没见过的类别

CLIP 的 Zero-shot 流程:

1. 构造提示词模板(Prompt Engineering):

python
# 基础模板
template = "a photo of a {class}"

# 改进模板(效果更好)
templates = [
    "a photo of a {class}",
    "a photo of a large {class}",
    "a photo of a small {class}",
    "a photo of the {class}",
    # ... 共 80 个模板
]

# 示例
class_name = "cat"
prompts = [t.format(class=class_name) for t in templates]
# ["a photo of a cat", "a photo of a large cat", ...]

2. 编码文本和图像:

python
# 对所有类别生成提示词
all_prompts = []
for class_name in class_names:
    for template in templates:
        all_prompts.append(template.format(class=class_name))

# 编码提示词(批量)
text_features = clip.encode_text(all_prompts)  # N_class × N_template × 512

# 平均多个模板(ensemble)
text_features = text_features.mean(dim=1)  # N_class × 512

# 编码图像
image_features = clip.encode_image(image)  # 1 × 512

# 归一化
image_features = image_features / ||image_features||
text_features = text_features / ||text_features||

3. 计算相似度并分类:

python
# 余弦相似度
similarity = image_features @ text_features.T  # 1 × N_class

# Softmax(转概率)
probabilities = softmax(similarity * temperature)

# 预测
prediction = class_names[probabilities.argmax()]

为什么 Zero-shot 效果好?

1. 海量数据学习语义:

训练数据:4 亿图文对
覆盖类别:数百万种物体、场景、动作

结果:
  CLIP 见过大量"猫"的图片和描述
  即使没在特定数据集上训练,也能识别猫

2. 语言作为桥梁:

传统 CV 模型:
  训练:看 1000 个类别的图片
  测试:只能识别这 1000 类

CLIP:
  训练:学习图文对齐
  测试:给任何文本描述,都能找对应图片

示例:
  训练时没见过"金毛犬"
  但见过"狗"、"金色"、"毛茸茸"
  → 能推理出"金毛犬"

3. 提示词工程放大效果:

单模板:
  "a photo of a cat"
  准确率:76.2%

多模板(80个):
  "a photo of a cat"
  "a photo of a large cat"
  ...
  准确率:82.7%(+6.5%)

实测性能(ImageNet):

模型训练数据Zero-shotFew-shot(16样本)
ResNet-50ImageNet0%56.4%
CLIP ViT-B/324亿图文对68.3%82.7%
CLIP ViT-L/144亿图文对76.2%88.9%

面试话术:

"CLIP 的 Zero-shot 本质是用语言知识迁移到视觉。通过对比学习,CLIP 学会了图文语义对齐。给任何文本描述,都能找到匹配的图像,不需要额外训练。多模板 ensemble 能进一步提升 5-10%。"