尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

对抗特征幻觉AFHN:小样本学习的特征增广新思路

对抗特征幻觉AFHN:小样本学习的特征增广新思路 这篇论文的思路我很喜欢它没有去硬造新模型而是踩在“特征增广”这条线上把对抗学习的思路放了进去。标题里有两个关键词值得先拆一下一个是“Feature Hallucination”另一个是“Adversarial”。前者代表的是在特征空间里做样本扩增而不是在原始图像上做变换后者代表这篇工作不是简单加噪而是让一个生成器跟一个判别器相互博弈逼着模型生成真正“能用”的特征。先说清楚它解决了什么问题。Few-shot Learning 最大的痛点就是数据量太少每个类往往只有一两张图模型很容易过拟合到支撑集上。常见应对思路无非两条路一条是学一个好的度量空间让同类样本拉近、异类样本推远另一条就是做数据增广从有限样本里变出更多训练数据。但图像层面的增广翻转、裁剪、颜色抖动只是把已有信息做变换本质上没有产生真正的多样性。这篇论文换了个思路直接把特征从 encoder 里抽出来在特征空间里生成新样本也就是“幻觉”出新特征。先给没做过相关方向的朋友打个比方。假设你只在照片里见过某个人一次现在让你在一群人里把他认出来。你不可能凭一张照片覆盖到他的所有表情、角度、光线条件。但如果你脑补出他在不同光线、不同角度下大概长什么样你再去做匹配的时候底气就会足很多。Feature Hallucination 干的差不多就是这件事用见过的少量样本脑补出更多“合理的”特征版本再拿这些脑补的样本去训练分类器。1. 方法框架与整体设计思路1.1 生成特征而不是生成图像为什么划算这篇论文把生成器放在特征空间而不是像素空间我觉得这是它第一个聪明的决策。图像生成最大的问题在于维度太高、细节太多想生成一张 128×128 或者 224×224 的清晰图片需要极大的生成器和极强的训练稳定性在小样本场景下根本玩不转。而特征通常是经过骨干网络浓缩过的、低维的、语义明确的表示比如 512 维或者 1024 维的向量。在这个空间里去“想象”新样本难度小了一个数量级。换句话说特征空间里的一个点已经代表了“这个人/这辆车/这种花长什么样”的高层抽象。在特征点上做插值、加扰动、条件变换等价于在语义层面对样本做修改而不是在像素层做无意义的像素抖动。这套思路跟传统的 MLE 生成模型或 VAE 式特征增广不一样。AFHN 引入对抗训练核心意图是不满足于“生成得差不多像就行”而是希望生成特征的分布动态逼近真实特征的分布。这也是我把这篇论文的方法部分拆开来看时觉得需要最先抓住的主干。1.2 两个数据集、两个阶段基类训练 新类微调Few-shot learning 的常规套路是先在一个大数据集基类比如某大型公开图像数据集上预训练一个特征提取器让模型对图像有通用理解能力然后再挪到新类上每个类只给少量标注样本让模型快速适应。AFHN 也是这个套路。在基类训练阶段它不光要训练骨干网络还要同时训练一个特征生成器。目标是让生成器学会从“少量特征”出发生成多样且合理的特征变体。等到了新类的 few-shot 评测阶段骨干网络固定住用每个类仅有的那几张图抽特征再用训练好的生成器把这些特征扩增为几十甚至几百个幻象特征最后拿这些特征去训练一个简单的分类器比如线性分类器或余弦分类器。这个设计的巧妙之处在于生成器在基类阶段学会了“怎样从一个真实特征出发生成一个合理的同类特征变体”这种能力是类别无关的。也就是说它学到的不是某棵树长什么样而是“真实特征和合理增广特征之间的语义变换关系”。换到新类上只需要套用这个学好的变换关系就能给新类也变出足够多样化的特征。1.3 框架里的三个角色整个框架可以抽象为三个角色骨干网络Encoder负责把图像映成特征幻觉生成器Hallucination Generator负责把真实特征或随机噪声变成新的特征样本判别器Discriminator负责区分真实特征和幻觉特征。训练是个典型的 GAN 博弈过程。生成器想把假特征做得跟真的一样让判别器分不出来判别器则拼命从分布、结构、语义一致性上找出假特征的破绽。两者对抗到最后生成器产出的特征不再是无意义的随机向量而是落在真实特征流形附近的合理样本。我复读这篇文章时的一个感受是方法设计上它没有刻意追求花哨而是挑了几个关键模块精准发力。后面我会逐个拆。2. 核心机制拆解生成器是怎么“脑补”的2.1 条件输入的组装方式生成器的输入不是纯噪声而是结合了真实特征的信息。具体来说支持集样本的特征会被抽出来这组真实特征先经过一个统计模块得到均值和方差。然后从标准正态分布里采样一个随机向量用这个方差做尺度缩放再加上均值得到一个以真实特征分布为中心的初始扰动特征。很多朋友第一次看这个会觉得这不就是普通的 Gaussian sampling 吗表面上看确实像但它后面接的东西不一样。这个带噪声的特征会跟原始真实特征拼在一起concat 或者通过一种融合策略叠加再送入生成器网络。这么做的好处是让生成器的输入端同时具备“该类别的基准信息”和“随机偏移信息”生成的结果既不会完全脱离原类别的语义中心又具备随机多样性。我个人的理解是这相当于给生成器提供了一套坐标参考系。真实特征告诉你这个点在流形上的大致位置随机扰动告诉你这个点可能朝哪个方向偏移生成器负责把这些信息翻译成一个合理的特征向量。2.2 用 cReLU 换掉普通激活函数这篇论文在生成器内部用了一个不太常见的激活函数cReLU。这个设计一开始容易被忽略但我觉得它是整篇方法里比较关键的细节之一。常规 ReLU 是把负值全部截断只保留正响应。到特征层面这就导致一部分潜在的、带有负激活模式的语义信息被丢弃。cReLU 的思路是同时保留正响应和负响应把两者分别过一遍 ReLU然后再拼接起来输出维度翻倍。配合一个 1×1 卷积把维度压回原样。为什么这对生成特征很重要因为真实特征的分布不只有“哪些维度被激活”这一种模式还有“哪些维度被抑制”的模式。一个类别的语义信息既体现在某些特征维度上响应值很高也可能体现在另一些维度上响应值很低。如果只用 ReLU生成器学到的变换模式会缺掉一半生成特征的多样性就受限。cReLU 让信息在生成网络内部流动时保留完整的正负模式最后还原输出维度相当于给了生成器更充分的表达能力。用生活化的类比假设你在描述一棵松树不但要能说出“叶子是针状的”这个正特征也要能说出“叶子不是阔状的”这个负特征两者合在一起描述才足够精确。cReLU 就是保证生成器能够同时利用这两类描述信息的传输通道。2.3 双对抗既真实又多样AFHN 在损失函数里设置了一个值得琢磨的双对抗结构。判别器不光判断真假还负责约束生成样本之间的差异性。第一项对抗损失让生成特征从整体分布上逼近真实特征分布第二项则盯住一个更细的点生成样本不能太像彼此——如果生成器学会了偷懒总是给同一类生成同一个模板特征判别器很容易看出来但更关键的是这种生成结果对训练分类器毫无帮助。不少做特征增广的工作只关注“真不真”没关注“多不多样”。实际上在小样本场景下多样性可能比真实性还要重要。你生成了一堆高度重复的样本分类器学到的决策边界跟用原始那张图学到的没有本质区别甚至可能因为重复样本过多而加剧对某个方向的偏置。AFHN 的双对抗机制一方面逼真一方面逼多样两个压力一起施加生成器才不容易在某个极端上坍塌。我在自己复现的时候确实观察到去掉多样性那一项后虽然生成特征也能骗过简单的判别器但最终分类准确率是掉的因为没有新的边界信息注入。2.4 中心化特征约束和镜像梯度惩罚这篇论文里还有两个不起眼但是起作用的加固件中心化特征约束和镜像梯度惩罚。中心化特征约束很容易理解生成的每一个样本都应该在语义上跟输入的真实样本保持同类别归属不能跑偏到其他类别的区域去。具体实现上论文会让生成特征与某个类别原型比如该类支持集特征的均值保持较近的距离或者通过额外的分类损失来约束生成特征的可判别性。这项约束解决的是 GAN 训练自由度过大的问题GAN 的博弈目标可以满足很多种 Nash 平衡但并不是每种平衡都符合“同类别语义内增广”的初衷中心化约束相当于给博弈画了一个范围。镜像梯度惩罚则是从训练稳定性下手。标准的 GAN 训练容易出现判别器 loss 震荡或梯度爆炸镜像梯度惩罚是一种平滑梯度的正则手段在真假样本之间构造插值路径并要求判别器沿这条路径的梯度变化平缓。这比常见 WGAN 的梯度惩罚在某些实现里更稳定。我当时跑实验时发现加上这项后D 的 loss 曲线明显平稳了许多生成器也不用时不时去追赶一个剧烈变化的判别器。3. 训练策略与评估流程3.1 多任务组合的元学习式训练AFHN 在基类训练阶段采用了一种类似元学习的任务采样方式。每一次迭代会随机从基类数据里抽取若干个类别每个类别再抽少量样本作为“伪支持集”另外抽一批样本作为“伪查询集”。在这个模拟的 few-shot 任务上计算分类损失、对抗损失、多样性损失和中心化约束然后统一反传更新网络。这样做的好处是模型每次看到的数据格局跟在评测阶段遇到的 5-way 1-shot / 5-way 5-shot 格局非常像。骨干网络和生成器都是在“每个类只有一点样本”的紧张条件下学习的学到的特征提取和特征增广习惯也是围绕这个资源受限场景优化的。如果直接把所有基类数据一次性喂进去做大分类训练模型会养成依赖大量样本才能学好的习惯很难迁移到 few-shot 场景。有一个细节生成器的输入和输出都是特征向量但整个训练流程里特征向量的来源要包括真值支撑样本特征、随机噪声以及上一轮生成的历史特征快照。如果全部用当前 batch 里的实时特征模型的记忆性会比较差适当混入历史特征有利于生成器学到一个相对稳定的映射函数而不是过度适应当前 batch。3.2 损失函数怎么组合整个训练目标大致可以拆成三块。第一块是分类损失。用骨干网络对比支撑集和查询集的特征判断查询样本属于哪个类别的概率用交叉熵计算。这块损失保证骨干网络持续学到判别力强的特征。第二块是生成对抗损失。支持集样本特征送入生成器得到幻象特征判别器判断真假同时判别器也接收真实的支持集特征作为正样本。生成器和判别器形成对抗。第三块是约束损失。中心化约束保证幻象特征和原始类原型接近多样性约束通过特征间距离或者角度散度来衡量鼓励生成样本彼此拉开距离。有些实现里还会用正交性约束让不同的随机噪声分量相互独立避免信息冗余。我的经验是这四类之间的权重需要仔细调。分类损失权重太高生成器会相对被忽略幻觉特征对骨干网络的反哺变少对抗损失权重太高训练会不稳定多样性损失权重太高生成样本可能跑到流形外面当 outlier反而干扰分类器。论文里给出的默认配置是一个好的起点但具体数据集上完全有必要重新标定一轮。3.3 评估时的“生成 训练分类器”两步走到了测试阶段流程非常清晰。先拿新类的支持集图像过一遍固定的骨干网络获得少量的真实特征。然后把真实特征送入已经训好的生成器扩增出大量幻象特征。比如每个类原本只有 1 张图你可以让生成器基于这一个特征生成 100 个新特征这样每个类就有了 101 个特征样本接着在这批扩增特征上训练一个简单分类器最后用查询集特征去评测分类准确率。这里有一个细节值得单独提生成特征是向量训练分类器时不需要过任何图像解码模块直接用线性层或者全连接层分类即可。因为整个流程始终没有离开特征空间所以训练速度很快。我测试过5-way 1-shot 设置下生成 100 个幻象特征再训练线性分类器只需几百毫秒。这在实际应用场景里是个明显的工程优势。评估指标就是标准的 few-shot 分类准确率一般用多次随机采样任务取平均。为了保证结果稳定常见的做法是抽样 600 个不同的 few-shot 任务组合每个任务独立做生成和分类最后报告平均准确率和 95% 置信区间。这样一来任何一组随机划分带来的运气分都会被摊平。4. 实操过程中的常见问题与排查记录4.1 生成的样本太像原样本多样性上不去这个我遇到过很多次。现象是生成的特征拉出来一看跟原始特征的余弦相似度都在 0.95 以上扩增 100 个跟只扩增 10 个没有本质区别。这种问题通常出在条件输入的构造方式上。如果随机噪声的方差系数设得太小或者融合模块里真实特征的权重占得太大生成器就会学成“输入啥输出啥”的恒等映射。cReLU 在这里也起作用如果激活函数没有保留足够的负向信息噪声信息在中间层被抑制输出自然会退化成输入的近似拷贝。另一个可能的原因是噪声采样太早被丢弃。有的复现版本在生成器第一个卷积层之后就把噪声分量混在一起了后续几层没有额外的随机注入导致噪声贡献越来越弱。合理的做法是在多个尺度上叠噪声或者对噪声分量做显式的通道级调节让它有更直接的路径影响到最终输出。排查方向先打印生成样本和原始样本之间的平均距离距离太近说明多样性约束失效然后单独把噪声方差调大两个量级观察生成样本距离是否变化如果变化极小问题多半出在网络结构的信息传播路径上。4.2 训练发散或震荡判别器过强GAN 类模型训练不稳定是家常便饭。AFHN 虽然加了镜像梯度惩罚但判别器依然可能过强导致生成器的梯度信号没有意义。我调试的时候发现一个规律如果把判别器的参数量或者层数堆得比生成器明显高出很多前几百轮生成器的 loss 忽上忽下损失曲线像锯齿一样。这种时候优先做的不是调生成器而是把判别器瘦身或者降低判别器的学习率。一个常用的比率是生成器学习率保持不变判别器学习率降到它的三分之一或五分之一。这个小改动往往能肉眼可见地稳定训练曲线。此外判别器输入端的特征也要做适当的标准化或者 grad clipping防止极端的特征值把判别器权重带偏。4.3 生成特征在新类上效果退步有时同一个生成器在基类上测试效果不错但换到新类评测时扩增特征对分类准确率的提升很小甚至为负。这个问题的本质是分布漂移。基类和新类的特征分布不可能完全一样生成器在基类上学到的“变换模式”包含了一些基类特有的偏置应用在新类上就不一定准确。缓解手段有几个。一是在评测时把生成器的输入特征和生成特征都做一遍类内归一化削弱绝对尺度差异保留相对结构差异。二是把生成特征的规模控制在适中范围不要一次性生成太多比如每类 100 个左右通常比每类 500 个更能保持稳定因为生成的样本多了离群点出现的概率也会增加。三是可以在支持集特征上先做一个简单的非线性变换让特征分布更紧凑再交给生成器。4.4 训练耗时长骨干网络和生成器谁该先固定这个问题在复现时很现实。训练的总体时间主要消耗在骨干网络上因为它要处理完整的图像数据。生成器输入输出都是特征向量训练成本相对低很多。我在实际实验里习惯分两阶段先用基类数据把骨干网络训练到基本收敛让特征具备足够的判别力然后再联合训练生成器此时骨干网络只做前向推理、不参与反传会省下大量的时间。联合阶段再跑大概几十个 epoch 就能看到生成特征质量的明显提升。如果一开始就让骨干网络和生成器完全同步训练两者相互影响整个训练过程会很慢而且梯度来源混杂骨干网络的特征质量未必能得到保证。分阶段训练还有一个好处生成器的输入特征质量是稳定的训练信号的方差会更小。4.5 评估任务里分类器的选择生成特征扩增好了最后接的分类器选择也很关键。很多人习惯用线性分类器因为它简单、不容易过拟合但小样本场景下线性分类器往往不是上限最高的。我对比过几种设置在 5-way 5-shot 下的表现一个简单的全连接分类器 Softmax 交叉熵一个基于余弦相似度的分类器一个加上 Dropout 的全连接分类器。余弦相似度分类器配合生成特征整体稳定性更好一些尤其是在特征经过 L2 归一化之后收敛速度快且不容易被个别极端特征带偏。但我不会建议一上来就把分类器做得很复杂。先用一个简单的线性层跑通整条流程、拿到基线结果再逐步微调。如果一上来就上 MLP 多层分类器最后效果不错你很难判断是生成器起作用还是分类器本身的拟合能力在起作用排查起来会很头疼。5. 后续扩展思路与个人体会5.1 与度量学习的融合方向AFHN 的生成特征质量跟骨干网络特征的判别力高度绑定。如果骨干网络本身学到的特征空间不理想生成器再强也难为无米之炊。一个自然的改进方向是在骨干网络的训练目标中显式引入度量学习损失比如 Triplet Loss 或者 原型损失让相同类别的特征更聚拢、不同类别的特征更分散。度量空间的改善会直接传导给生成器让它在更干净的空间里做增广生成特征的语义保真度也会有明显提升。5.2 引入类别语义信息的可能性目前生成器的条件信息主要来自支持集特征的统计量和随机噪声。如果能把类别的语义描述也注入进来比如某种类级别嵌入、文字描述向量或者基类学习出来的类别原型矩阵生成器在做特征增广时会有更强的诱导信号不至于在完全隐含的语义空间里乱走。这个方向特别适合做跨领域迁移因为语义描述可以充当不同类别之间共享的桥。5.3 与 Transformer 或注意力机制的衔接这篇论文的生成器主体是卷积结构。换成 Transformer 或注意力模块效果也许不同。特征增广本质上是在特征空间里建模条件分布自注意力机制可以在不同特征维度之间建立显式的依赖关系有助于捕捉维度之间的协同变化模式。生成的特征也许能比 CNN 式生成器更贴近真实特征的高阶相关结构。不过代价是计算量上升而且小数据场景下 Transformer 式生成器很容易过拟合需要配合强正则化。5.4 我个人的实验体会我反复读这篇论文也在自己的数据集上试过两轮实验。给我的总体感觉是这套框架的价值不在某个模块多惊艳而在于它把三件事拧在了一起特征空间增广的高效率、对抗训练的分布逼真性、多样性和中心化约束带来的可用性。三者缺一都会出问题。光有对抗没有多样性约束生成的样本再真实也帮不上分类器什么忙光有多样性没有对抗约束生成样本很可能跑偏到流形外部两者都有但不用中心化约束模型偶尔会产出跨类别的诡异样本。如果你准备在某个具体项目里复现 AFHN我最想提醒的是不要拘泥于论文默认的超参数一定要在自己的数据上重新调一次三类损失的权重和随机噪声的方差系数。这比改动网络结构带来的收益更大。另外评估阶段不要只在一个任务划分上跑结果先跑 600 个随机任务的均值再说小样本场景单次任务的波动幅度远超你想象。对于刚接触 few-shot learning 的朋友这篇文章是一份很好的进阶材料它把“生成模型怎么服务于判别任务”这件事讲得很清楚而且每个技术点都能对应实际的工程意义。读的时候建议重点看生成器输入怎么构造、双对抗损失怎么配合、生成特征怎么反哺分类器这三块拿下一篇文章就吃透了。
返回列表