如何用 CLIP 实现零样本图像分类:类名写成一句话,不标一张图也能出第一次预测
2026/9/18 20:49:18 网站建设 项目流程

如何用 CLIP 实现零样本图像分类:类名写成一句话,不标一张图也能出第一次预测

【免费下载链接】CLIPCLIP (Contrastive Language-Image Pretraining), Predict the most relevant text snippet given an image项目地址: https://gitcode.com/GitHub_Trending/cl/CLIP

分类需求到了,标注却还没开始:传统分类器要先攒几千张标好的图,ImageNet 一个数据集就是 128 万张。CLIP(Contrastive Language-Image Pretraining)不需要任何标注:把每个类别写成一句英文,图片过一遍,直接输出各类别的概率。官方 README 给出的依据是:不借助 ImageNet 任何一张标注样本,它的零样本表现已对齐原版 ResNet-50。

CLIP 如何做零样本图像分类:机制与标注流程的差异

CLIP 是一个"双塔"模型:视觉侧支持 ResNet(RN 系列)与 Vision Transformer(ViT 系列)两种骨干,文本侧是 Transformer 编码器,实现细节见 clip/model.py。两座塔在大规模公开图文对数据上联合训练——来源含网络爬取与 YFCC100M 等数据集,model-card.md 有记载——目标是让配对图文的向量靠近、错配的远离。

推理时不做任何训练:图片过视觉塔得到图像向量,每个类别的句子过文本塔得到文本向量,两个向量的余弦相似度(再乘一个可学习温度系数,初始值np.log(1/0.07))就是匹配分数,softmax 之后所有类别概率和为 1。所谓"分类器"就是你自己写的一堆文字,改文字等于改分类器。

对比维度传统监督分类CLIP 零样本
标注成本数千到百万张标注图(ImageNet 128 万张)0,写类别名句子即可
新增类别重新采数据、重训模型换一句话,立即生效
任务形态固定类别集合可当"以文搜图":与任意句子做匹配
细粒度判别数据充足时上限高官方 model card 承认细粒度分类、计数是弱项

一句话定位:类别集合固定、要榨 top-1 极限精度,传统监督仍是主路;类别少而杂、或要求新类别当天生效,CLIP 的零标注是更省事的选项。

如何跑通 CLIP 零样本分类:从安装到第一次预测 🚀

依赖很少:PyTorch 1.7.1 及以上、torchvision,外加 ftfy、regex、tqdm、packaging 四个小库(清单在 requirements.txt)。先装好 torch 系,再克隆仓库并把本仓库作为包安装,-e是 editable 安装:

git clone https://gitcode.com/GitHub_Trending/cl/CLIP pip install -e CLIP

首次推理会下载权重文件(数百 MB)并缓存在~/.cache/clip,这一步需要联网。

第一次预测直接用仓库自带的 CLIP.png 当测试图,候选句子给三个,看哪个概率最高:

import torch import 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)

preprocess是随模型返回的变换:缩放到模型输入分辨率(多数模型为 224)、中心裁剪、归一化;图像走它、文本走clip.tokenize,记住这一条即可。跑对了会看到[[0.9927937 0.00421068 0.00299572]]a diagram拿到 99.3%——这张图本身就是一张结构图,说明环境通了。想交互式把玩,仓库附带 notebooks/Interacting_with_CLIP.ipynb,从相似度计算到零样本分类完整演示了一遍。

CLIP 核心参数怎么设:load 与 tokenize 的默认值和改法

实际接触的参数集中在 clip/clip.py 的available_modelsloadtokenize三个函数上:

参数默认值作用何时改
load 的name"ViT-B/32"选哪套权重;available_models()可列出全部 9 种,从 RN50 到 ViT-L/14@336px无 GPU 选 RN50(ResNet 骨干);GPU 有富余选 ViT-B/16 或更大
load 的device自动:有 cuda 用 cuda,否则 cpu模型放到哪块设备CPU 会被源码自动转 float32,一般不动
load 的download_root~/.cache/clip权重缓存目录内网离线:把name指成本地 .pt 路径,load支持本地文件
tokenize 的context_length77文本序列长度,所有 CLIP 模型都是 77基本不用改
tokenize 的truncateFalse文本超过 77 token 时直接抛 RuntimeError类名是长句时置 True

可直接落地的结论:默认姿势就是clip.load("ViT-B/32")一行,只有"没有 GPU"和"离线"两种情况需要各改一个参数。

如何验证 CLIP 零样本分类效果:看哪个指标,分档怎么提升

用 CIFAR-100 的 100 个类别做验证场景(官方 README 有现成示例):100 类全部统一写成a photo of a xxx,任取一张图,看 top-5 概率。判断效果看两个指标:top-1 是否命中真实类别、以及它的概率值高低。下面代码取第 3637 张:

from torchvision.datasets import CIFAR100 cifar100 = CIFAR100(root="~/.cache", download=True, train=False) image, _ = cifar100[3637] image_input = preprocess(image).unsqueeze(0).to(device) text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in cifar100.classes]).to(device) with torch.no_grad(): img_f = model.encode_image(image_input) txt_f = model.encode_text(text_inputs) img_f /= img_f.norm(dim=-1, keepdim=True) txt_f /= txt_f.norm(dim=-1, keepdim=True) sim = (100.0 * img_f @ txt_f.T).softmax(dim=-1) print(sim[0].topk(5))

输出与 README 一致:snake 65.31%、turtle 12.29%、sweet_pepper 3.83%、lizard 1.88%、crocodile 1.75%,top-1 命中(这张图正是蛇)。不满意时按成本从低到高走三档:

  1. 改句子(零成本):所有类别共用一个模板,只替换类名;单类别可写 2~3 个模板再对概率取平均。仓库自带 data/prompts.md,26 个数据集的官方提示词可直接抄。
  2. 线性探针(需少量标注,CPU 可训):冻结模型,先把训练集过一遍encode_image提取特征存盘,再只训一个逻辑回归头。README 的 CIFAR-100 示例用的是LogisticRegression(C=0.316, max_iter=1000),注释提醒 C 要用验证集调出来。
  3. 换更大模型(只改一个字符串)ViT-B/32ViT-B/16ViT-L/14,骨干越大算力开销越大,按硬件与实测精度取舍。

CLIP 报错时怎么办:5 个常见现象与排查

  • 首跑卡住或报网络错误— 原因:权重文件首次从 CDN 拉取,源码_download会复核 SHA256,不一致就抛 RuntimeError;解法:手动把 .pt 文件放进~/.cache/clip,或把loadname参数指到本地文件(源码明确支持)。
  • 报 "Input ... is too long for context length 77"— 原因:tokenizetruncate默认 False,句子超过 77 个 token 直接中断;解法:传truncate=True,或把类别描述写短。
  • 报 "Expected all tensors to be on the same device"— 原因:clip.tokenize返回的文本张量在 CPU 上,忘了.to(device);解法:图像与文本计算前移到同一设备。
  • 中文类名概率明显偏低— 原因:词表按英文 BPE 构建(实现见clip/simple_tokenizer.py),model card 也声明该模型只针对英文场景;解法:用英文类名,展示层再映射回中文标签。
  • 细粒度类别(上百鸟种、车款)或计数任务不准— 原因:model card 明确把细粒度分类、计数列为已知短板;解法:先降低类别粒度,或补少量标注走线性探针。

下一步:先复现第三节对 CLIP.png 的"自我分类"确认环境无误,再换成自己的图像与类别句子,拿到零样本基线;想再提精度,就照 README 的 "Linear-probe evaluation" 一节,把 CIFAR-100 示例套到自己的数据集上跑一遍。

【免费下载链接】CLIPCLIP (Contrastive Language-Image Pretraining), Predict the most relevant text snippet given an image项目地址: https://gitcode.com/GitHub_Trending/cl/CLIP

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询