MaPLe多模态提示学习:CLIP少样本分类的协同优化方法

发布时间:2026/9/15 16:48:49
MaPLe多模态提示学习:CLIP少样本分类的协同优化方法 做视觉-语言模型的少样本分类最绕不开的一类技术就是提示学习Prompt Learning。从CoOp、CoCoOp一路到VPT大家都在想同一个问题CLIP虽然强大但直接端到端微调又贵又容易过拟合能不能只往输入里加一些可学习的提示词让模型自己“调频道”MaPLe全称Multi-modal Prompt Learning就是在这一串名字里很有代表性的一个方法。它既不像CoOp/CoCoOp那样只在文本分支加提示也不像VPT那样只在视觉分支加提示而是同时在CLIP的文本编码器和视觉编码器的多个Transformer层中维护两组提示并且用耦合函数把语言提示映射到视觉提示让两个分支在训练过程中真正协同起来。这篇内容适合正在做少样本图像分类、想复现提示学习论文、或准备把CLIP接到自己任务上的研究者我会把方法思路、核心设计、复现经验和容易踩的坑一次说清楚。1. 项目概述与核心思路拆解1.1 从CLIP和提示学习说起CLIP的思想很简单用海量图文对做对比学习把图像和文本映射到同一个向量空间。训练完以后你给一张图片再给一串候选文本描述比如“a photo of a cat”和“a photo of a dog”它就能算出图片跟哪个文本更接近。这种零样本能力很惊艳但实际问题里类别名往往不是“cat”这种日常词而是医学影像、卫星场景、工业缺陷等专业概念。直接让CLIP零样本分类效果经常不够用所以才有了提示学习这条路。提示学习的核心假设是CLIP预训练时的文本模板是有固定形式的比如“a photo of a {class}”。如果把这些模板里的词换成一串可学习的向量并且只训练这些向量就能用极少样本把CLIP适配到新任务上。CoOp把文本模板中的上下文词改成可学习向量CoCoOp进一步让这些向量依赖图像内容VPT则转向在视觉分支的输入序列里加可学习token。这些方法的共同点都是只调整一侧的表示另一侧完全冻结。等到MaPLe出现思路又往前走了一步只调文本侧视觉特征还是原始CLIP空间里的老样子只调视觉侧文本侧又是老样子。可CLIP的图文空间并没有完美对齐尤其是下游数据分布和预训练数据差别大的时候单侧提示很难同时把两侧拉到合适的语义位置。那为什么不两边一起提示还让两边提示相互通个气呢这正是MaPLe想做的事。1.2 MaPLe到底在解决什么问题MaPLe要解决的核心问题可以概括成两个。第一单模态提示的表示能力有限。文本分支有可学习上下文向量时模型只能调整文本侧的类别描述视觉分支有可学习prompt时模型只能调整图像侧的局部特征。但下游任务真正需要的是“新的视觉概念”和“新的语义描述”一起变化。单侧调参本质上是在固定一个空间只移动另一个空间遇到分布偏移时容易顾此失彼。第二如果两侧都加提示但各学各的依然有问题。视觉提示和语言提示在深层特征空间里如果没有交互训练时看似都在更新实际上还是两条互不干扰的平行线。MaPLe的做法是显式地在语言提示和视觉提示之间建立一个映射关系也就是耦合函数。语言提示经过耦合函数变成视觉提示的初始化或补充这样梯度可以跨分支传播文本和视觉的优化就绑在了一起。从实验结果来看这种设计对小样本场景特别有效。基类上训练的样本量很小如果只是单纯增加可学习参数很容易过拟合成训练集里的纹理和背景。MaPLe把视觉提示限制为语言提示的某种函数等于给视觉分支的调整加了一个先验约束图像侧的改动要跟语义侧的改动有关联不能乱动。这个先验在基类到新类的泛化中起到了明显的稳定作用。1.3 多模态提示学习的含义很多人在看到项目名时会把MaPLe顺手读成Maple这也挺好记的。它全称是Multi-modal Prompt Learning重点是multi-modal这个词。多模态在MaPLe里有两层含义。第一层是指模型输入天然跨模态。CLIP本来就有图像和文本两条分支所以提示学习天然可以分成语言提示和视觉提示。第二层是指可学习参数本身也是跨模态的。MaPLe不只是在两条分支里分别加了一组参数而是让两组参数通过耦合函数产生关联形成共同的可学习空间。你更新语言提示时会影响视觉提示的生成你更新耦合函数时又同时改变了两侧的表达。这种“共轭更新”才是多模态提示学习和简单双分支提示的核心差别。理解这一点很重要因为所有后续关于MaPLe的复现和变体本质都是围绕“如何定义视觉和语言提示之间的关系”做文章。2. 方法拆解MaPLe的核心设计2.1 冻结CLIP只学提示和耦合函数MaPLe没有改动CLIP的预训练权重主干网络保持冻结。需要学习的参数只有三类语言分支各层的提示向量、视觉分支各层的提示向量以及把语言提示映射到视觉提示的耦合函数。这样做的最大好处是训练开销极小一张消费级显卡就能跑小规模实验。从参数效率角度看MaPLe比全量微调或LoRA式微调都更接近“提示学习”的本意。它没有引入大量额外分支耦合函数通常就是一个轻量MLP或线性映射总体新增参数量远小于模型本身。官方实验中即便只用16个样本的基类支持集MaPLe也能稳定训练这背后就是冻结主干带来的强先验。不过冻结主干也意味着CLIP本身对输入分布很敏感。如果你的图像预处理和CLIP预训练时不一致比如分辨率不是224x224或者归一化参数不对后续所有提示都白学。复现时第一件事就是检查image transform而不是急着调超参数。2.2 语言分支的深层提示CoOp只在文本编码器的第一层输入位置加入一组上下文向量后面所有层共享同一个输入序列但transformer层层加深时交互方式其实已经固化。MaPLe更彻底在多个Transformer层各设置一组独立的语言提示。具体来说文本输入仍然是“[CLASS]”前面拼接一些token例如模板“a photo of a [CLASS]”中的“a photo of a”会被替换成一组可学习的上下文向量。区别在于这些上下文向量不是只在第一层存在而是每一层都有一份专属的提示。第1层的提示和第6层的提示可以学到不同抽象层级的语义类别信息能在早期就参与特征交互而不是在最后一层才发挥影响。这里有一个很直观的类比如果只改第一层提示相当于你在给一个陌生人讲任务时只调整了第一句话后面全让对方自由发挥。多层提示则是在对话的每个环节都递小纸条不断把任务意图重新注入。对CLIP这种深层Transformer来说越深层引入提示越能直接作用于最后用于对比的特征这也是MaPLe提升性能的关键原因之一。语言提示的长度一般取M比如4或8。长度太短表示能力不足长度太长可学习参数变多小样本下容易过拟合而且会和文本原有的token抢位置。实践中我一般从4开始试如果训练集稍大再调到8。2.3 视觉分支的提示与耦合函数视觉分支这边MaPLe在每层Transformer的patch token序列前面或中间插入视觉提示。因为图像被切成的patch patch数量是固定的插入的提示token数量可以比patch数量少很多。视觉提示的维度和patch embedding一致ViT-B/16通常是768维左右而文本提示的维度是CLIP文本编码器的隐藏维度通常512。两者维度不同所以不能直接复用参数。这里就是耦合函数发挥作用的地方。MaPLe会把当前层的语言提示送入一个耦合函数由耦合函数映射出一个视觉提示。这个映射可能包含线性投影和非线性变换目的就是让视觉分支的初始提示带上语言分支的语义信息。除了这个映射生成的提示视觉分支也可以再保留一小部分可学习增量用于吸收语言映射表达不了的信息。如果去掉耦合函数让视觉提示和语言提示各自随机初始化、各自更新这其实就是一个更强版的双分支提示方法效果也能提升但如果加上耦合训练时反向传播路径就通了损失函数对视觉提示求梯度视觉提示又来源于语言提示和耦合函数于是梯度能传到语言提示上。语言分支的更新不再只依赖文本分类结果而是同时受到视觉特征的影响两个模态才真正开始协作。2.4 训练和推理流程训练阶段和大部分CLIP提示学习方法一样。输入一张图像经过视觉编码器得到图像特征输入一组类别文本比如“a photo of a cat”经过文本编码器得到文本特征。两者做点积相似度再接一个交叉熵损失。反向传播时CLIP主干不动只更新各层提示和耦合函数。关键区别在于MaPLe的视觉特征和文本特征都已经被多层提示“修饰”过。图像分支的每一层都注入了来自语言提示映射的视觉提示文本分支的每一层也都注入了可学习的上下文向量。因此在最终特征空间里两个模态的表示都向当前任务做了协同偏移。推理阶段更简单。把所有候选类别的文本特征算一遍并缓存起来然后对任意一张测试图只跑一次视觉编码器算相似度取最大值即可。这种解耦式的分类器设计使得新增一个类别时不需要重新训练只要重新生成文本特征就行。实际工程里这个特性很实用比如你给一个系统增加新的SKU只需要改类别名列表不用碰模型。3. 实验效果与评价协议3.1 少样本分类MaPLe的官评协议沿用了提示学习领域常用的少样本评估方法在ImageNet以及Caltech101、OxfordPets、StanfordCars、Flowers102、Food101、FGVCAircraft、SUN397、EuroSAT、UCF101等一系列数据集上分别用1、2、4、8、16个样本做训练。每个数据集类别数不同所以总训练量也不同但协议统一。从结论来看MaPLe在大多数数据集上都稳定超过CoOp、CoCoOp和VPT。尤其突出的是在细粒度数据集上比如StanfordCars和FGVCAircraft这些数据集的类别差异很小单靠文本侧提示很难把语义区分开。MaPLe因为在视觉分支的多层都注入了提示视觉特征也能针对任务做局部调整效果明显更稳。要注意的一点是这么多数据集的平均分只能说明整体趋势不同数据集上的增益差异很大。有些数据集本身和CLIP预训练分布很接近提升幅度可能就1个点左右有些域差距很大的数据集提升能到5个点以上。你复现的时候如果只看某个单一数据集感受到的增益可能和论文里平均分不完全一致这是正常的不代表复现出了问题。3.2 基类到新类泛化基类到新类泛化是这个领域最关注的指标之一。训练时只给模型看部分类别的少量样本测试时却要求模型同时识别训练过的基类和没训练过的新类。这非常考验模型有没有充分利用CLIP本身的开放词汇能力而不是单纯记住训练集类别。MaPLe在这个协议下有一个很明显的特点新类准确率比CoOp高出不少。CoOp容易过拟合到基类新类效果经常掉得厉害CoCoOp用图像条件缓解了一部分但依然受限于只在文本侧做提示。MaPLe因为视觉提示和语言提示是耦合的训练过程中模型把更多精力放在如何调整任务语义上而不是如何过度拟合训练集纹理。实验里它的基类准确率可能不是最高的但新类表现往往会更好基类和新类的平均分更均衡。如果你实际要做的是一个小样本分类系统上线后可能不断出现新类别那就不应该只看基类测试集上的准确率而要认真跑一下基类到新类评估。这种评估更能反映模型在真实开放场景里的可用性。3.3 领域泛化与鲁棒性除了常规少样本分类MaPLe还在ImageNetV2、ImageNet-Sketch、ImageNet-A、ImageNet-R这些鲁棒性数据集上做过测试。这些数据集的共同点是和ImageNet训练集分布有明显偏移比如素描风格、对抗样本风格、自然变化等。提示学习一个容易踩的问题就是微调后虽然目标数据集准确率涨了但CLIP原本的鲁棒性被破坏。为什么会这样因为可学习提示如果把太多注意力放在训练集特有的统计规律上就会丢失CLIP原始特征空间里的通用知识。MaPLe在这类评估中相对稳健原因是它没有直接改CLIP主干视觉提示又受到语言提示的约束整体对特征空间的扰动更小。这个结论对实际工程很有价值如果你的任务需要应对各种摄像头、光线、清晰度变化最好别选过拟合能力太强的微调方案。3.4 消融实验带来的启发MaPLe的消融实验里有几个点很值得关注。第一提示层数的影响。只在第一层加提示性能提升有限随着加提示的层数增多性能逐步上升但到一定深度后继续增加收益变小甚至可能轻微下降。这说明深层提示有效但不是越多越好需要平衡参数量和过拟合风险。第二耦合函数是否存在的对比。去掉耦合函数、视觉和语言提示独立更新效果比完整版要差。这直接证明了耦合设计不是锦上添花而是核心贡献。第三视觉提示的初始化方式。用随机初始化的视觉提示不如用耦合函数从语言提示生成的提示效果好。这个结果告诉我们在少样本条件下视觉提示的“起点”非常重要合理初始化相当于给优化提供了更好的先验比单纯增加参数容量更划算。4. 实操复现与超参数经验4.1 环境与代码库选择MaPLe官方代码基于PyTorch实现仓库名称就叫mapl-prompting核心依赖是open_clip或官方CLIP模型。复现时不需要额外安装重型框架只要把CLIP权重下载下来就行。显存方面ViT-B/16作为视觉主干时单卡16GB完全够用如果用ViT-L/14建议batch size调小或者用梯度累积。我第一次复现时用的是一张RTX 3090batch size设416-shot的ImageNet实验并没有太大压力。提示学习相关参数都很少真正占显存的是CLIP主干的前向激活值。如果你不想从零开始训练也可以在官方代码基础上做改动。源码里把数据集加载、FewShot采样、模型构建都封装好了改起来比较顺手。不建议自己重新搭一套CLIP提示学习框架因为很容易在数据划分和文本模板这些细节上出错。4.2 关键超参数设置原则MaPLe里最核心的超参数是prompt长度M、提示层数D、学习率和训练轮数。从我复现的经验看M取4是比较稳的起点。M1时提示过于单薄每层只有一个token很难承载复杂语义M8在某些数据集上效果更好但训练集只有1-shot或2-shot时会显著过拟合。D一般取总层数的一部分ViT-B/16有12层D取9是比较常见的选择。D取12时所有层都有提示参数更多但提升不明显训练也慢一些。学习率方面提示向量和耦合函数可以设置不同学习率。耦合函数相当于一个小网络学习率太大容易震荡提示向量本质上是embedding类参数通常可以用稍大一些的学习率。官方配置一般用SGD加动量学习率范围在1e-3到5e-3之间。如果你用AdamW学习率要相应调低否则前期loss会直接飞起来。训练轮数一般设定在20个epoch以内。因为少样本数据量很小跑太多轮只会让模型记住支持集新类泛化反而变差。每轮迭代次数也少20个epoch很快就能跑完。要特别注意的是随机种子对结果影响可能非常大同一个配置换一个seed准确率波动1到2个百分点并不罕见所以对比方法时一定要多跑几个seed取平均。4.3 复现中容易踩的坑第一个坑是文本模板不一致。MaPLe对文本编码器输入的处理会直接影响结果。很多人复现时会随手写一个“a photo of a {class}”的模板但不同数据集、不同类名拼写甚至类名前面是否加冠词都会显著影响特征质量。建议直接沿用官方代码里的模板不要自行发挥。第二个坑是图像分辨率。CLIP预训练有固定分辨率ViT-B/16是224x224。有些数据集原生图很大如果resize策略和CLIP的预处理不一致等于给模型喂了分布外的输入。复现时最好把图像统一处理成224x224再按CLIP自带的normalize参数做标准化。第三个坑是冻结参数没有完全冻结。很多改代码的人会把CLIP的train()/eval()模式切换写错导致BatchNorm或Dropout状态异常。CLIP主干用的是LayerNorm和Attention一般情况下不需要因为训练集太小而切换状态但一定要确认自己是只更新prompt和耦合函数不要误把backbone的requires_grad设为True。第四个坑是损失函数和类别顺序。少样本训练时每个batch通常只包含当前batch内的类别而不是全量类别。如果直接写一个所有类别的分类器会无意中让模型看到未来类别的文本特征造成信息泄漏基类到新类评估结果会虚高。4.4 如何把MaPLe迁移到自己的任务如果你不想跑论文里的公开数据集而是要把MaPLe用在自己的业务场景步骤其实不复杂。先准备好类别名列表。类别名最好是人类可读的自然语言比如“scratch on metal surface”“broken capacitor”这类描述。然后构造文本模板。可以是简单的“a photo of {class}”也可以根据领域改成“a satellite image of {class}”“a histological image of {class}”。接下来用少量标注图像训练提示和耦合函数。不需要标注大量数据16-shot每类16张图就能启动。训练完以后保存各层的提示向量和耦合函数参数。在线推理时先对所有类别编码文本特征再对图像编码视觉特征做矩阵乘法就能得到分类分数。如果你的任务不是分类而是图文检索或视觉问答MaPLe的核心思想同样可以借用。只要你有两条模态分支并且希望同时调整两侧的提示就可以参考耦合函数的设计。不过要注意MaPLe是在CLIP框架下提出的换成其他双塔模型时维度、层数、token插入位置都需要按新模型重新调。5. 常见问题与后续扩展5.1 常见问题速查表实际操作中大家问得最多的问题我整理成了一张表方便对照排查。问题现象可能的排查方向loss持续不下降学习率太大或太小文本模板错误类别名拼写异常耦合函数权重初始化异常基类准确率高但新类很低训练轮数太多prompt长度偏长提示层数过多导致过拟合只优化基类分类器两个分支效果都不如单侧提示没有正确设置多层提示耦合函数路径没有梯度视觉提示和语言提示维度不一致换一个seed结果波动很大少样本本身方差大建议多seed平均检查数据采样逻辑是否固定显存不足减小batch size减少提示层数降低输入分辨率但会影响结果用梯度累积复现结果和论文不一致检查CLIP模型版本检查数据集划分是否和官方一致检查是否误用了全量文本类别这些坑里最隐蔽的是数据划分问题。提示学习领域的少样本划分不是简单随机采样很多论文会固定一个划分文件。如果你自己随机采样很可能采样到的类别子集和官方不一致导致结果没有可比性。5.2 MaPLe与其他提示学习方法的取舍做一个简单对比帮你判断什么场景下选谁更合适。方法提示位置是否跨模态耦合适合场景CoOp仅文本输入层否文本模板固定、类别语义清晰的任务实现最简单CoCoOp仅文本输入层依赖图像否类别变化多、需要动态文本特征的任务比CoOp泛化好VPT仅视觉各层否视觉特征需要精细调整文本语义不太重要的任务MaPLe文本和视觉多Transformer层是少样本、基类到新类、跨模态需要协同对齐的任务从部署复杂度看CoOp最轻量MaPLe多了一个耦合函数和一组视觉提示但总体仍然比微调CLIP轻得多。如果你的任务只是固定类别集合CoOp已经够用如果你的任务需要频繁加新类或者训练样本极少且域差距大MaPLe的泛化优势会更明显。5.3 MaPLe之后的一些扩展方向MaPLe之后提示学习领域出现了很多变体比如改善耦合函数设计的、用大语言模型生成提示的、或者把prompt学习和adapter结合的。整体脉络都是沿着“如何在保持CLIP泛化能力的同时用更少的可学习参数让两个模态更好对齐”这个方向走。我觉得最有价值的扩展方向不是改耦合函数的网络结构而是把跨模态提示用于生成任务。MaPLe本质上是为分类任务设计的但它“视觉提示由语言提示映射而来”的思路天然适合图文生成、视觉问答、零样本检测等需要对齐语义和视觉细节的场景。比如做开放词汇检测时语言侧提示可以增强类别描述视觉侧提示可以增强区域特征两者耦合后可能比分开调优更自然。另一个方向是和时间维度结合。视频理解里每一帧都有对应的文本描述如果每一帧的视觉提示都由全局视频级语言提示来生成可能比独立处理每一帧更稳定。这类扩展目前在研究社区里已经有了一些尝试说明MaPLe的核心思想还有不少可挖掘的空间。写在最后的一点个人体会我从第一次读MaPLe论文到实际复现最深的感受是“耦合”这个设计看着简单但带来的改变是全方位的。以前做视觉-语言提示学习总习惯把图像和文本当成两个独立模块分别调优MaPLe提醒了我预训练模型虽然有两个分支但它们最终是在一个共享语义空间里工作的。只要让模型知道“图像侧应该怎么改应该参考文本侧怎么改”少样本条件下的对齐就会稳很多。最后再分享一个小技巧如果你在某个数据集上复现效果不理想先别急着调耦合函数结构把提示层数从浅到深扫一遍再检查文本模板大多数问题都出在这两个地方。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询