ECCV2020拓扑保持类增量学习:从特征空间几何关系抑制灾难性遗忘

📅 发布时间:2026/10/17 13:32:54
ECCV2020拓扑保持类增量学习:从特征空间几何关系抑制灾难性遗忘
增量学习这几年在顶会上的热度一直没降过尤其是类增量学习Class-Incremental Learning, CIL这个方向几乎每年ECCV、CVPR、ICCV都有新坑被填。但大部分工作都在跟灾难性遗忘死磕思路基本围绕蒸馏、回放、参数隔离这几条线。2020年ECCV上有一篇思路比较清奇的工作从拓扑结构的角度切入试图在特征空间里保住类与类之间的几何关系这就是今天要拆的这篇Topology Preserving Class-Incremental Learning。我第一次读这篇的时候最直接的感受是它没有去卷怎么记住旧样本或者怎么约束参数而是问了一个更本质的问题——模型学到的特征空间里类别之间的相对位置关系能不能作为一种知识被保留下来这个视角在当时算是比较新颖的。下面我按自己的理解把这篇工作的动机、方法、实验和落地时容易踩的坑完整地捋一遍。适合做增量学习方向的研究生、需要落地持续学习系统的算法工程师以及对表征学习感兴趣的同学参考。1. 类增量学习到底难在哪为什么值得从拓扑角度重新看1.1 灾难性遗忘的本质是表征漂移不只是分类头失忆很多人一提增量学习第一反应是模型学了新类就忘了旧类。这个描述没错但太粗糙。真正的问题分两层一层是分类器层面的偏置新类的权重在训练中被反复更新旧类的决策边界被挤压另一层更隐蔽是特征提取器本身的漂移。网络参数一动旧类样本在特征空间里的分布就整体挪位了哪怕你冻结分类头旧类特征也已经不在原来的位置上了。传统方法大多在治第一层病。比如知识蒸馏让新模型在旧类上的输出逼近旧模型比如回放存一部分旧样本一起训。这些方法有效但它们默认了一个前提只要输出对得上特征怎么变无所谓。可实际上特征空间的几何结构一旦被破坏类与类之间的可分性就会下降尤其是在增量步数多了以后特征会逐渐坍缩到少数几个方向上。这篇论文的出发点就在这里。作者认为旧类样本在特征空间中形成的相对几何关系——谁离谁近、谁和谁在哪个方向上——本身就是一种结构化的知识。如果新任务训练时能把这个结构保住那么旧类的可分性就能维持遗忘也会被抑制。这就是拓扑保持这个名字的由来。1.2 拓扑保持和传统蒸馏的区别在哪这里要澄清一个容易混淆的点。知识蒸馏保的是输出分布也就是softmax之后的概率向量。而拓扑保持保的是特征空间里的相对关系是softmax之前的东西。两者关注的对象不一样。举个例子。假设有三个旧类A、B、C在旧特征空间里它们构成一个三角形A离B近C离两者都远。蒸馏只要求新模型对这三个类的预测概率别变太多但它不关心A、B、C的特征点在新空间里是不是还构成类似的三角形。完全可能出现这种情况预测概率对了但A和B的特征被挤到一起C被推到很远三角形被压扁了。这时候如果再来一个新类D它很可能就插在A和B中间把原本清晰的边界搅乱。拓扑保持要做的就是约束这个三角形别变形。具体怎么约束后面会讲。这里先建立直觉它管的是一种关系型的知识比单纯的输出对齐更细粒度。1.3 为什么这个思路在ECCV2020那个时间点有价值2020年前后增量学习的主流还是基于蒸馏和回放的混合方案比如iCaRL、LwF、EEIL这些。它们的问题在于随着增量步数增加性能衰减还是很明显。大家开始意识到光靠输出层面的约束不够得往表征层面挖。同期也有一些工作在关注特征空间比如用原型prototype来代表类用类均值来约束。但原型方法只保住了类中心的位置没保住类与类之间的相对结构。拓扑保持相当于把约束从点扩展到了点之间的关系粒度更细。这个思路在当时是有增量价值的也是它能上ECCV的原因之一。2. 拓扑保持的核心机制拆解从样本关系到损失函数2.1 用什么样的数学对象来描述拓扑论文里描述拓扑用的工具是样本之间的相似度关系。具体来说对于一个batch里的样本计算它们两两之间的特征相似度形成一个相似度矩阵。这个矩阵就编码了当前特征空间里的局部拓扑结构——相似的样本对相似度高不相似的相似度低。关键操作是在训练新任务时同时计算旧模型和新模型在这个相似度矩阵上的差异把它作为损失的一部分。这样新模型在学新类的同时被要求维持旧样本之间的相似度关系不变。注意这里约束的是样本对之间的关系不是单个样本的绝对位置所以它对特征的整体平移、旋转有一定的容忍度但对谁和谁像这种相对关系很敏感。这个设计有个好处它不需要存旧样本的原始特征只需要在训练时能拿到旧样本或者旧样本的代理计算它们的相似度即可。如果配合回放缓冲区实现起来就很自然。2.2 相似度矩阵怎么构造温度系数为什么重要构造相似度矩阵的常见做法是对特征做L2归一化然后算内积再除以一个温度系数。公式大致是S_ij exp(sim(f_i, f_j) / T) / sum_k exp(sim(f_i, f_k) / T)这里T是温度。温度的作用是控制相似度分布的尖锐程度。T小分布尖锐只有最相似的样本对才有高权重T大分布平滑所有样本对都参与。为什么温度重要因为它决定了拓扑约束的关注范围。如果T太小模型只被要求保住最近邻关系局部结构保住了但全局结构可能乱如果T太大约束太松区分度不够拓扑保持的效果就弱。论文里一般会设一个适中的值比如0.1到0.5之间具体要看数据集和特征维度。这个参数在实际复现时是需要调的不能照搬。2.3 损失函数怎么组合各项权重怎么定整体损失一般是三部分相加新类的分类损失交叉熵、旧类的蒸馏损失可选、拓扑保持损失。拓扑保持损失通常用KL散度或者交叉熵衡量新旧相似度分布的差异。权重方面拓扑损失的系数不能太大否则会压制新类的学习也不能太小否则起不到约束作用。经验上拓扑损失系数在0.1到1之间比较常见。如果增量步数多可以适当调大因为后期遗忘更严重。这个权重和温度系数是耦合的调的时候最好固定一个调另一个别同时动。提示复现时如果发现新类准确率上不去先检查拓扑损失权重是不是太大了。这个损失本质是在拉住旧结构拉得太狠会限制模型适应新数据的能力。2.4 和原型方法的对比为什么关系比点更稳原型方法比如把每个旧类的特征均值存下来训练时约束新特征靠近旧原型有个问题原型是一个点它对特征的绝对位置敏感。如果新任务导致特征整体平移原型约束就会失效甚至产生冲突。拓扑保持约束的是关系对整体平移、旋转不敏感。只要样本之间的相对相似度不变特征整体挪一挪没关系。这种不变性让它在增量场景下更鲁棒。当然代价是计算量更大因为要算样本对之间的关系复杂度是O(n²)。实际实现时一般在一个batch内算batch size不会太大所以还能接受。3. 复现这篇论文时最容易翻车的几个环节3.1 回放缓冲区的采样策略直接决定拓扑约束有没有意义拓扑保持损失需要旧样本来计算相似度关系。如果缓冲区里旧样本太少或者采样偏差大算出来的相似度矩阵就不能代表真实的旧拓扑约束就形同虚设。我的经验是缓冲区里每个旧类至少保留20到50个样本且要尽量覆盖类内的多样性。如果只存类中心附近的样本相似度矩阵会过于集中拓扑信息量不足。采样时可以用herding策略iCaRL那套也可以用随机采样但一定要保证每个类都有代表。另外计算拓扑损失时旧样本和新样本最好在同一个batch里混合这样相似度矩阵能同时反映新旧关系。如果分开算新旧之间的拓扑关系就丢了效果会打折。3.2 温度系数和损失权重的联合调参是个坑前面提过温度和权重耦合。实际调的时候我建议先用一个较小的拓扑权重比如0.1跑通流程确认新类能正常学然后再逐步加大权重观察旧类准确率的变化。温度可以先固定在0.1等权重定了再微调温度。有个常见的错误是一上来就把拓扑权重设得很大结果模型完全被旧结构绑死新类学不进去最后所有类准确率都低。这时候人会以为是方法不行其实是参数没调好。3.3 特征归一化方式会影响相似度矩阵的稳定性算相似度之前要不要做L2归一化这个细节影响很大。如果不归一化特征的模长会进入相似度计算而模长在训练中波动很大会导致相似度矩阵不稳定。一般建议做L2归一化让相似度只反映方向不反映模长。但归一化也有副作用它会把所有特征压到单位球面上可能损失一些幅度信息。如果数据集本身类间差异主要靠幅度体现归一化反而有害。这个要看具体任务不能一刀切。3.4 增量步数多了以后拓扑约束会逐渐失效这是拓扑保持方法的一个固有局限。随着增量步数增加旧样本在缓冲区里的占比越来越小新类越来越多相似度矩阵被新类主导旧拓扑的约束力被稀释。到后期拓扑损失对旧类的保护作用会明显下降。缓解办法有几个一是动态调整拓扑权重后期加大二是用生成式回放补充旧样本三是分层约束只对最近几个任务的类做拓扑保持更早的类靠其他机制保护。论文里没有完全解决这个问题实际落地时需要自己补。4. 实验设计上的取舍怎么验证拓扑保持真的有用4.1 消融实验要控制变量别把蒸馏的功劳算到拓扑头上这篇论文的消融实验里最关键的是要证明拓扑损失单独起作用。但实际实现中拓扑损失往往和蒸馏损失一起用两者有重叠。如果消融时只去掉拓扑损失保留蒸馏性能下降可能不明显让人误以为拓扑没用。正确的做法是设计三组对比只用蒸馏、只用拓扑、两者都用。如果只用拓扑就能接近两者都用的效果说明拓扑确实是主力。论文里应该有类似的设计复现时也要照做。4.2 评价指标不能只看平均准确率增量学习的评价指标有好几个平均准确率average accuracy、遗忘率forgetting measure、后向迁移backward transfer。只看平均准确率会掩盖问题。拓扑保持方法的特点是旧类准确率保持得好但新类可能略低平均下来可能和基线差不多。这时候要看遗忘率如果遗忘率明显低说明方法有效。另外建议画一下特征空间的t-SNE图直观看看旧类的簇有没有被破坏。这个图在论文里通常会有复现时自己也画一下能发现很多数字上看不出来的问题。4.3 数据集选择要覆盖不同难度论文一般会在CIFAR-100、ImageNet-subset这些标准数据集上测。复现时建议至少跑两个数据集一个小的CIFAR-100快速验证一个大的ImageNet子集看扩展性。如果只在CIFAR上跑结论可能不 robust。还有个细节增量步数的设置。常见的有10步、20步、50步。步数越多越难拓扑保持的优势在步数多的时候更明显。如果只跑5步可能看不出差异。5. 从论文到落地这套方法适合什么场景5.1 适合类边界清晰、类间关系稳定的任务拓扑保持假设旧类的相对关系是有意义的、值得保留的。如果任务本身类间关系就很模糊或者类定义随任务变化这个假设就不成立。比如细粒度分类里类间差异很小拓扑关系本身就不稳定硬保可能适得其反。比较适合的场景是类之间有明显语义层次比如动物、植物、日用品这种大类类间关系相对稳定。或者工业质检里缺陷类型有明确的物理区分拓扑结构有意义。5.2 计算开销和存储开销的权衡拓扑损失的计算是O(n²)n是batch里参与计算的样本数。如果batch size是64那相似度矩阵是64x64还好。但如果为了算得更准把batch开到256矩阵就是256x256显存和计算都会上去。实际部署时要根据硬件条件权衡。存储方面缓冲区大小直接影响效果。一般建议缓冲区能存1000到2000个样本每个类均匀分配。如果存储受限可以考虑用特征压缩或者原型协方差的方式来近似但会损失一些精度。5.3 和其他增量学习技术的组合空间拓扑保持不是孤立的它可以和很多技术组合。比如和知识蒸馏组合一个管输出一个管特征和参数正则组合一个软约束一个硬约束和生成式回放组合用生成样本补充旧拓扑。组合的时候要注意别让约束互相打架。比如蒸馏要求输出分布一致拓扑要求特征关系一致如果两者冲突模型会无所适从。一般建议先让拓扑损失主导特征层蒸馏损失主导分类层分工明确。6. 我个人在复现和扩展中的几点体会第一次复现这篇论文时我最大的教训是低估了缓冲区采样的重要性。当时为了省事每个旧类只存了5个样本结果拓扑损失几乎没效果旧类准确率掉得和基线一样。后来把每类样本加到30个效果立刻出来了。这说明拓扑保持对样本数量是有下限要求的样本太少相似度矩阵估计不准约束就是噪声。第二个体会是温度系数的敏感性。我试过T0.05和T0.5前者太尖锐模型只关注最近邻旧类的全局结构保不住后者太平滑约束太弱几乎没作用。最后在CIFAR-100上定在0.1左右比较稳。这个值可能因数据集而异建议复现时做个简单的网格搜索。第三个体会是关于增量步数。在10步的设置下拓扑保持相比基线的提升大概2到3个百分点到20步提升能到4到5个百分点步数越多优势越明显。这也符合直觉步数少的时候遗忘本身就不严重拓扑保持的边际收益小。最后一个建议如果你打算在这个方向上做扩展可以考虑把拓扑约束从样本级扩展到类级用类原型之间的关系来构造拓扑这样计算量能降下来而且对缓冲区大小的依赖也会减小。这个思路我在小规模实验里试过效果还不错但还没系统验证有兴趣的可以试试。注意拓扑保持的核心是关系不变性任何破坏这个不变性的操作比如强数据增强导致特征剧烈变化、学习率过大导致特征跳变都会削弱它的效果。训练时学习率建议用warmup别一上来就大。整体看下来这篇ECCV2020的工作在思路上是有启发性的它把增量学习的关注点从记住什么转向了记住关系。虽然工程落地还有不少细节要磨但作为理解表征层面增量学习的一个切入点值得花时间读一读、跑一跑。