资讯详情

资讯详情

零样本学习与少样本学习:原理、实战对比与工程选型指南

先说一个我常拿来暖场的例子给AI看一张它从没见过的动物照片比如某种只存在于神话里的生物或者一种刚被发现的深海鱼。零样本学习和少样本学习都是为了让AI在这种“没见过”的情况下还能认出东西来。但它们的“猜法”完全不同——一个靠“听说过”一个靠“看过三五张”。这篇文章就围绕这两种学习方式的区别展开我会从原理讲到代码再讲到我实际跑任务时踩过的坑。适合正在做人脸识别、物种识别、工业缺陷检测这类小样本应用的同学也适合想搞明白大模型为什么“什么都会一点”的好奇型读者。1. 先搞懂本质区别一个靠语义一个靠样例零样本学习要解决的是训练阶段模型完全没接触过目标类别的任何一张图只给一句描述或者一组属性就要在推断时认出来。少样本学习要解决的是目标类别有少量标注图通常每类一两张到十几张模型要从这“屈指可数”的样本里学会区分。说白了零样本是“没吃过猪肉但听过猪跑”的路线。模型不是靠图像样本认识“麒麟”的而是靠“龙头、鹿角、遍体鳞甲”这种语义描述在它已有的知识体系里拼出一个位置。少样本则是“给你三片猪肉尝一口”的路线虽然有样可依但样本量少到稍微过拟合就翻车。两者都在解决同一个现实问题深度学习太吃数据了可现实世界里的标注成本高得吓人尤其在医疗影像、生态保护、工业质检、古籍文献识别这些领域目标类别的正样本稀缺是常态。这两个概念经常被放在一起讨论也是因为它们的核心诉求一致降低对大规模标注数据的依赖。但技术路径完全不同。零样本的关键在于建立“图像特征”和“语义特征”之间的桥梁测试类别虽然没见过但它的语义描述在训练时已经间接参与过对齐。少样本的关键则在于如何从极少量的支持样本中提取稳定的类别区分度要么靠强大的预训练先验要么靠精心设计的度量方式。我把两者的设定差异整理成了一张表理解这个之后后面不管看论文还是做工程思路都会清晰很多维度零样本学习少样本学习目标类别是否出现在训练阶段完全不出现测试类别对模型来说是“盲区”每类仅有1-5个样本出现在训练阶段额外依赖的信息类别描述文本、属性向量、知识图谱等语义信息少量标注图像必要时配合类别名称推断机制图像特征与语义空间中的类别向量做相似度匹配从少量支持样本中归纳原型或微调分类边界失败的典型原因语义描述不够准确、视觉与语义空间对齐得差样本过拟合、数据增强不足、类别间区分度不够工程落地难度低推理时甚至不需要再训练中多数场景还是要训一轮这张表看清楚之后你就明白为什么零样本模型在推理时可以直接拿一个“描述文本”去匹配图片。它猜的依据不是“我以前见过这种猫”而是“我见过猫科动物的视觉特征也理解‘豹纹体型大’是什么意思我能在语义空间里把这两者对上”。这个机制我下面细讲。2. 零样本学习模型凭什么“无中生有”——核心是语义对齐不是玄学2.1 零样本的三步走零样本学习看起来像“无中生有”本质上是一次跨模态的知识迁移。整个流程可以拆成三步。第一步把类别变成AI能理解的语义向量。早期做法是人工为每个类别标注一组属性比如“有翅膀”“生活在水中”“体色为棕色”然后把属性组合成一个向量。中期做法直接用词向量比如把类别名“豹子”通过预训练的词嵌入模型映射到一个多维向量。到了现在最常见的是用CLIP这类图文预训练模型把一整句自然语言描述编码成向量往往比老式的属性向量信息密度高得多。第二步把视觉特征映射到同一个语义空间。训练的时候模型学的不是“这张图是美洲豹”这个硬标签而是“美洲豹的图片特征应该在语义空间里靠近‘大型猫科动物、黄褐色带黑斑’这个描述向量”。这个对齐过程可以理解为把图像编码器的输出空间尽量拧成和文本编码器的输出空间一致。第三步推理时match。测试的时候来了一个没见过的类别比如“麒麟”模型没有麒麟的训练图但训练时已经见过大量“动物图片与动物描述”的对应关系。它只需要把麒麟的描述编码成向量再把待识别图片编码成向量算一下余弦相似度谁最接近就选谁。整个过程没有对麒麟图像做过任何梯度更新却完成了一次“猜测”。2.2 从“属性词典”到“图文预训练”语义信息发生质变早年的零样本工作比如基于属性预测的方法本质上是在做“属性检测器集成”。模型先预测图像里有没有条纹、有没有尾巴、有没有角再把这些预测结果拼起来跟目标类别的属性表比对。思路朴素效果也朴素一旦属性标错了整个预测链条就崩了。词向量登场算是一波进步。类别名被嵌入到语义空间后模型不再依赖人工指定的属性枚举而是靠词与词的共现信息来推断类别关系。比如“荔枝”和“龙眼”的词向量天然就比“荔枝”和“狼”更接近这种先验知识帮了零样本不小的忙。但真正让零样本从“玩具”变成“能用的工具”的是图文预训练模型的崛起。这类模型在海量互联网图文对上做对比学习目标就是让配对图文对的表征一致。它不需要人工定义属性直接用一句话就能表达一个类别“长什么样”。描述从“有翅膀有喙会飞”这种碎片化属性升级成了“一种体型较小的海鸟背部深灰腹部白色常在海岸岩石上筑巢”这种接近自然语言的高维信息。语义空间丰富度上去了零样本的天花板自然也被顶高了很多。这里要特别解释一下“为什么描述质量比模型结构影响更大”。零样本的本质是语义对齐而描述文本就是对齐的锚点。同样是区分两种长得极像的灰雀一个只写“小型鸟类”一个写“雄鸟腹部淡红褐色翼带白斑喙短粗且呈圆锥形”后者的识别准确率可能高出20个百分点都不止。这不是玄学因为文本编码器能提取的信息上限直接受限于输入文本的信息量。2.3 零样本为什么也会“翻车”三个绕不开的瓶颈零样本不是万能的我想泼几盆冷水。第一盆是领域偏移。训练时见过的类别和测试时没见过的类别虽然共享语义空间但视觉分布可能差得很远。如果训练集里全是城市街景的车测试集里全是野外泥地里的工程车视觉特征分布的偏移会让相似度匹配失效。第二盆是语义鸿沟尤其是细粒度分类场景。你能用语言描述“雪豹和豹子的区别”但从像素层面两者花纹的细微排布差异很难被一句描述讲清楚这就是零样本在细分类上普遍表现差的原因。第三盆是枢纽点问题。在高维语义空间里某些向量会莫名其妙地成为大量其他向量的最近邻导致图片全部匹配到那几个“万金油”类别上。使用零样本模型时如果发现某几个类别稳定地被误判为同一个大类先别怀疑模型坏了去检查语义空间里这几个类别的描述向量是不是离得太近。很多时候是描述没把关键区分特征写出来。3. 少样本学习把“屈指可数”的样本榨干——三条主流路线3.1 先理解“N-way K-shot”的考试规则少样本学习领域有一套自己的考试规则叫N-way K-shot。N-way表示测试任务里一共有N个类别K-shot表示每个类别只提供K张标注样本K通常取1或者5。比如5-way 1-shot就是5个类别每类只有1张参考图。真正的少样本评测还会额外划分一个大的支撑类别集合用来帮助模型学习通用知识再在完全没参与训练的目标类别集合上考。为什么这个规则重要因为它把“少样本”量化得非常清晰K1时基本没法靠微调学出什么像样的分类边界更多是考模型的归纳能力K5时模型有了一丁点统计信息可以开始尝试估计类别分布。工业界说的“给我五张图就上线一个识别引擎”其实就是5-shot场景。3.2 路线一预训练加微调回本最快工程上性价比最高、也最常见的做法是在大规模预训练模型的基础上做轻量微调。预训练模型已经在海量图像上学到了通用的视觉表征比如轮廓、纹理、光照不变性这些知识对小样本来说是最宝贵的先验。到了目标任务只需要在ImageNet或类似大数据集预训练的图像编码器后接一个分类头再用每类三五张图微调一下就行。这里有个关键操作细节不要全部解冻。我在实际项目里通常是冻结backbone的前面所有层只解冻最后1-2个block加上新加的分类头学习率压到普通训练的五分之一以下。因为样本太少全参微调几乎必然过拟合模型会直接把那几张三张图的颜色、背景、光照当成类别特征背下来换个环境分分钟翻车。冻结底层的逻辑是底层特征通用且稳定顶层特征更偏向任务所以只动顶层代价是上限略低但稳定性高得多。3.3 路线二度量学习——学一个“像不像”的标尺度量学习的思路不是直接学分类边界而是学一个距离度量。让同类样本在特征空间里靠近异类样本远离。训练时拿一个支撑集把每类的K个样本特征做平均得到“原型向量”查询样本和每个原型比距离最近的是谁就归谁。这就是原型网络的核心思想。这个方法的直觉非常好懂虽然每类只有三五张图但特征空间里这三五张的质心大概率能逼近真实的类别中心只要特征空间本身学得够好。度量学习的另一个好处是推理时类别可以动态增加不用重新训练加一个新类别只需要算一下新类别的原型向量就行这在工业上是很受欢迎的特性。3.4 路线三元学习——学会怎么学元学习即“meta-learning”目标不是学会一个模型而是学会“快速学会一个新任务”的能力。拿MAML这类典型算法来说它在大量相似的小样本任务上反复训练每次任务都做一次“内循环”的梯度更新再基于这次更新的效果来调整模型的初始参数让初始参数停留在“随便几步梯度下降就能在新任务上表现不错”的位置。理论上确实漂亮但我对元学习的态度一直比较务实它在标准benchmark上时常亮眼到了真实工程里却往往不好落地。原因是真实任务的类别类别之间差异巨大很难像benchmark那样找到足够多“同分布”的任务来训练元学习器。另外元学习的训练框架复杂度高调试成本大。如果你手上资源有限我建议先走预训练加微调把这条路跑通再说。4. 实战对比我把两种方法放到同一个任务上跑了一遍4.1 实验任务与数据准备纸上谈兵没意思我拿一个模拟项目X来演示假设要做一个小型野生动物监测系统的识别模块初始拿到一批常见物种的图像但系统上线后经常拍到没见过的物种。实验目标是对比“直接用零样本识别”和“每类收集5张图做少样本微调”两种方案在5个新物种上的分类效果。数据上我挑了几种视觉差异大的比如雪豹、棕熊、金丝猴、孔雀、丹顶鹤又特意加了两种视觉极接近的比如雪豹和云豹来制造难度。每个新物种准备50张测试图少样本方案每类再额外抽5张做训练。零样本方案只用中文或英文描述文本不用任何目标类别的图像参与训练。4.2 零样本分类把图像和文本向量拉进同一个空间零样本分支的代码很短核心逻辑就是加载一个预训练的图文模型把图像和文本分别编码然后算相似度。我下面写一个伪代码级别的实现具体的加载接口可以按你用的库替换但流程是完全一样的# 零样本分类图像向量与类别描述向量做余弦匹配 import torch from PIL import Image # 加载预训练图文模型具体接口按所用实现替换 image_encoder, text_encoder, preprocess load_pretrained_multimodal() # 待识别图像 img preprocess(Image.open(query_photo.jpg)).unsqueeze(0) # 候选类别描述 candidate_names [雪豹, 云豹, 棕熊, 金丝猴, 孔雀, 丹顶鹤] candidate_texts [fa photo of a {name} for name in candidate_names] with torch.no_grad(): img_vec image_encoder(img) text_vecs torch.stack([text_encoder(t) for t in candidate_texts]) sims torch.cosine_similarity(img_vec, text_vecs) pred candidate_names[sims.argmax().item()] print(预测结果:, pred)这段代码跑起来会发现几个现象。第一视觉差异大的类别比如雪豹和孔雀几乎不会错零样本的表现出乎意料地好。第二雪豹和云豹这种近亲出错率直接飙升模型经常把两者搞混。第三描述文本用中文还是英文影响也挺大因为预训练模型的语料分布决定了它对哪种语言理解得更深。4.3 少样本分类在预训练模型上做轻量微调少样本分支同样基于预训练图像编码器但多了一步微调。我采取的方案是冻结backbone只训练新加的分类头配合随机裁剪、水平翻转、色彩抖动这一组常见数据增强让有限的样本发挥尽可能多的信息量# 少样本微调冻结编码器只训练分类头 import torch import torch.nn as nn class FewShotClassifier(nn.Module): def __init__(self, base_encoder, num_classes): super().__init__() self.base_encoder base_encoder self.head nn.Linear(base_encoder.feature_dim, num_classes) def forward(self, x): with torch.no_grad(): feat self.base_encoder(x) return self.head(feat) model FewShotClassifier(load_pretrained_image_encoder(), num_classes6) # 严格冻结预训练编码器 for p in model.base_encoder.parameters(): p.requires_grad False optimizer torch.optim.Adam(model.head.parameters(), lr1e-3) loss_fn nn.CrossEntropyLoss() # 每个类别 5 张原始图 数据增强扩到 30 张训练 20 个 epoch # 关键早停在验证集上监控准确率变化防止分类头过拟合那几张三张图跑下来结果也很明显5-shot微调在绝大多数类别上的准确率超过了零样本尤其是云豹和雪豹这种细分类有真实像素级样本兜底模型终于能抓住花纹排布的区别了。缺点是需要一点点人工标注、需要训练、需要调学习率一套流程下来少了些“即插即用”的爽快。4.4 实测对比什么时候谁更稳我把两者在新物种上的准确率汇总成一张表任务难度零样本准确率少样本(5-shot)准确率大类差异明显雪豹 vs 孔雀极高基本不犯错极高基本不犯错近缘物种雪豹 vs 云豹明显下降经常混淆5-shot后能拉回多数错误描述写得太泛只说“中型猫科”掉崖式下降受描述影响很小类别总数多且候选相似准确率波动大相对稳定但样本量不足时会过拟合这个表是我反复跑了几轮之后得到的总体印象。零样本的上限和下限都取决于语义描述的质量和区分粒度少样本则更依赖样本量和增强策略。结论很直白能凑到每类5张以上的靠谱标注就优先少样本。凑不到或者类别频繁变动就上零样本但要把类别描述下足功夫。5. 选型建议与避坑清单到底该用哪个5.1 从场景出发做决策很多同学来问我选型问题我给的答案从来不是“哪个技术高级就选哪个”而是列一张决策表一行一行对判断项条件满足时建议选择目标类别持续变动每月都有新类目加入零样本为主每类能稳定收集到5张以上高质量标注少样本微调任务对细粒度区分要求极高视网膜病变分级、同属昆虫分类少样本微调必要时增加标注量标注预算为零只有类别名单和一句描述零样本类别非常多且部分有标注部分没标注零样本初筛 少样本精修的组合方案离线低延迟场景推理时不能依赖外部打标先用零样本推理后续离线补少量样本迭代少样本模型这套判断逻辑的核心是“你在意的是上线速度还是区分精度”。在意速度零样本在意精度少样本在意又准又全那就混合着来。5.2 高频故障与排查清单我把自己在项目里踩过的、以及身边同行遇过的问题整理成一个清单对照排查比看理论有用得多现象可能原因处理办法零样本所有图片都预测到同一个类别描述向量太相似或语义空间存在枢纽点重写类别描述加入更多区分性细节或集成多个描述模板取平均零样本总把A类判成B类A和B在描述文本里没写出真正的视觉差异补上颜色、纹理、形体比例等像素可感知特征别写抽象属性少样本微调后训练集准确率99%测试集掉到60%过拟合增加数据增强冻结更多层学习率再降一个量级少样本增加一张图后效果反而下降这张图质量差或分布异常清洗样本把模糊、目标占比过小、光照异常的图剔除微调后模型变“笨”原来能识别的类别也认不出了分类头尺寸变化破坏了预训练特征的可用性不要重新训整个backbone分类头初始化后只训头保留底层特征零样本对真实照片还行对翻拍屏幕照片失效图像分布偏移在zero-shot推理前加一个简单的图像质量归一化或对测试图做增强集成排查这些问题的思路其实很统一先确认是“特征空间没对齐”还是“决策边界没学好”。零样本问题九成出在语义端少样本问题九成出在训练策略端找准端再下手效率翻倍。5.3 进阶思路两种方法可以组队很多人把零样本和少样本当成两个互斥选项其实最好的工程方案往往是组合。我实践下来最顺手的模式是“级联”第一级用零样本模型在全量候选中做粗筛把得分排名靠前的50个候选捞出来第二级用每类少量样本微调过的精分类模型在50个候选里做细分数。这样既避开了零样本细粒度弱的短板也不需要给每个类别准备几百张图。另一个非常实用的组合是“零样本产伪标签少样本做精修”。用零样本给未标注数据打标签挑出置信度高的当作额外训练数据扩充少样本训练集。说白了就是用无标注数据稀释标注压力。这个思路我建议在实际项目里优先尝试因为它改造成本低收益却常常比单纯调模型结构大得多。6. 我在实际项目里踩过的坑与心得最后聊几个具体心得。第一个心得是零样本的文本模板别只写一个。同一个类别用“a photo of a snow leopard”“a wild snow leopard in the mountains”“a big cat with grey-white fur and dark spots”三个模板分别编码再取平均效果通常比单一模板稳健不少。这个技巧在论文里叫提示集成实操成本几乎为零收益却很明显。第二个心得是少样本微调的学习率一定要压住。我踩过最惨的一次是在5-shot任务上用默认学习率微调训练两轮后验证集准确率不升反降。后来把学习率从0.01直接砍到0.001冻结层数加多效果才恢复正常。少样本场景下宁可让模型“学得慢一点”也不能让它“背得快一点”。第三个心得是别迷信复杂的元学习模型。我刚入门那会儿也对MAML这类方法充满兴趣觉得又酷又前沿但真上手后才发现训练难度极高光是要构造海量相似任务就够折腾一个季度。反而是预训练微调这种“土办法”在大多数真实项目里又快又稳。技术选型还是要回到成本和收益的账本上。第四个心得是关于评估的少样本的结果一定要多次重复实验取平均。五张图的随机划分对结果影响极大一次实验可能5-shot准确率是82%换一组图就变成68%。我在自己的项目里习惯把支撑集划分重复20次用均值加减方差做汇报这样既能看到真实水平也能发现自己方法对样本选择的敏感度到底有多大。零样本和少样本的这场“猜谜比赛”一个靠“听说”一个靠“照葫芦画瓢”没有谁绝对碾压谁。我现在的项目里两者经常搭档出场零样本负责快速响应新类别少样本负责稳定收敛到高精度。记住一点这两个概念的核心不是“替代谁”而是帮你把手里的标注预算花出最大价值。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →