Transformers 零样本图像分类实战指南:pipeline 一行推理与手动实现全解析
2026/9/11 20:36:55 网站建设 项目流程

Transformers 零样本图像分类实战指南:pipeline 一行推理与手动实现全解析

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

零样本图像分类(Zero-shot image classification)是 🤗 Transformers 中一项基于多模态模型的视觉分类任务:它允许用户无需任何微调,仅凭自由文本描述即可将图像划分到全新、未见过的类别中。本文以 docs/source/ja/tasks/zero_shot_image_classification.md(与 英文原版 内容一致)为主体,讲解如何用一行pipeline完成推理、如何手动拆解推理全过程,并结合当前仓库源码剖析其底层工作原理。读完你将掌握零样本图像分类的完整实战路径,并能自行切换候选标签与模型。

零样本图像分类是什么

传统图像分类的流程是:先在带标注的固定类别数据集上训练模型,让模型学会把「图像特征」映射到「标签」。一旦遇到一组全新的标签,就必须通过微调(fine-tuning)重新校准模型,成本高且周期长。

零样本(或称为开放词汇,open vocabulary)图像分类则完全不同。这类模型通常是在多模态数据集(海量图像 + 相关描述文本)上预训练的,例如 CLIP 系列。训练过程中,模型学习到的是对齐后的视觉-语言表示(aligned vision-language representations)——图像特征与文本特征被投影到同一个向量空间,语义相近的图像与文本在空间中彼此靠近。这种表示能力可以被迁移到包括零样本图像分类在内的众多下游任务上。

因此,零样本图像分类是一种更灵活的范式:模型可以泛化到从未见过的新类别,无需额外训练数据;用户可以用自由形式的文本描述去查询目标对象,分类边界完全由提示词决定。

准备工作:安装依赖

动手前先安装必要库。文档给出的最小安装命令为:

pip install -q "transformers[torch]" pillow

其中transformers[torch]附带 PyTorch 后端,pillow用于图像解码与预处理。如果你已经安装了完整的 Transformers 环境,这两者通常已就绪。

方法一:使用 Zero-shot image classification pipeline

最快捷的推理方式是调用 Transformers 内置的 [pipeline] 接口,它会自动完成「加载模型 → 图像预处理 → 文本分词 → 前向计算 → 后处理排序」的全流程。

实例化 pipeline

从 Hub 上的 checkpoint 实例化一个零样本图像分类 pipeline:

>>> from transformers import pipeline >>> checkpoint = "openai/clip-vit-large-patch14" >>> detector = pipeline(model=checkpoint, task="zero-shot-image-classification")

这里显式指定了task="zero-shot-image-classification"。从当前仓库源码看,该任务 ID 对应ZeroShotImageClassificationPipeline类(见 src/transformers/pipelines/zero_shot_image_classification.py),其类文档明确指出该 pipeline 基于CLIPModel实现,输入一张图与一组candidate_labels即可预测类别。

实用提示:若 checkpoint 是零样本分类专用模型(如google/siglip-so400m-patch14-384),task参数也可省略,pipeline会自动推断。

准备输入图像

pipeline 接受三种形式的图像输入(源码__call__的 docstring 明确列出,见 zero_shot_image_classification.py):

  1. 指向图像的HTTP 链接字符串
  2. 图像的本地路径字符串
  3. 直接传入PIL 加载好的图像对象
>>> from PIL import Image >>> import requests >>> url = "https://unsplash.com/photos/g8oS8-82DxI/download?ixid=MnwxMjA3fDB8MXx0b3BpY3x8SnBnNktpZGwtSGt8fHx8fDJ8fDE2NzgxMDYwODc&force=true&w=640" >>> image = Image.open(requests.get(url, stream=True).raw) >>> image

传入候选标签并获取预测

把图像和候选对象标签一起传给 pipeline。候选标签可以是简单的单词(如"fox""owl"),也可以是更具描述性的短语(如"a red fox in the snow"):

>>> predictions = detector(image, candidate_labels=["fox", "bear", "seagull", "owl"]) >>> predictions [{'score': 0.9996670484542847, 'label': 'owl'}, {'score': 0.000199399160919711, 'label': 'seagull'}, {'score': 7.392891711788252e-05, 'label': 'fox'}, {'score': 5.96074532950297e-05, 'label': 'bear'}]

输出是按分数降序排列的列表,每个元素为{"score": float, "label": str}字典,score介于 0~1 之间。

pipeline 内部做了什么(源码级拆解)

结合 src/transformers/pipelines/zero_shot_image_classification.py 的preprocess方法,pipeline 的完整处理链路为:

  1. 加载图像load_image(image, timeout=timeout)统一将路径/URL/PIL 对象转成 PIL 图像;
  2. 图像预处理self.image_processor(images=[image], return_tensors="pt")完成 resize、归一化等操作;
  3. 提示模板包装sequences = [hypothesis_template.format(x) for x in candidate_labels],默认模板为"This is a photo of {}.",即每个候选标签都会被包装成一句完整的描述性文本(这正是零样本分类的关键——把分类问题转化为图文匹配问题);
  4. 文本分词self.tokenizer(sequences, return_tensors="pt", padding=True),其中对 SigLIP 系列模型还会额外设置padding="max_length", max_length=64, truncation=True
  5. 前向计算_forward中调用self.model(**text_inputs, **model_inputs)取出outputs.logits_per_image
  6. 后处理排序postprocess中,非 SigLIP 模型对 logits 做softmax(dim=-1)得到概率,SigLIP 模型则使用sigmoid(因为 SigLIP 是逐标签二分类式训练),最后按分数降序输出{score, label}列表。

额外参数说明(来自_sanitize_parameters__call__docstring):hypothesis_template可自定义提示模板,若候选标签本身已格式化好,传"{}"即可跳过包装;timeout控制从网络拉取图像的最大等待秒数,None表示不设超时。

方法二:手动执行零样本图像分类推理

pipeline 封装了全部细节,但理解手动流程有助于深入掌握原理,也便于在自定义训练/评估脚本中复用。

加载模型与处理器

从同一 checkpoint 加载模型与关联处理器:

>>> from transformers import AutoProcessor, AutoModelForZeroShotImageClassification >>> model = AutoModelForZeroShotImageClassification.from_pretrained(checkpoint) >>> processor = AutoProcessor.from_pretrained(checkpoint)

AutoModelForZeroShotImageClassification是当前仓库提供的自动类(定义于 src/transformers/models/auto/modeling_auto.py),它根据 checkpoint 的 config 自动路由到正确的模型类。AutoProcessor则组合了负责图像的 image processor(resize、归一化)与负责文本的 tokenizer。

准备一张新图像

>>> from PIL import Image >>> import requests >>> url = "https://unsplash.com/photos/xBRQfR2bqNI/download?ixid=MnwxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjc4Mzg4ODEx&force=true&w=640" >>> image = Image.open(requests.get(url, stream=True).raw) >>> image

用 processor 构造模型输入

processor 接受imagestext两个入口,同时完成图像预处理与文本分词:

>>> candidate_labels = ["tree", "car", "bike", "cat"] # 遵循 pipeline 的提示模板,才能得到与 pipeline 一致的结果 >>> candidate_labels = [f'This is a photo of {label}.' for label in candidate_labels] >>> inputs = processor(images=image, text=candidate_labels, return_tensors="pt", padding=True)

return_tensors="pt"表示返回 PyTorch 张量;padding=True将多条文本按最长序列补齐,便于 batch 计算。注意这行模板包装:英文原版文档特意注释了「follows the pipeline prompt template to get same results」,即手动推理时若想与 pipeline 输出完全一致,必须手动复刻默认假设模板"This is a photo of {}."(pipeline 源码中该默认值定义于preprocess方法签名,见 zero_shot_image_classification.py)。

前向传播与后处理

>>> import torch >>> with torch.no_grad(): ... outputs = model(**inputs) >>> logits = outputs.logits_per_image[0] >>> probs = logits.softmax(dim=-1).numpy() >>> scores = probs.tolist() >>> result = [ ... {"score": score, "label": candidate_label} ... for score, candidate_label in sorted(zip(probs, candidate_labels), key=lambda x: -x[0]) ... ] >>> result [{'score': 0.998572, 'label': 'car'}, {'score': 0.0010570387, 'label': 'bike'}, {'score': 0.0003393686, 'label': 'tree'}, {'score': 3.1572064e-05, 'label': 'cat'}]

这里的核心是outputs.logits_per_image:它是一张「图像 × 文本」的相似度矩阵,第i行第j列表示图像i与第j条候选文本的匹配得分。对该行做softmax即得到每个候选标签的归一化概率;sorted(..., key=lambda x: -x[0])实现按分数从高到低排序。

底层原理:CLIP 式双塔对比学习

零样本图像分类的根基在于 CLIP 式的双塔对比学习架构。以当前仓库的 src/transformers/models/clip/modeling_clip.py 为例,CLIPModel包含两个独立编码器:

  • 视觉编码器:将图像编码为image_embeds
  • 文本编码器:将描述文本编码为text_embeds

前向过程中两者被投影到同一向量空间并计算相似度,得到logits_per_text,再经转置得到logits_per_image(源码第 808 行附近)。预训练时使用image_text_contrastive_loss(定义于 modeling_clip.py)拉近「匹配的图文对」、推远「不匹配的图文对」。正是这种对齐后的表示,使模型在推理时能对任意文本标签给出合理的图像匹配分数——也就是零样本分类能力。

文档示例中checkpoint = "openai/clip-vit-large-patch14"即为该架构的代表模型。logits_per_image.softmax(dim=1)取标签概率的做法在 CLIPModel 的官方示例 docstring 中也有印证(modeling_clip.py)。

支持哪些模型

当前仓库的自动映射表MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING_NAMES(见 modeling_auto.py)列出以下模型类型可加载为AutoModelForZeroShotImageClassification

模型类型对应类
alignAlignModel
altclipAltCLIPModel
blipBlipModel
blip-2Blip2ForImageTextRetrieval
chinese_clipChineseCLIPModel
clipCLIPModel
clipsegCLIPSegModel
metaclip_2MetaClip2Model
siglipSiglipModel
siglip2Siglip2Model
tipsv2Tipsv2Model
videoprismVideoPrismClipModel

选择模型时需留意后处理差异:pipeline 对siglip系列使用sigmoid而非softmax(见 zero_shot_image_classification.py),因为 SigLIP 的训练目标是对每个标签独立做二分类。若你手动推理 SigLIP 模型,也应对应使用 sigmoid 激活。

工程实践要点与验证

候选标签设计:候选标签越贴近「这张图片是什么」的自然表述,分类越稳定。pipeline 默认假设模板为"This is a photo of {}.",描述性短语(如"a white owl perched on a branch")通常优于单个裸词。若标签已含完整句子,可传hypothesis_template="{}"关闭包装。

批处理输入:pipeline 的__call__支持传入图像列表(list[str]list[PIL.Image]),返回list[list[dict]];源码_forward中对批处理场景有专门的解包逻辑(见 zero_shot_image_classification.py),适合批量评估场景。

测试与一致性:仓库在 tests/pipelines/test_pipelines_zero_shot_image_classification.py 中提供了该 pipeline 的完整测试套件(标注为@is_pipeline_test@require_vision),覆盖多模型下的输出结构与 Hugging Face Hub 输出规范的比对(compare_pipeline_output_to_hub_spec),可作为自定义实现的正确性参考。

手动 vs pipeline 的一致性:手动推理务必复刻"This is a photo of {}."模板与 softmax/sigmoid 选择,否则分数与 pipeline 结果会存在偏差——这正是英文原版文档在第 123 行特意注释的原因。

小结

零样本图像分类将「分类」转化为「图文匹配」,让模型在无需训练数据的情况下适配任意新类别。本文覆盖了从pipeline一行推理到手动拆解推理全链路的两种路径,并借助当前仓库源码(pipeline 实现、CLIPModel 前向逻辑、自动类映射)阐明了提示模板、softmax/sigmoid、双塔对比学习等关键机制。下一步,你可以直接替换checkpointcandidate_labels在你的数据集上实验,或将上述手动流程嵌入到批量评估脚本中。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

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

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

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

立即咨询