
刚把这篇持续学习综述从头到尾啃完趁着热乎劲儿还在把笔记和心得整理出来。如果你在接触增量学习、终身学习、或是想让模型像人一样“边学边不忘记”这篇文章应该能省下你大量翻论文的时间。这篇综述的全称是A Comprehensive Survey of Continual Learning: Theory, Method and Application算是目前覆盖范围最全的持续学习Continual Learning, CL综述之一。它不光是罗列方法还从理论、方法、应用三个维度做了系统梳理。我读完最大的感受是持续学习这个领域已经被拆得非常细了但细中有主线只要抓住“灾难性遗忘”这个牛鼻子后面的东西都能贯起来。1. 持续学习到底解决什么问题先搞懂“灾难性遗忘”这条主线1.1 一个所有深度学习开发者都会撞上的痛点先设想一个场景你训练好的图像分类模型在A类数据上精度已经到90%了这时候来了一批B类数据你想让模型顺便学会B。常规做法就是拿着新数据继续微调但跑完你会发现模型在A类上的精度掉得惨不忍睹——这就是典型的灾难性遗忘Catastrophic Forgetting。很多人第一次遇到这个问题时第一反应是“是不是学习率太大导致参数崩了”于是调小学习率、加正则折腾一圈后发现精度依然回不来。原因其实很本质神经网络在通过梯度下降更新参数时新任务会改动那些对旧任务至关重要的权重。教科书里讲的“模型参数是对数据分布的压缩表示”在连续多任务场景下这套压缩会被新任务覆盖掉旧信息被连带冲散。这在统计学习里叫非独立同分布下的持续学习问题在工程里叫“模型老是学会了新的就忘了旧的”。持续学习Continual Learning要做的就是让模型在顺序学习多个任务的过程中同时做到三点能学会新任务、不显著遗忘旧任务、且尽可能不依赖已经见过的旧数据。这里“尽可能不依赖旧数据”是实操里的关键约束——很多工业场景根本存不下历史数据或者出于隐私原因不能存。1.2 稳定性-可塑性困境持续学习所有矛盾的起点理解了灾难性遗忘之后再看整个领域你会发现所有方法和设计其实都围绕一个核心矛盾稳定性与可塑性。模型的参数空间同时承载着旧知识与新知识。如果你把参数锁得太死模型的稳定性很高但学新东西的能力——可塑性——就会变差新任务精度上不去反过来如果你完全放开参数新任务倒是学得快旧任务的知识就被冲掉了。这个两难在文献里叫Stability-Plasticity Dilemma它是持续学习所有偏执设计的出发点。举个例子后面要讲的正则化方法本质是“允许参数动但朝某些方向动会付出代价”回放方法本质是“把旧数据留着或模拟出来随时拉着模型回忆”架构方法本质是“给新任务分配额外参数旧任务权重尽量不碰”。每一种策略都是稳定性与可塑性之间的一次取舍。搞清楚这一点你在读具体论文时就不会迷失在公式里你会有意识地追问这个方法倾向于保稳定性还是保可塑性它在哪个维度上做了妥协1.3 三种增量场景任务增量、领域增量、类别增量读持续学习的论文一开始最容易被概念整懵的就是任务增量Task-Incremental Learning、领域增量Domain-Incremental Learning、类别增量Class-Incremental Learning这三兄弟。它们之间的差异决定了解题范围。任务增量Task-IL每个任务有明确的标识测试时知道当前是哪个任务模型可以针对性地用对应输出头。难度最低相当于“分别学多个任务只是共享特征提取层”。领域增量Domain-IL任务之间没有明确边界输入分布会变化但输出类别集合保持一致。比如同一个相机在不同光照下的图像标签集合不变。类别增量Class-IL任务按新类别到来模型需要学会所有见过的类别测试时不提供任务标识模型要在不断扩大的类别集上做统一预测。这是最贴近真实世界的设置也是难度最高的。我在这里吃过亏早期复现某方法时论文说效果比常规基准高很多我拿过来一直调参数都达不到后来才发现论文用的是 Task-IL 的评估协议而我在按 Class-IL 跑。两者对“任务标识是否可得”的假设不一样精度差异可以达到二三十个百分点。所以读任何持续学习论文第一件事是确认它跑的是哪种增量场景否则对比就没有意义。2. 方法体系全景拆解三大技术流派各自的算盘与局限2.1 正则化方法不保存数据但圈住参数的活动边界正则化方法的核心逻辑是新任务来了模型参数可以继续更新但对那些对旧任务非常重要的参数更新时要施加惩罚不让它们偏移太远。最经典的代表是EWCElastic Weight Consolidation弹性权重巩固。EWC 的思路是用 Fisher 信息矩阵Fisher Information Matrix去估算每个参数对旧任务的重要性。Fisher 信息大的参数说明对旧任务似然影响大更新时要强力拉住Fisher 信息小的参数则可以放飞自我。在实现上EWC 在损失函数里加一个二次正则项[ L(\theta) L_{new}(\theta) \frac{\lambda}{2} \sum_i F_i (\theta_i - \theta_{i}^{old})^2 ]其中 (F_i) 是参数 (\theta_i) 的 Fisher 信息值(\theta_{i}^{old}) 是旧任务学习结束后的参数(\lambda) 控制正则强度。直观理解Fisher 信息就像给每个参数挂了一把“锁”信息量越大锁越紧新任务想掰动它就越费劲。LwFLearning without Forgetting则是另一种思路——不锁参数而是用旧模型对旧任务输出的响应做知识蒸馏约束。新任务训练时除了正常的分类损失还要让模型在新数据上的输出保持与旧模型一致从而“默默回忆”旧知识。这个方法的好处是不需要 Fisher 计算实现简单但缺点是当任务数多了之后误差会累积易出现“蒸馏漂移”。正则化方法最大的优势是不需要存储旧数据内存占用恒定。但缺点是在类别增量场景下早期任务的决策边界很容易被后续任务挤压因为决策边界本质上需要旧数据来“撑住”仅靠参数约束很难精确保持。实操中灾难性遗忘严重时这类方法会上限较低适合任务数少、数据分布变化不剧烈的场景。2.2 回放方法最朴素有效的办法——把旧数据留着“复读”如果你试过正则化方法发现效果一般那就该上回放方法Replay了。这个流派的思路简单粗暴内存里存一部分旧任务的数据或特征训练新任务时把它们掺进当前批次让模型每次更新都同时看到新旧数据从而抑制对旧知识的覆盖。经验回放Experience Replay是最基础的实现假设你允许保留一个大小为 (K) 的样本缓冲区每学完一个任务从该任务数据中挑选一部分代表性样本存进去每次训练时从缓冲区和当前任务数据中一起采样组成训练批次。关键问题是什么选什么样的样本进缓冲区。最常见的是随机采样但随机采样在任务较多时代表性会退化。后来有工作提出按梯度方向挑选样本或者按难例挖掘策略保留那些模型容易遗忘的样本这类方法统称为基于样例选择的回放。另一个方向是生成式回放Generative Replay代表方法是DGRDeep Generative Replay。它用生成模型模拟旧任务的分布训练新任务时把生成器生成的伪样本与真实新样本一起喂给模型。这种方案的优点是理论上不需要存储任何真实旧样本但对生成模型质量要求极高——如果生成器生成的旧样本已经失真那模型复习到的就是“被污染的回忆”误差会随任务累积。我的个人体验是回放方法尤其是经验回放是所有方法里性价比最高的。它原理简单、实现快速、效果稳定。在很多基准上一个带固定内存的简单回放就能干过一堆复杂的正则化算法。这在机器学习里不算罕见——有时候最简单的基线因为足够朴素稳定反而能在各种复杂场景中保持竞争力。2.3 架构方法给新任务单独开一块“地盘”架构方法走的是另一条路与其限制或复习不如给新任务分配专属参数。代表思路有两种一种是动态扩充网络——每来一个新任务就为它新增一组网络模块比如新任务专用的分类头或特征提取分支旧任务参数保持冻结不再更新另一种是参数隔离与路由——同一个网络通过掩码Mask为不同任务分配不同子网络任务推理时通过标识选择对应子网络。架构方法在任务增量Task-IL场景下表现最强因为任务标识是已知的每个任务可以各自有独立输出头几乎不存在任务间干扰。但是它的致命缺陷也很明显模型体积会随着任务数量线性增长。你做10个任务就要存10份模块或掩码参数做100个任务模型会变得极重。这在工业部署里往往不可接受因为你得为未来的未知任务预留足够多的扩展空间但实际硬件资源是有限的。我记得有一篇论文里把架构方法形象地称为“一种通过增加模型容量换取知识容量的做法”说白了就是用空间换时间。如果你的应用场景是任务数量有限且可预估的动态扩充是很好的选择但如果你想做一个“永远学下去”的在线系统纯靠扩充参数是不可持续的得配合剪枝或者参数共享策略来控制体积。2.4 三类方法横向对比选型建议与实验直觉方法类型代表方法是否存旧数据内存开销类别增量表现适用场景正则化EWC、LwF、SI否低且恒定中等偏弱任务数少、存储受限、近似在线回放ER、GEM、DGR是或生成器随缓冲区增长强通用场景实测稳健架构PackNet、HAT、动态扩充否随任务线性增长强依赖任务标识任务可预估、能接受模型膨胀实际落地时我建议的选型标准是如果任务数在10个以内存储预算又很紧先试EWC或LwF因为它们改动最小如果效果不达标升级到经验回放——这是性价比的甜点区间只有当任务数非常多、且你能接受模型变大才需要考虑架构类的方案。3. 评估体系与基准别让“精度提升2个点”忽悠了你3.1 评估协议任务标识到底给不给持续学习领域的评估比普通机器学习要敏感得多一个小小的设定差异结果就是天壤之别。你复现论文时一定要死抠三个细节任务边界是否明确测试时是否给出任务标识以及学习过程中是否允许访问旧数据。在训练侧任务边界通常由数据集定义——比如 Split CIFAR-100 按 20 个任务每个任务 5 个类依次出现Permuted MNIST 则是同一批数字在不同随机排列下构成不同任务。在测试侧Task-IL 会给模型任务标识模型能用对应的输出头预测Class-IL 不给标识模型要从所有见过的类中判断。还是那句话——用 Task-IL 评估出来的结果可能虚高很多因为模型每步都知道自己在做哪个任务难度直线下降。我强烈建议你在读论文时先把论文的 Setting设置部分单独截图存下来再看结果。如果一篇论文只在 Task-IL 下评测并宣称“超越所有方法”它的实际落地价值是存疑的。真实世界的应用场景——尤其是移动端、边缘端的模型持续更新——几乎都是 Class-IL 或者 Domain-IL。3.2 三个常用指标准确率、回溯、前向迁移评估持续学习性能时只用最终精度是不全面的。领域里约定俗成至少要看三个指标平均准确率Average Accuracy, ACC所有任务学习完成后在每一个已学任务上的测试精度取平均。衡量模型最终的整体记忆水平。平均回溯Average Backward Transfer, BWT每个新任务学完后旧任务精度的平均变化。BWT 为正说明后续任务反而带来正向迁移旧任务变好了BWT 为负代表遗忘正在发生。前向迁移Forward Transfer, FWT模型在任务 (t) 上学到的知识对任务 (t1) 的学习有多大帮助。FWT 越高说明模型的表示泛化能力强。一张典型的持续学习结果表通常是一串任务的累积矩阵Task×Task 的测试精度矩阵对角线表示刚学完的精度左下角表示未来任务的回溯。看这种矩阵比盯着单点精度有意思得多你能直观看出模型在哪一步开始崩溃又是哪一步被后续任务严重干扰。我自己复现实验结果之后第一件事永远是画累积矩阵图而打印平均精度——矩阵图能暴露很多平均精度掩盖的问题比如某次学习灾难性严重、但平均到每个任务后被抹平了。3.3 常用基准与数据划分从简单到复杂持续学习有一套约定俗成的基准池了解它们能让你快速判断一个方法在什么难度级别上有效Split MNIST / Permuted MNIST入门级。Split MNIST 把0-9分成5个二分类任务Permuted MNIST 把像素随机重排生成不同任务。由于任务简单很多方法都能近饱和适合跑通流程。Split CIFAR-10 / CIFAR-100中等难度。Split CIFAR-100 是20任务×5类或10任务×10类是当前论文最常报的基准之一。Split TinyImageNet / ImageNet-Subset高难度。类别多、分辨率高对回放缓冲区和正则化方法都是严峻考验。Domain-Net / CORe50领域增量特殊基准模拟同一物体在不同域光照、背景、旋转下的持续变化。实验时我常犯一个误区一开始就在 CIFAR-100 上调参结果疯狂跑不动。后来学乖了先在 Split MNIST 上验证方法运行正确再去 CIFAR-100 做真正对比效率翻倍。4. 理论视角为什么持续学习这么难以及理论给我们的启发4.1 从最优传输和风险泛化角度看遗忘综述里有一个很值得琢磨的理论视角把连续任务学习看作一组任务风险的最小化问题。每个任务对应一个损失函数 (L_t(\theta))理想情况下我们希望模型在所有任务上的联合损失都能保持较低。但梯度下降不是这样工作的——它沿着当前任务损失下降最快的方向走这个方向在旧任务损失上的梯度可能很大导致旧任务风险骤增。这就是为什么单纯微调会灾难性遗忘神经网络的高度表达性让它能轻易找到一组只优化新任务、而不管旧任务的参数。EWC 等正则化方法本质上是在旧任务风险附近引入一个惩罚约束让新任务优化尽量发生在旧任务风险盆地loss basin的平坦区域。你也可以把 Fisher 信息看作是旧任务损失在最优参数附近的二阶曲率估计——曲率大的方向推一下损失就会飙升所以要锁住。4.2 梯度空间中的冲突GEM 的启示提到理论解析GEMGradient Episodic Memory是个不得不提的经典。它的核心洞察是在新任务梯度方向 (g) 之上检查它会不会提高旧任务的损失——如果会就把它投影到离所有旧任务梯度都不冲突的方向上确保新旧任务更新方向夹角不超过90度。技术上GEM 每次更新时求解一个二次规划QP问题[ \min_g \frac{1}{2} |g - \text{原梯度}|^2 \quad \text{s.t.} \quad \text{旧任务梯度} \cdot g \ge 0 ]这个约束的意思是旧任务在预测时的损失不会因为你这次更新而变大。GEM 的实现并不复杂但启发意义很大——它让我们意识到灾难性遗忘不只是“参数覆盖”的问题更本质的是梯度冲突当前任务梯度与旧任务梯度在参数空间内存在冲突方向只要你能巧妙地规避冲突就可以在不存旧数据的情况下大幅减少遗忘。顺带一提A-GEM 是 GEM 的轻量版不要求每一个旧任务都满足约束而是要求对旧任务整体的平均损失不上升求解速度更快。实战里 A-GEM 更容易跑通也更稳定。4.3 理论结论对方法设计的实际启示理论往往不是拿来直接写代码的但它能给你很强的设计方向感既然灾难性遗忘发生在梯度方向冲突上那么设计方法时可以关注梯度方向约束而不是简单加权重衰减。既然旧任务损失曲面存在曲率差异那么用 Fisher 对角近似一阶曲率能低成本地实现不错的效果。既然模型参数高度冗余那么通过稀疏掩码把不同任务分配到不同子空间可以大幅减少干扰。另外记忆重放本质上是在用旧样本估计旧损失梯度相当于从数据层面修正梯度偏差——这解释了为什么回放方法总是比纯正则化有效因为它直接修正了梯度方向而非侧面包一个惩罚项。5. 前沿应用场景从视觉到语言模型持续学习在哪落地5.1 计算机视觉从分类到分割再到目标检测持续学习在视觉领域的应用是最广泛的。分类任务之外目标检测、语义分割、实例分割都面临模型上线后要学习新类别的需求。比如一个安防监控系统已经能识别常见物体新出现了一批要识别的目标类别如果重新全量训练代价巨大如果直接微调老类别的检测性能掉得让人崩溃。这时候持续学习就有了用武之地。视觉领域的难点在于检测和分割的输出是稠密的——一张图上多个目标的类别、位置、掩码一起输出这比分类任务的信息维度高得多。在持续学习设定下旧任务目标一旦没被正确识别模型无法像分类那样简单地给一个错误类名整个检测框就会消失对后续算法链路影响很大。所以视觉持续学习常用的技巧包括冻结特征提取器、只微调检测头或者用回放样本联合训练检测头。如果你在这一行做落地最稳的起点是冻结骨干网络只更新最终输出层——这样旧特征的语义空间不被破坏遗忘率会大幅下降。5.2 自然语言处理大模型时代的持续预训练与指令增量NLP 领域的持续学习可以分为两类主题持续预训练和持续指令学习。持续预训练指模型在新领域语料上继续训练比如一个通用语言模型要在医疗文本上继续学习。此时如果直接微调通用能力会退缩。常规做法是收集一个混合语料新语料通用语料抽样做二次预训练同时用回放和知识蒸馏控制遗忘。这其实就是工程领域常说的“增量预训练”本质上是一种回放策略的落地。指令增量学习则更前沿——模型要在用户新给出的指令/任务上学会正确响应同时不能丢掉旧指令的处理能力。比如一个多模态助手今天学了一个新技能明天被要求回答问题不能因为学了新技能就忘了怎么回答旧问题。大模型时代持续学习与模型对齐Alignment结合是当前的热点很多公司在模型迭代时采用“核心能力注入旧能力蒸馏”的混合方案保证模型一次比一次强而不是一次比一次偏。5.3 推荐系统与用户画像数据分布漂移的常态战场推荐系统可能是持续学习最“刚需”但最不显眼的落地场景。用户兴趣随时间漂移、热门物品变换、新物品不断加入推荐模型必须在数据流中不断学习。线下全量重训成本高线上增量更新如果直接微调旧兴趣会被吞噬推荐的多样性会崩塌。很多大厂的做法是双模型结构一个长期模型负责稳定兴趣更新慢、用全量数据抽样一个短期模型负责捕捉实时兴趣更新快、只吃近期数据再通过门控机制融合。这个架构虽然不是标准的持续学习论文但本质上就是稳定性与可塑性的工程化妥协——长期模型保稳定短期模型给可塑两者融合得到平衡。如果从头搭这类系统我建议先从经验回放组件做起在系统里加一个最近N天的交互样本池在线更新时按比例混合效果改善往往会很明显。6. 论文精读实操我啃综述类论文的方法与踩坑记录6.1 精读综述的技巧先扫框架后钻公式综述类论文Survey和普通单点技术论文的读法完全不同。单点论文的目标是从问题到方法再到实验验证一条线综述论文则承担着“给你一张领域地图”的职责不能逐页细读那样会陷入细节而失掉全景。我的做法是“三轮阅读法”。第一轮只读摘要、引言、结论和各个大段的标题10分钟画出领域总地图搞清楚综述把方法分成哪几大类、评估用了哪些基准第二轮在各方法段落里精读最核心的两三篇代表论文把它们的数学表达推导一遍第三轮是带着问题回去查比如“这方法在Class-IL下还能打吗”“它的存储开销是多少”“它需要几步训练前步骤” 这种带着问题检索式阅读比从头到尾死磕效率高得多。以这篇综述为例第一轮读下来你手里的地图应该是理论遗忘为什么发生、如何建模→ 方法正则化/回放/架构三大流派→ 评估任务协议与指标→ 应用视觉/NLP/推荐等场景。有了这张图之后再读任何单篇论文你都可以瞬间把它定位到对应流派并自动联想到它的邻域工作和优劣关系阅读速度会提升一个量级。6.2 亲手复现一个最小实验配置防遗忘例行检查读综述不能只看我建议你亲手写一个最小实验哪怕是玩具也能把几个关键概念串起来。一个可行的最小配置是用一个两层MLP在 Split MNIST 上测试三种方法。1直接顺序微调Fine-tuning学完第二个任务后第一个任务精度大概率腰斩2EWC在损失里加Fisher正则项遗忘明显缓解3经验回放缓冲区每类存20个样本精度可能超过EWC。当你亲手写出这三个实验并对比曲线后灾难性遗忘的观感就彻底融入直觉了。你会发现几个有趣现象EWC里的 (\lambda) 参数要调到1左右才有效调到10会过分锁死参数导致可塑性丧失经验回放虽然简单但每类只要存少量样本就能稳住大部分精度直接微调时即使把学习率降得很低遗忘依旧严重说明这不只是“步子太大”的问题还有任务间梯度冲突的本质因素。6.3 踩坑记录复现论文时最容易翻车的细节最后分享几条我在持续学习复现中踩过的坑读到就是赚到。坑一评估协议没对齐结果对不上。这一点再强调一遍都不嫌多。你复现论文A在 CIFAR-100 上的结果时先确认它用的是 Split CIFAR-100 的哪个版本5类一个任务还是10类一个任务任务划分方式不同结果没有可比性。坑二没有固定随机种子实验方差极大。持续学习对初值、数据顺序、回放采样顺序都极度敏感。我实测在 Split CIFAR-100 上同一方法换一个随机种子能差3~5个点。复现或对比时最少跑5个种子取均值并在论文里标明。坑三回放缓冲区样本来源要严格区分。某些论文会偷懒在回放时把当前任务数据也当作缓冲区的补充这实际上是变相提升了显式存储量。对比时必须保证缓冲区大小在所有方法之间一致否则你的基线是在羞辱自己。坑四正则项里的Fisher矩阵计算有叠加误差。EWC 在多个任务累加 Fisher 时如果任务多对角矩阵近似下存储其实很省但需要在线累计别每次从头重算会非常慢。工程上可以把每个任务结束后的 Fisher 保存下来累加到公共对角矩阵中。坑五评估回放方法时注意训练轮数的公平性。有些回放方法每个任务训练多个epoch而有些只训练一个epoch这种训练量差异足以反转结论。在所有对比中统一总训练步数否则比较的是训练预算而不是方法本身。提示持续学习实验的复现难度普遍高于普通监督学习线性探测linear probing和冻结骨干这两招几乎是视觉任务里的“免死金牌”工具实在调不动就优先试试它们。最后说点个人体会这篇综述我读下来最大的收获不是某个具体算法的细节而是对整个领域“条条大路通遗忘”的全局感。持续学习的难点表面上看是算法设计核心其实是数据分布与参数空间的长期博弈。即使是最强的单点方法放到真实世界那种没有明确任务边界、动态变化的场景里也可能迅速失效。所以如果有条件设计自己的持续学习方案时先跑一个简单的经验回放作为底线再逐步叠加正则化和架构策略——这比一开始就端一套复杂算法上去再排错要稳妥得多。另外持续学习不是万金油也不是“一个模型把所有事情终身学完”的浪漫设想。在很多落地场景里周期性的离线全量训练依然是最好的工程决策持续学习更适合那些数据不断到来、全量训练成本不可接受、且旧知识有长期价值的场景。想清楚这一点才不会为了用持续学习而用持续学习。最后再分享一个小技巧在标准基准之外额外构造一个“混合领域增量”测试集用随机种子打乱顺序跑几遍你会更清楚一个方法在真实混乱场景下的鲁棒性到底行不行。