卷1 · 深度学习与 CV 基础
1.6 CLIP 精读与 zero-shot 评测实操(第一个完整项目)
展开本章目录与同卷章节
1. 精读地图:CLIP 论文里该带走什么2. 嵌入空间的性质(理解它,才能用好它)3. 项目实操:三件事(完整代码)3.1 Zero-shot 分类(CIFAR-10)3.2 Prompt 集成实验(提分点)3.3 跨模态检索 demo3.4 repo 规范(作品集标准)4. CLIP 的产业角色(为什么值得花一周)5. 自测题6. 动手作业(项目交付标准)7. 延伸资源同卷章节1.1 从 CNN 到 ResNet:卷积时代的遗产1.2 注意力机制:从加权检索到万物的基础操作1.3 Transformer 逐层拆解:从 Block 到小 GPT1.4 ViT 与视觉 Transformer 谱系:图像成为 token1.5 自监督三巨头:MAE、CLIP、DINO1.6 CLIP 精读与 zero-shot 评测实操(第一个完整项目)1.7 SAM 与分割基础模型:提示式视觉1.8 检测与分割极简史:知道即可的一章1.9 图像形成与相机模型:给 3D/具身留的几何底座本章目标:把 1.5 的 CLIP 思想落到一个完整可交付的项目——用预训练 CLIP 在 CIFAR-10 上做 zero-shot 分类、prompt 集成提分、跨模态检索 demo,写成规范的 repo。这是你作品集的第一块”多模态”砖,也是卷3 理解 VLM 的钥匙。
1. 精读地图:CLIP 论文里该带走什么
1.5 章已讲清目标函数,精读时重点补三块:
- 训练配方:4 亿图文对、batch 32768、可学习温度初始化 0.07(上限钳到 100)、图像增强只有”随机裁剪+flip”(对比学习界花哨增强在此无用)、AdamW+cosine、训 32 epoch 量级。启示:对比学习怕假负样本,增强过度反而破坏图文对语义;
- zero-shot 分类:把分类变成检索——每个类别写一句 prompt(“a photo of a {class}”),编码成嵌入,看图像嵌入和哪个类嵌入最近。prompt 就是分类器的权重;
- prompt engineering 与集成:单个 prompt 在细粒度任务上不稳(“boxer”是人还是狗?),论文对每个类用 80 个模板(“a photo of a big {class}”、“a sculpture of a {class}”…)编码后取平均——集成后 ImageNet 从 63% → 76%。这是本章作业的提分点。
2. 嵌入空间的性质(理解它,才能用好它)
- 余弦相似度:塔输出强制 L2 归一化,内积即余弦。所有检索、打分、分类都建立在”归一化嵌入的内积”这一个操作上;
- 跨模态检索:同一空间里 image↔text 双向检索(以文搜图的商品化技术底座就是它);
- 方向即语义:嵌入空间中的平移/方向对应语义变化(“好照片 vs 差照片”的方向 = 8.2 章美学探针的原理);
- 已知怪癖:对”词序”近乎无感(scrambled words 实验)、计数与空间关系弱、训练分布是英文互联网——评测时永远记住”CLIP 分数是它见过的分布的镜像”。
3. 项目实操:三件事(完整代码)
环境:pip install open_clip_torch(open_clip 是 CLIP 的开源复现集合,学术界事实标准)。
3.1 Zero-shot 分类(CIFAR-10)
import torch, torch.nn.functional as F
import open_clip
from torchvision import datasets, transforms
device = "cuda" if torch.cuda.is_available() else "cpu"
model, _, preprocess = open_clip.create_model_and_transforms("ViT-B-32", pretrained="openai")
tokenizer = open_clip.get_tokenizer("ViT-B-32")
model = model.to(device).eval()
CLASSES = ["airplane", "automobile", "bird", "cat", "deer",
"dog", "frog", "horse", "ship", "truck"]
TEMPLATES = ["a photo of a {}.", "a photo of the {}.", "a blurry photo of a {}.",
"a bright photo of a {}.", "a photo of one {}."] # 先 5 个,作业里扩
# 文本侧:每个类 = 各模板嵌入的平均(再归一化)
with torch.no_grad():
class_emb = []
for c in CLASSES:
toks = tokenizer([t.format(c) for t in TEMPLATES]).to(device)
e = model.encode_text(toks)
e = F.normalize(e, dim=-1).mean(0)
class_emb.append(F.normalize(e, dim=0))
class_emb = torch.stack(class_emb) # (10, 512)
# 图像侧 + 评测
test = datasets.CIFAR10("data", train=False, transform=preprocess)
loader = torch.utils.data.DataLoader(test, batch_size=512, num_workers=4)
correct = total = 0
with torch.no_grad(), torch.autocast("cuda", dtype=torch.bfloat16, enabled=(device=="cuda")):
for x, y in loader:
img = F.normalize(model.encode_image(x.to(device)), dim=-1)
pred = (img @ class_emb.T).argmax(dim=1).cpu() # 余弦最近邻 = 分类
correct += (pred == y).sum().item(); total += y.size(0)
print(f"zero-shot acc: {correct/total:.4f}") # ViT-B/32 通常 0.85~0.90
对照读法:encode_image 是 1.4 的 ViT;encode_text 是 1.3 的 decoder-only Transformer(取 EOT 位置的输出);img @ class_emb.T 是 1.2 的注意力打分函数去掉了 softmax(归一化内积)。三个前章在这里会师。
3.2 Prompt 集成实验(提分点)
把 TEMPLATES 扩到 20+ 个(模仿论文的 80 个:光照、风格、尺寸、视角…),记录 acc 曲线。观察收益递减的位置——写进 README,这就是你的第一份”实验报告”。
3.3 跨模态检索 demo
准备 100 张图 + 自定义查询(“a dog on the beach”),编码后 img_emb @ query_emb 排序,matplotlib 拼出 top-5 结果图。这个 demo 在面试里比分类数字更有说服力。
3.4 repo 规范(作品集标准)
clip-zero-shot/
├── README.md # 结果表 + 曲线图 + 三个发现(用数字说话)
├── requirements.txt
├── src/
│ ├── zeroshot.py # 3.1
│ ├── prompt_sweep.py # 3.2
│ └── retrieval.py # 3.3
└── assets/ # 检索结果图
4. CLIP 的产业角色(为什么值得花一周)
- 数据引擎:LAION 用 CLIP 给数十亿图文对打分过滤 → 文生图模型的训练集(你训练的 SD/FLUX 的血统里都有 CLIP);
- 奖励模型底座:美学评分(8.2 章)、人类偏好对齐(PickScore 等)全在 CLIP 空间上建;
- VLM 视觉塔:早期 LLaVA 直接用 CLIP ViT 当视觉编码器(卷3.2);
- 内容审核与搜索:以文搜图、违规内容向量分类,工业界每天在跑。
一句话:CLIP 是多模态产业的”公共基础设施”,也是你科研里最常用的预训练底座。
5. 自测题
- zero-shot 分类为什么可行?“分类器权重”是什么?(对齐空间使图文可比;各类 prompt 的嵌入向量)
- 为什么 prompt 集成有效、收益为何递减?(多视角消解 prompt 偏差;覆盖同类语义后饱和)
- 温度可学习化在训练中起什么作用?(自适应难度:早期拉近粗对齐,后期聚焦难样本)
- CLIP 在计数/空间关系上为什么弱?(训练目标是全局对齐,监督信号不要求局部结构理解)
- 用 CLIP 做数据过滤的系统性风险是什么?(过滤偏差会烙进下游模型——“谁定义了好数据”成为权力,也是研究题)
- batch 32768 除了算力还防什么问题?(对比学习需要足够负样本密度;小 batch 排斥力不足,学不到细粒度区分)
6. 动手作业(项目交付标准)
- 跑通 3.1,基线 acc 记入 README;
- prompt sweep:5 → 20 → 50 模板三档 acc 曲线(wandb 或 matplotlib 图贴 README);
- 检索 demo 出 5 张结果拼图;
- 加做:zero-shot 迁移到你自己挑的细粒度数据集(如 8.1 的 WikiArt 流派分类,21 类),对比论文报告的水平——顺手完成 8.1 作业 2 的升级版;
- README 里写一节”失败与怪癖”:找到至少 1 个 CLIP 分类翻车的例子并分析原因(用 1.5/8.1 的语言)。
7. 延伸资源
- CLIP 论文(Learning Transferable Visual Models From Natural Language Supervision)+ 李沐精读一期
- open_clip repo + 文档——model zoo 里 ViT-B/32 → ViT-L → SigLIP 逐个玩
- LAION-5B 论文泛读——数据引擎视角看 CLIP
