迁移学习(七):零样本学习
从第一性原理推导零样本学习:DAP 属性原型、双线性与深度兼容性函数、DeViSE、生成式 ZSL 的 f-CLSWGAN、广义 ZSL 的偏置问题与校准方法,以及 CLIP 这种视觉-语言预训练带来的范式跃迁,附 PyTorch 核心实现。
你这辈子没见过斑马。但我告诉你它"长得像马,身上画了黑白条纹",下次走进动物园你一眼就能认出来。没标注样本、没有微调,只有一座语义桥梁把你已知的概念(马、条纹)和未知的物种连了起来。
零样本学习(Zero-Shot Learning, ZSL) 就是把这个本事教给机器。在一批已见类(seen classes) 上做有监督训练,测试时却要识别一组完全不重叠的未见类(unseen classes) —— 模型对未见类的唯一线索,是它们的语义描述:一组属性、类别名的词嵌入、一段文字、或者一句 CLIP 风格的提示语。模型能不能成功,全看它在共享的视觉-语义空间里学到了什么样的几何结构。
本文从一个公式出发 —— 图像与类别描述之间的兼容性函数 $F(x, c)$ —— 把过去十五年里出现的主流方法依次串起来:属性原型、双线性和深度兼容性、生成式特征合成、广义零样本学习的校准方法,以及 CLIP 这种把整个 ZSL 问题"用规模化"几乎吞掉的范式。
你将学到什么
- ZSL 的形式化定义、已见 / 未见类划分
- 属性表示与直接属性预测(DAP)
- 兼容性函数:双线性、深度、排序损失(DeViSE、ALE)
- 生成式 ZSL(f-CLSWGAN、f-VAEGAN-D2):把 ZSL 重新变回有监督学习
- 广义零样本学习(GZSL) 为什么离开校准就崩溃,以及三类修法
- CLIP:当今最有效、最易扩展的答案
前置知识
- 本系列第 1–6 部分(尤其第 4 部分小样本学习、第 6 部分多任务学习)
- PyTorch、softmax / 交叉熵训练
- Word2Vec / GloVe 等词嵌入,以及对 GAN 的基本印象
1. 问题定义
记 $\mathcal{C}^s$ 为已见类集合(有标注训练数据),$\mathcal{C}^u$ 为未见类集合(一张标注图都没有)。ZSL 的标志性约束是
$$ \mathcal{C}^s \cap \mathcal{C}^u = \emptyset. $$每个类别 $c$ —— 不管见过没见过 —— 都对应一个语义描述向量 $a_c \in \mathbb{R}^M$。这是已见类的信息能够"渗透"到未见类的唯一通道。它可以是:
- 二值或连续的属性向量(如 有条纹、有翅膀、水生);
- 类别名的词嵌入(Word2Vec、GloVe);
- 一段百科文字的句嵌入(BERT [CLS]);
- 视觉-语言模型里的提示语嵌入(CLIP)。
随后再分两种任务设定:
| 设定 | 测试标签空间 | 现实程度 |
|---|---|---|
| 经典 ZSL | $y \in \mathcal{C}^u$ | 简单基准;事先就知道测试图属于未见类。 |
| 广义 ZSL(GZSL) | $y \in \mathcal{C}^s \cup \mathcal{C}^u$ | 真实部署场景;难度高得多,因为模型天然偏向已见类。 |
把后面所有方法贯穿起来的就一个公式 —— 兼容性函数:
$$ F: \mathcal{X} \times \mathcal{C} \to \mathbb{R}, \qquad \hat{y} = \arg\max_{c \in \mathcal{C}_{\text{test}}} F(x, c; \theta). $$我们在已见类上学这个函数,然后指望语义空间的几何关系把它延拓到未见类。

2. 属性表示与 DAP
属性是最具可解释性的语义描述方式。每个属性都是人类定义的简短谓词,比如 有条纹、四条腿、有翅膀、水生。常用的 AwA2(Animals with Attributes 2) 给 50 类动物各分配了 85 维属性向量;细粒度鸟类数据集 CUB-200-2011 用了 312 维属性。
把所有类别的属性向量堆起来,就得到一个 $|\mathcal{C}| \times M$ 的属性原型矩阵。例如:
$$ a_{\text{斑马}} = (\underbrace{1}_{\text{条纹}}, \underbrace{1}_{\text{四条腿}}, \underbrace{0}_{\text{翅膀}}, \underbrace{1}_{\text{蹄子}}, \ldots). $$直接属性预测(DAP)
Lampert 等人 2009 年的工作 —— 也就是把现代 ZSL 这个问题正式立起来的那篇 —— 提出了一个非常清爽的两阶段流程:
阶段一:在已见类图像上,为每个属性单独训练一个二分类器:
$$ \hat{a}_m(x) = P(\text{属性 } m \mid x), \qquad m = 1, \ldots, M. $$阶段二:测试时把 $M$ 个属性分类器全跑一遍得到 $\hat{a}(x)$,再选与之最近的未见类原型:
$$ \hat{y} = \arg\min_{c \in \mathcal{C}^u} d\bigl(\hat{a}(x),\, a_c\bigr). $$举个例子:查询是一张斑马图。属性分类器在 有条纹、四条腿、有蹄子、有鬃毛 上输出高分,在 翅膀、水生 上输出低分。把 $\hat{a}(x)$ 跟原型矩阵做余弦相似度,斑马 排第一,马 和 老虎 紧随其后。

为什么能 work: 属性分类器之所以能迁移,是因为属性本身在不同类别之间是共享的。“条纹"这个谓词,对斑马(未见类)和老虎(已见类)来说是同一件事。
为什么不够好:
- 误差累积。属性分类器哪怕 90% 准确,$\hat{a}(x)$ 也是有噪声的,最近邻搜索还会把噪声放大。
- 属性独立性假设。DAP 默认在给定类别后属性互相独立,但 有翅膀 和 会飞 显然高度相关。
- 标注成本。属性体系本身要专家定义、专家标注。
变体 IAP(Indirect Attribute Prediction) 反过来先预测已见类的概率分布、再通过属性矩阵转到未见类,但结构性局限依旧。
3. 兼容性函数:一个统一视角
不再把"预测属性"作为中间步骤,而是端到端地学 $F(x, c)$。
双线性(ALE / SJE)
最简单的形式是双线性:
$$ F(x, c) = \phi(x)^\top W\, a_c, $$其中 $\phi(\cdot)$ 是 CNN 主干输出的 $d$ 维视觉特征,唯一的可训练参数是 $W \in \mathbb{R}^{d \times M}$。在已见类上用标准的 softmax 交叉熵训练:
$$ \mathcal{L}(x, y) = -\log \frac{\exp F(x, y)}{\sum_{c \in \mathcal{C}^s} \exp F(x, c)}. $$Akata 等人的 ALE(2013)和 SJE(2015)把交叉熵换成了结构化排序损失 —— 要求正确类别的得分比每个错误类别至少高一个间隔 —— 实测上对未见类的泛化要明显好于普通 softmax。
深度兼容性 / 双塔
为捕获非线性的视觉-语义关系,用两个小 MLP 把两边都投到 $d$ 维共享空间:
$$ F(x, c) = \frac{f_v(\phi(x))^\top f_s(a_c)}{\|f_v(\phi(x))\|\, \|f_s(a_c)\|} \cdot \tau, $$其中 $\tau$ 是可学习的温度。这种双塔结构,正是 DeViSE、CLIP、以及现代稠密检索的同一套骨架,区别只在数据规模。

几何图景就是整个 ZSL 的全部直觉。训练时已见类的视觉特征围着对应的语义原型聚拢(马、猫、狗);未见类的原型(斑马、狮子、熊猫)纯靠语义自己摆位置。一张查询图投到同一个空间里,落在最接近自己语义内容的未见类原型旁边 —— 那就是预测。
DeViSE:用词嵌入做语义侧
Frome 等人(2013)提出的 DeViSE(Deep Visual-Semantic Embedding)把人工属性换成了类别名的词嵌入(Word2Vec / GloVe)。架构是双塔,损失是 hinge 排序:
$$ \mathcal{L} = \sum_{c' \neq y} \max\bigl(0,\; m - F(x, y) + F(x, c')\bigr), $$推断时与所有类别嵌入算分,包括从没看过任何图像的类别。

DeViSE 第一次证明了 ZSL 是可以扩展的:在 ImageNet 上训出的模型,能对 WordNet 里数万个零样本类别给出像样的预测。它的弱点是词嵌入编码的是语言相似性(猫、狗、宠物 聚一起),而不是视觉相似性(按视觉应当聚成一堆的 斑马、老虎、美洲豹 —— 都有条纹 —— 在词向量里反而散开)。这种模态鸿沟(modality gap) 直接催生了后面所有的工作。
4. 生成式 ZSL:直接合成未见类的视觉特征
判别式 ZSL 学一个固定的兼容性函数,然后指望它能延拓。生成式 ZSL 反过来想:直接用语义描述合成未见类的视觉特征,再用合成特征 + 真实已见特征训一个完全普通的有监督分类器。ZSL 又变回了有监督学习。
f-CLSWGAN(Xian et al., 2018)
一个带分类器引导的条件 Wasserstein GAN:
- 生成器 $G(z, a_c) \to \tilde{x}$。输入:噪声 $z \sim \mathcal{N}(0, I)$ 和类别语义 $a_c$;输出:合成的 CNN 特征。
- 评论家 $D(x)$ 给真实 / 合成特征打分(无 sigmoid,Wasserstein 损失)。
- 辅助分类器 $\mathrm{cls}$ 接在生成特征上,由真实已见类特征训练得到。
总目标是
$$ \mathcal{L} = \underbrace{\mathbb{E}[D(\tilde{x})] - \mathbb{E}[D(x)] + \lambda\,\mathrm{GP}}_{\text{WGAN-GP}} \;+\; \beta \cdot \underbrace{\mathbb{E}\bigl[-\log P(y \mid \tilde{x})\bigr]}_{\text{分类损失}}, $$其中 $\mathrm{GP}$ 是标准的梯度惩罚 $\mathbb{E}[(\|\nabla_{\hat{x}} D(\hat{x})\|_2 - 1)^2]$。分类损失是关键 —— 它逼着合成特征不仅"像真”,还要类别可分。
测试时:对每个未见类采样 $\tilde{x}^{(u)} \sim G(z, a_u)$,把 $\{(x, y) : y \in \mathcal{C}^s\} \cup \{(\tilde{x}^{(u)}, u)\}$ 喂进 softmax 训一个普通分类器即可。仅这一步,AwA2 上 GZSL 的调和平均 $H$ 就能从约 22 跳到约 58。
f-VAEGAN-D2
Xian 等人(2019)在前者基础上加了一个 VAE 编码器稳定训练,又加了第二个判别器利用未标注的测试图像(transductive)。“VAE 稳训练 + GAN 提质量 + 分类器保可分"这套配方,目前已经是特征生成式 ZSL 的标配。
5. 广义零样本学习:偏置问题
经典 ZSL 基准把测试标签空间限制在 $\mathcal{C}^u$ 内,等于偷偷绕开了真正的难点:实际部署时,你根本不知道一张图属于已见类还是未见类。
把标签空间放开到 $\mathcal{C}^s \cup \mathcal{C}^u$ 后,所有只在已见类图像上训出来的模型都会出现严重的已见类偏置。已见类的视觉特征落在 $F$ 已经熟悉的区域里;未见类的特征略显分布外,几乎一定输掉 argmax。
标准评估指标是已见准确率与未见准确率的调和平均数:
$$ H = \frac{2 \cdot S \cdot U}{S + U}. $$它会惩罚任何"赢了一边、输了另一边"的方法。一个 $S=88, U=12$ 的模型,$H$ 只有 21 —— 极差。

三类修法:
1. 校准堆叠(Chao et al., 2016)。 把所有已见类的得分整体减去一个常数:
$$ F_{\text{cal}}(x, c) = F(x, c) - \gamma \cdot \mathbb{1}[c \in \mathcal{C}^s]. $$$\gamma$ 在验证集上搜一下就行。便宜、有效,是最先该尝试的强基线。
2. 生成式特征合成(见第 4 节)。一旦能合成未见类特征,GZSL 就退化成了一个数据均衡的有监督分类问题。
3. OOD 门控。 训一个二分类检测器判断"这张图到底属于已见还是未见”,再路由到对应的子分类器。整体性能受限于这个 OOD 检测器本身。
6. CLIP 与视觉-语言预训练时代
回过头看,CLIP(Radford et al., 2021)就是第 3 节那种深度双塔兼容性函数 —— 只不过训练数据是从网络爬来的 4 亿张图文对,损失是双向对比交叉熵:
$$ \mathcal{L} = -\sum_i \log \frac{\exp\bigl(I_i \cdot T_i / \tau\bigr)}{\sum_j \exp\bigl(I_i \cdot T_j / \tau\bigr)} \;+\; (\text{在文本一侧对称地再来一遍}). $$零样本推断时,用文字现场搭分类器。给定 $K$ 类问题,写一个提示模板(如 "a photo of a {class}"),把 $K$ 个提示喂给文本塔得到 $K$ 个文本向量,新图像走视觉塔得到一个图像向量,谁的余弦相似度最高就预测谁。

两点值得记住的影响:
- 不再需要语义工程。类别用自然语言描述。要新增一个类?写一句话就行。
- GZSL 不再是独立问题。CLIP 在它"训过"和"没训过"的类别上准确率相当,因为它从一开始就不是按类别判别的方式训练出来的。
基准曲线印证了这条主线:

DAP(2009)→ ALE / DeViSE(2013):双线性与排序兼容性;SAE(2017):语义自编码器;f-CLSWGAN(2018)→ CADA-VAE(2019):生成式特征合成关闭了 GZSL 的差距;CLIP(2021):大规模对比预训练把上限推向了新的高度。
7. 实现
下面是深度兼容性模型和特征生成 GAN 的精简 PyTorch 骨架,足够看清楚结构。完整训练脚手架(AwA2 数据加载、ZSL 与 GZSL 评估)在文末参考实现里。
| |
gzsl_evaluate 里的 gamma 就是校准堆叠 —— GZSL 上首先该试的最简修法。
8. Q&A
Q1:什么时候选 ZSL,而不是小样本或主动学习? 满足以下任一条件就可以考虑:(a) 长尾类别又宽又不稳定,新类来得比标注还快;(b) 你已经有现成的丰富语义资源,比如属性体系、商品目录、文字描述;(c) 你能直接用上预训练的视觉-语言模型(CLIP、SigLIP、OpenCLIP),那干脆跳过 ZSL 专用机器,直接用 CLIP 推断。
Q2:属性、词嵌入、句嵌入、CLIP 提示,到底用哪个? 属性单维信息量最大但需要专家设计;词嵌入扩展性好但编码的是语言相似而非视觉相似;句嵌入是个折中;CLIP 提示在大多数自然图像基准上压倒所有低层方法 —— 因为它的视觉、文本编码器是联合训练的。
Q3:GZSL 为什么不校准就崩? 训练目标只奖励已见类的正确预测,已见和未见 logit 之间没有任何尺度对齐。测试时已见类得分系统性更高,几乎每次都抢走 argmax。校准堆叠、生成合成、OOD 门控本质上都在攻这个不平衡。
Q4:CLIP 之后,传统 ZSL 研究还有意义吗? 对自然图像:基本没有了。但对开源数据稀缺的领域 —— 医学影像、工业缺陷、遥感图 —— 老一套属性 / 语义机制仍然是数据效率最高的冷启动方式。而且 CLIP 本身就是一个深度双塔兼容性模型,本文搭建的概念框架仍然完全适用。
Q5:怎么避开 Hubness 问题? Hubness 是高维空间的病态:少数"枢纽"原型成了太多查询的最近邻。常见做法:打分前在两侧都做 L2 归一化(上面代码里已有);用基于排名的相似度(CSLS、ZestNorm);或对每个类别的得分做标准化。
参考文献
- Lampert, C. H., Nickisch, H., & Harmeling, S. (2009). Learning to detect unseen object classes by between-class attribute transfer. CVPR. —— DAP,AwA 数据集。
- Frome, A., et al. (2013). DeViSE: A deep visual-semantic embedding model. NeurIPS.
- Akata, Z., Perronnin, F., Harchaoui, Z., & Schmid, C. (2013). Label-embedding for attribute-based classification. CVPR. —— ALE。
- Chao, W.-L., et al. (2016). An empirical study and analysis of generalized zero-shot learning for object recognition in the wild. ECCV. —— GZSL 与校准堆叠。
- Xian, Y., Lampert, C. H., Schiele, B., & Akata, Z. (2019). Zero-shot learning — A comprehensive evaluation of the good, the bad and the ugly. TPAMI.
- Xian, Y., Lorenz, T., Schiele, B., & Akata, Z. (2018). Feature generating networks for zero-shot learning. CVPR. —— f-CLSWGAN。
- Xian, Y., Sharma, S., Schiele, B., & Akata, Z. (2019). f-VAEGAN-D2: A feature generating framework for any-shot learning. CVPR.
- Schönfeld, E., et al. (2019). Generalized zero- and few-shot learning via aligned variational autoencoders. CVPR. —— CADA-VAE。
- Radford, A., et al. (2021). Learning transferable visual models from natural language supervision. ICML. —— CLIP。
系列导航
| 部分 | 主题 |
|---|---|
| 1 | 基础与核心概念 |
| 2 | 预训练与微调 |
| 3 | 域适应 |
| 4 | 小样本学习 |
| 5 | 知识蒸馏 |
| 6 | 多任务学习 |
| 7 | 零样本学习(本文) |
| 8 | 多模态迁移 |
| 9 | 参数高效微调 |
| 10 | 持续学习 |
| 11 | 跨语言迁移 |
| 12 | 工业应用与最佳实践 |