Zero-shot 深度解析:经典零样本学习、LLM 零样本与「预训练语义空间」的贯通

本文系统梳理经典零样本学习(ZSL)与大语言模型(LLM)零样本的共性机制,提出以预训练语义空间为核心的统一抽象:输入x和未见标签y均映射至共享空间S,通过双编码器+相似度打分实现零样本泛化。重点剖析CLIP的对比对齐范式、DAP/DeViSE/InfoNCE等数学形式,并涵盖GZSL偏见校正、评估协议(H指标)、prompt与模板工程等关键技术要点。

0 · 导读:一条把两条路线焊在一起的铁律

Zero-shot(零样本)的字面意思很简单:测试/推理时面对的「类别」或「任务」,在训练阶段一个样本都没见过。但「没见过类别」不等于「没见过相关信号」——这是理解零样本的全部钥匙。两条历史路线其实在做同一件事:

零样本 = 借助一个训练时见过、但任务标签未见过的「语义空间」,把输入和「未见过的标签/任务」对齐,从而在不更新权重的前提下做预测。

  • 经典 ZSL(视觉为主):训练时见过「马、老虎、熊猫」和一组属性(有毛/会飞/水生/体型…)。测试时给一个从没见过的类「斑马」,但给了它的属性向量——模型靠「属性」这个语义空间,把「带条纹的马」这种没见过的类对齐到输入上。
  • LLM 零样本(语言为主):模型在预训练时见过海量文本,但没为「情感分类」这任务调过参数。推理时你用自然语言描述任务(“这句话是正面的吗?”),模型靠「语言」这个语义空间,把任务对齐到下一词预测的分布上。

两条路线的差异只是「语义空间」的来源不同(人工属性 vs 语言 token),底层机制是同构的:都归结为 score(x, y) = sim(enc_x(x), enc_y(y))。第 4 节会把这个同构讲透,第 6 节用一个 numpy 玩具和第 4 节的可视化把它跑出来。

相关篇章(本系列):next-token-prediction-deep-dive(§6.3 的 ICL 贝叶斯解释是 LLM 零样本的地基)、nlp-deep-dive(词向量与语义空间)、llm-deep-dive(预训练与对齐)、bert-pretraining-deep-dive(MLM 双向表征,与 NTP 单向的对比)。


1 · 定义与统一视角

1.1 什么是「零样本」:先划清三条边界

概念 训练期是否见目标类/任务 推理期给什么 典型例子
监督学习(含标准微调) 见过 同类分布下的新样本 用带标签猫狗图训练猫狗分类器
Few-shot / ICL(少样本/上下文学习) 未见权重但提示里给少量示例 几个示例 + 查询 GPT-3 给 3 个 QA 样例再问第 4 个
Zero-shot(零样本) 未见,且提示里也不给示例 任务描述 / 类属性 / 模板 “判断这句话的情感:…”;给未见类的属性向量
Open-set recognition 见过已知类 已知类 + 「未知」兜底 人脸识别里把陌生人判为 unknown

关键区分:zero-shot 与 few-shot 都不更新权重,差别在提示里有没有示例;zero-shot 与 open-set 都被迫处理未见类别,但 open-set 只要求「认出没见过」而不要求「分到某个具体未见类」。本文的 zero-shot 取最严格的定义——测试标签空间 YtestY_{test}Ytest​ 与训练标签空间 YtrainY_{train}Ytrain​ 不相交(Ytrain∩Ytest=∅Y_{train} \cap Y_{test} = \emptysetYtrain​∩Ytest​=∅),即「真正没见过」。

1.2 统一抽象:把「输入」和「标签/任务」都塞进一个共享空间

零样本没法直接学 P(y | x)(因为训练时某些 yyy 从没出现)。解法是引入一个中间语义空间 S\mathcal{S}S,把两边都投影进去:

x→ ϕ ϕ(x)∈S,y→ ψ ψ(y)∈Sx \xrightarrow{\ \phi\ } \phi(x) \in \mathcal{S}, \qquad y \xrightarrow{\ \psi\ } \psi(y) \in \mathcal{S}x ϕ  ​ϕ(x)∈S,y ψ  ​ψ(y)∈S

预测时不再直接比较 (x,y)(x, y)(x,y),而是比较它们在 S\mathcal{S}S 里的向量靠近程度:

y^=arg⁡max⁡y∈Y  score(ϕ(x), ψ(y)),score(u,v)≜u⊤v  或  cos⁡(u,v)\hat{y} = \arg\max_{y \in \mathcal{Y}} \; \mathrm{score}\big(\phi(x),\, \psi(y)\big), \qquad \mathrm{score}(u, v) \triangleq u^\top v \;\text{或}\; \cos(u, v)y^​=argy∈Ymax​score(ϕ(x),ψ(y)),score(u,v)≜u⊤v或cos(u,v)

为什么这能实现零样本:ψ(y)\psi(y)ψ(y) 这个投影函数(属性向量、词向量、文本模板编码…)对「未见过的 yyy」同样可用——只要我们能写出「斑马」的属性或文本描述,哪怕训练时从没见过斑马图,也能把它投影进 S\mathcal{S}S 参与打分。训练只需让 ϕ\phiϕ(视觉/文本编码器)和 ψ\psiψ(语义编码器)把见过的样本对齐好,泛化到未见 yyy 由「共享空间」保证。

1.3 两条路线,一种机制:实例化对照

维度 经典 ZSL LLM 零样本
输入编码器 ϕ\phiϕ CNN / ViT(图像→向量) Transformer(token→向量)
语义编码器 ψ\psiψ 人工属性向量 / 词向量 / 文本描述编码 自然语言模板 → token 分布
语义空间 S\mathcal{S}S 属性空间(如 85 维 AWA 属性)或词向量空间 语言模型隐空间 / token 概率空间
评分 ϕ(x)⊤Wψ(y)\phi(x)^\top W \psi(y)ϕ(x)⊤Wψ(y)(兼容性) 在 prompt 条件上 PPP(target token ∣\mid∣ context)
未见信息来源 类的属性/词向量(标注或外部知识库) 预训练语料里蕴含的任务描述
典型失败 属性噪声、hubness、GZSL 偏见 prompt 敏感、calibration 差、推理短板

1.4 与相邻概念划界

  • Transfer learning / 域适应:源域有标签、目标域有(或无)标签,但标签空间通常相同;zero-shot 强制标签空间不同。
  • Domain generalization:标签空间相同,只是测试分布偏移;zero-shot 没有「见过同类标签」这回事。
  • Metric learning / 检索:都在学一个空间里的距离,但检索不要求「训练时没见过查询类」。

2 · 经典零样本学习(ZSL)

2.1 属性基方法:DAP 与 IAP

Lampert et al. 2009 / 2014 的开创性工作把 ZSL 形式化为属性转移:每个类由一组语义属性描述(「有毛」「会飞」「水生」…)。两类推断策略:

  • DAP(Direct Attribute Prediction,直接属性预测):先学每个属性的二分类器 P(a∣x)P(a \mid x)P(a∣x),再聚合:

    P(y∣x)=∑aP(y∣a) P(a∣x)P(y \mid x) = \sum_{a} P(y \mid a)\, P(a \mid x)P(y∣x)=a∑​

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

reset2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值