0 张标注跑通图像分类:CLIP 让"看一句英文就能分类"的完整落地指南
【免费下载链接】CLIPCLIP (Contrastive Language-Image Pretraining), Predict the most relevant text snippet given an image项目地址: https://gitcode.com/GitHub_Trending/cl/CLIP
标注 ImageNet 要 1.28M 张人工打标的图,而 CLIP 一张标注都不用——你只写一句a photo of a snake,它就能把 CIFAR-100 的图判成 65% 概率是蛇。核心关键词:CLIP 零样本图像分类。
读完你能拿到什么
- 实现3 行代码的零样本分类,用 1 张图实测跑出 3 个类别概率。
- 避开重新标注数据的成本,理解"提示词"为什么能顶替标签。
- 定位9 个可选模型(
clip.available_models())里该选哪个、何时换提示词。 - 跑通一段官方线性探针(linear probe)代码,把 CLIP 特征接上逻辑回归。
一分钟看懂它为什么行
传统 CNN 是"喂 128 万张图、学死类别编号",换类别就要重训。CLIP 换了个思路:
- 两个编码器一个空间:图像和文字分别被编码成同一维度的向量(
clip/model.py里的encode_image/encode_text,投影到相同embed_dim)。 - 对比训练对齐语义:用 4 亿图文对拉近"匹配的"、推远"不匹配的",所以分类变成"图像向量 vs 候选文本向量谁更像"。
- 分类=匹配打分:
model(image, text)返回余弦相似度×温度(初始logit_scale = 1/0.07),softmax 即概率——标签只是你临时写的一句话,改句子就是改类别。
5 分钟跑通第一个结果
先装依赖,再把仓库当 Python 包装上(首次clip.load会自动下载模型到~/.cache/clip):
pip install ftfy regex tqdm pip install git+https://gitcode.com/GitHub_Trending/cl/CLIP最小可运行片段(README.md里的官方示例,直接复现):
import torch, clip from PIL import Image device = "cuda" if torch.cuda.is_available() else "cpu" model, preprocess = clip.load("ViT-B/32", device=device) # 加载模型+预处理 image = preprocess(Image.open("CLIP.png")).unsqueeze(0).to(device) # 图像 text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device) # 文本候选 with torch.no_grad(): probs = model(image, text)[0].softmax(dim=-1).cpu().numpy() print("Label probs:", probs)预期输出(README 实测值,不同设备略有出入):
Label probs: [[0.9927937 0.00421068 0.00299572]]一张架构图被判成a diagram概率 0.99,另外两类几乎为 0——这就是零样本的正反馈。
效果说话:零样本 vs 传统监督
| 维度 | CLIP 零样本(ViT-B/32) | 传统 ResNet50 监督 |
|---|---|---|
| 标注数据量 | 0 张(只用类别名文本) | 1.28M 张(ImageNet) |
| ImageNet 精度 | 与 ResNet50 打平(README 原文结论) | 基线 |
| CIFAR-100 零样本 top-1 示例 | snake 65.31%(README 可复现) | 需在该集上重训 |
| 新增一个类别 | 改一句英文提示词,秒级生效 | 采集+标注+重训,天级 |
| 依赖条件 | 一句可描述的英文类别名 | 该类足量标注样本 |
让效果再翻倍的 3 个技巧
- 换描述式提示词。裸类名
snake不如模板a photo of a snake(README 的 CIFAR-100 例子就用a photo of a {c})。做法:给类别名套一层场景前缀,再喂clip.tokenize。 - 多模板做集成。仓库 data/prompts.md 里 CIFAR-10 给了 18 条模板(
a blurry photo of...、a black and white photo of...)。做法:对每条模板算概率再平均,抗单句偏差。 - 有标注就接线性探针。别全量微调——冻结 CLIP,只对
encode_image的特征训练逻辑回归。README 官方代码用LogisticRegression(C=0.316),少量样本即可,改动最小。
踩坑实录
现象RuntimeError: Input ... is too long for context length 77→ 原因:提示词超过 77 token(clip/clip.py的tokenize)。 → 解法:缩短描述,或clip.tokenize(texts, truncate=True)自动截断。
现象RuntimeError: Model xxx not found; available models = [...]→ 原因:clip.load传了不存在的模型名。 → 解法:先print(clip.available_models())查表,共 9 个,从RN50到ViT-L/14@336px。
现象 无 GPU 时 CPU 上ViT-L/14慢到怀疑人生→ 原因:模型越大 CPU 推理越慢,且默认会尝试cuda。 → 解法:CPU 环境显式device="cpu",起步选ViT-B/32或RN50;另确认torch>=1.7.1(否则clip.py顶部会发版本警告)。
落地清单
- 明天先做:
pip install装好,跑通上面 3 行零样本片段,拿到Label probs正反馈。 - 确认
clip.available_models(),按有无 GPU 选定起点模型(有卡用 ViT-B/16,无卡用 RN50)。 - 把你的类别名改写成
a photo of a {class}形式,跑一版看概率分布是否合理。 - 若手里有几十~几百张标注:照 README "Linear-probe" 示例接
LogisticRegression,别直接微调整网。 - 需要更稳的分类时,翻 data/prompts.md 做多模板集成。
结尾
CLIP 把图像分类从"堆标注样本"变成"写一句英文提示词",零样本即可上手、少量标注即可接线性探针微调。想继续深入,读 notebooks/Interacting_with_CLIP.ipynb 里完整的交互式分类示例,或把 data/prompts.md 的提示词库接到你的领域里试。
【免费下载链接】CLIPCLIP (Contrastive Language-Image Pretraining), Predict the most relevant text snippet given an image项目地址: https://gitcode.com/GitHub_Trending/cl/CLIP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考