人不是这样学习的。你学会了骑车,也不会因此忘掉怎么走路。
但神经网络会——刚学会的任务,回头测一下,准确率可能直接从约 98% 掉到 50% 上下(随机猜)。
上一章《自适应计算》让「算多少」跟着输入变;这一章接着问:记住什么、忘记什么,也能变吗?
这一章你会亲手把它训出来。
神经网络的知识存在权重数字里。它没有一个「任务 A 的抽屉」和一个「任务 B 的抽屉」—— 所有任务共用同一堆参数。
为新任务做梯度下降,本质上是在调整那些同时也承载着旧任务的参数。 调整的幅度足够大,旧任务的知识就被覆盖掉了。 这不是 bug,是「参数共享」这个设计的必然结果。
像在一块已经写满字的黑板上写新内容。你只有这一块黑板(参数),
要写新的就得擦掉一部分旧的。
而梯度下降这个行为极其「只顾眼前」:它只关心怎么把当前的损失降下去,
完全不关心自己擦掉的是什么。
| 对比项 | 人 | 神经网络 |
|---|---|---|
| 学新技能 | 几乎不影响旧技能 | 旧任务能力断崖式下跌 |
| 机制 | 不同技能调用不同脑区,而且有睡眠期的记忆巩固 | 所有知识挤在同一批权重上,更新时没有保护 |
| 能不能靠「多练」解决 | — | 不能。不碰旧数据就一定会忘 |
因为现在的主流做法是「
这就是后面第 5 节要讲的对齐税。所以
互动 · 同一批 33 个参数,学 B 的时候被改动了多少
下面是一个在训练的网络:2 → 8 → 1 的小 MLP(2 个输入、8 个隐藏神经元、1 个输出)。 两个任务共用这一批权重,你来看旧任务的准确率怎么掉。
两个任务都只用两个输入(横坐标 x、纵坐标 y)。任务 A 的点只出现在左半边,按上下分: y > 0 判 1。任务 B 的点只出现在右半边,按左右分:x > 0.5 判 1。 网络看不到「现在做哪个任务」这个信号,只能凭输入猜。 A 的点全在左半边、B 的点全在右半边,两个区域不重叠——所以同一套权重本来可以同时对 (前提是学 B 时别把 A 覆盖掉)。
互动 · 真实的顺序训练
决策边界
① 任务 A 的准确率断崖式下跌。不是慢慢退化,是在开始训 B 之后的
最初几十步里就崩了——因为梯度毫不犹豫地把它覆盖掉。
② 网络完全没有「我在忘东西」的感觉。训练 B 的损失一路顺畅下降,
它对 A 的崩坏毫无察觉。损失函数里根本没有 A 这一项。
③ 打开回放(replay)再跑一次。训练 B 时混入一部分 A 的旧样本,
A 的准确率就被守住了。这就是最简单也最有效的解法。
① 你得留着旧数据。这在医疗、金融、隐私场景里可能直接不可行——
患者的影像数据不能长期保存并反复用于训练。
② 训练 B 会变慢。你把「回放比例」调成多少,就有多少比例的算力花在复习 A 上
(调到 20%,大约每 5 步里有 1 步在复习)。
这个「守住旧知识」和「学好新知识」的拉扯,有个专门的名字叫
稳定性-可塑性困境(stability-plasticity dilemma):
保护得太好就学不进新东西,放得太开就会忘掉旧的。没有两头都占的解。
上一节你亲眼看到旧任务的准确率掉下去。为什么会掉?这一节把它写成一行总目标, 再配两条损失曲线——每一个符号,都能在下面的图或滑块上指出来。
动画 · 训练 B 的时候,A 的损失在悄悄抬头
把参数想成家具摆位。L_B 是「新家好不好用」,只按它搬,你会把旧家具全扔掉。
EWC 就是搬家前给几件贵重家具各绑一根弹簧:越贵重的(F 越大)弹簧越硬,
想挪动它得先克服一股劲。结果是你不会为了新家把旧家彻底拆掉,而在两者之间找平衡。
微型图解 · 那根弹簧有多硬(F 真的算出来了)
| 思路 | 怎么做 | 代表方法 | 代价 |
|---|---|---|---|
| ① 正则化 (保护重要参数) |
估计「哪些参数对旧任务重要」,重要的不许大改 | EWC、SI、MAS | 保护太紧就学不进新任务;要算并存储 Fisher 信息矩阵,开销不小 |
| ② 回放 (复习旧数据) |
保留一部分旧数据,训练新任务时混进去 | Replay、GEM、A-GEM | 必须能存旧数据(隐私 / 存储问题);训练更慢 |
| ③ 参数隔离 (各用各的) |
给每个任务分配独立的参数子集 | Progressive Nets、PackNet、LoRA、提示池 | 模型会膨胀(每个任务一套参数);任务多了之后选择本身变成问题 |
EWC(Elastic Weight Consolidation,弹性权重固化)是正则化这一派的代表: 用 Fisher 信息估计「每个参数对旧任务有多重要」,然后在损失里加一项惩罚—— 重要的参数偏离旧值越远,惩罚越大,像给每个参数系了一根松紧不同的橡皮筋。 局限也明显:Fisher 的估计有噪声,任务越多,要固化的约束越互相冲突,能动的参数越来越少。
把三种解法想象成三个人共用一张书桌:
① 正则化:给重要的书贴上「请勿移动」的标签——但书多了之后,桌上到处是标签,新书没地方放。
② 回放:每次换书都先把旧书翻一遍——最有效,但你得留着所有旧书。
③ 参数隔离:每人分一块自己的区域——互不干扰,但桌子要越来越大。
互动 · 三类解法各得几分,外加什么都不做(真的各跑一遍训练)
一张图看懂三类解法在做什么
三类解法的共同点:都想让「学 B」这件事少碰、或者晚碰那些属于 A 的参数。区别只在手段——拦在损失里、拦在数据里、还是拦在结构上。
回放是最有效的一类方法,但「要回放多少」是个实际问题。
实测 · 回放比例 vs 旧任务保留率
这条曲线最值得注意的是头几步涨得特别快,后面很平:不回放基本忘光了, 加一点回放就拉回接近原来的水平,再往上加,收益迅速变小。 你不需要记住旧任务的每一个样本,只需要在参数空间里不断被「提醒」那个方向别跑太远。 所以如果你只能留 5% 的旧数据,那也比不留强得多——不要因为「留不全」就干脆不留。
互动 · 参数空间里的轨迹:先走到 A,再被 B 拽走
互动 · 回放缓冲里到底存了什么
阶段 5 讲过一个现象:微调会让模型损失一部分通用能力。
这在
| 现象 | 用持续学习的语言解释 |
|---|---|
| 对齐税 | 用偏好数据做 RLHF 时,模型把「听话」学得更好, 同时在通用基准上的分数掉了——旧任务被覆盖 |
| 在某个垂直领域数据上全量微调几十步, 模型的通用对话能力可能明显退化。领域内变强,领域外变傻 | |
| LoRA 为什么能缓解 | 因为绝大部分原始权重被冻住了,只有一小块低秩矩阵在学习。 相当于「给每个任务开一个小小的独立抽屉」——正是参数隔离的思路 |
| 但 LoRA 也会忘 | 只是程度轻。LoRA 学到的方向仍然在改变模型的输出, 只是它被限制在一个低秩子空间里,破坏力有限 |
| 多任务 LoRA 会打架 | 两个不同任务的 LoRA 合并在一起时,效果往往不如单独用。 因为它们学到的方向可能互相冲突 |
混入一小部分通用数据,几乎总是能缓解对齐税。这和大模型微调里的
「rehearsal / replay 比例」是同一件事——现有的大模型训练配方里,
数据混合比例本身就是在做
只不过大家通常不这么称呼它。
为什么 LoRA(参数隔离)能缓解对齐税
全量微调会动 W 里的每一个数;LoRA 只动右侧那一小块 ΔW = U·V——低秩就是把一个大矩阵换成两个很小矩阵相乘,参数量少得多,绝大部分原始权重被冻住。 领域内能变强,又不至于把通用能力铲平。这里的 U、V 和上面的任务 A、B 无关。
| 类别 | 方法 | 核心机制 |
|---|---|---|
| 正则化 | EWC (2017) | 用 Fisher 信息矩阵衡量参数重要性,加二次惩罚 |
| SI (2017) | 沿训练过程累积每个参数对损失变化的贡献(不需要 Fisher) | |
| MAS(Memory Aware Synapses,2018) | 看输出对哪个参数最敏感;不需要标签 | |
| 回放 | Replay | 直接保留并混入旧样本。最简单,通常也最有效 |
| GEM / A-GEM | 把旧任务的梯度当作约束,防止新梯度与它冲突 | |
| 生成式回放 | 不存真实数据,训一个生成模型来「回忆」旧数据——解决隐私问题 | |
| 参数隔离 | Progressive Nets | 每来一个新任务就加一列新参数,旧列冻结 |
| PackNet | 剪枝 + 重分配:把不重要的权重腾出来给新任务 | |
| LoRA | 低秩增量,基座冻结。今天最实用的一个 | |
| 提示池 Prompt Pool | 给每个任务学一组提示向量,推理时按任务选提示 | |
| 架构搜索 | 动态网络 / NAS | 让网络自己决定为新任务扩展哪一部分结构 |
| 难点 | 具体表现 | 什么时候真的会痛 → 换什么 |
|---|---|---|
| 稳定性-可塑性困境 | 保护旧知识的力量,必然也是阻止新知识进入的力量 | 指望「多调参数」绕开它 → 绕不开,这是结构性的 |
| 回放的数据问题 | 医疗、金融、隐私场景下,保存用户数据并反复用于训练可能直接违法 | 不能留原始数据 → 生成式回放(代价是训练成本和不准确) |
| 参数隔离会膨胀 | 一百个任务就是一百套参数;推理时还得先知道来的是哪个任务 | 任务边界模糊、要动态切换 → 隔离方法直接不适用 |
| 评测本身就很难 | 「忘了多少」怎么量化、「学多好算够」没有统一口径 | 想跨论文比分数 → 先看清它用的是哪套任务序列和指标 |
| 大模型上还没解决好 | 上面这些方法大多在小网络上验证:EWC 要额外存 F 和旧参数 θ*(各一份,共多出约 2 倍参数量),几百亿参数就多出几百亿×2 个数;回放成本高、隔离子空间难解释 | 直接搬到几百亿参数模型 → 规模一上来,方法都要重新设计 |
在小规模基准上,回放类方法通常表现最好——但它依赖「能存旧数据」这个未必成立的前提。
在大模型时代,实际工程里最常见的做法其实是三件事的组合:
冻结大部分参数(LoRA)+ 混入少量旧数据(replay)+ 定期用完整数据重训一轮。
它们都不是「解决」了遗忘,只是在管理它。
互动 · 惩罚调大:新任务学不动了,旧任务却没守住(真的扫描 λ)
这一节把前面七节的所有现象归到一个源头上: 旧知识不是存在某个格子里,而是摊在几乎每一个参数上。 所以「学新东西」其实就是把同一块地方重新涂改一遍。
回到第 2 节那张「真实的顺序训练」。学习率用默认的 0.35,直接点「▶ 开始训练」—— 右图里任务 A 的绿线会从约 98% 掉到 50% 上下,也就是随机猜: 它原本已经学会了,现在又完全不会了。
你没有删任何代码、没有改任何结构, 只是让同一批参数去学任务 B——它们就被调包了。 再把「回放比例」从 0% 拖到 20%,重新训一次:留意任务 A 的绿线被拉回到多少。 那一下你看到的是这笔牺牲的账单——你为旧任务保住的每一分,都是从新任务那里拿走的。
暗线不占任何一章。这里只挑和这一章关系最紧的三条。
| 暗线 | 这一章的回答 |
|---|---|
| B 什么被牺牲了 | 换来的是一件很实在的事:不重跑全量数据也能学新任务——
省的是算力、存储,有时候还关系到隐私和合规。 牺牲的是旧任务的性能,而且是不可控的:你无法预先知道新任务会碰掉旧任务的哪一块。 这就是「稳定性-可塑性困境」 |
| C 参数账本 | 这一章最有力的一点: · 页面上真跑的那个网络是 2 → 8 → 1 的 MLP,
参数 = 2×8 + 8 + 8×1 + 1 = 33 个;· 就这 33 个数,旧任务准确率从约 98% 掉到 ~50%。 于是问题与 换成大模型,账本变成三笔:① EWC 要额外存 F 和旧参数 θ*,各一份, 共多出约 2 倍参数量——几百亿参数就多出几百亿×2 个数,显存吃不消;② 回放要留住旧数据(比例 × 全量数据量); ③ 对齐微调后基座能力掉几个点(对齐税) |
| F 违背了哪个直觉 | 最刺人的一个:「学会了就不会忘」是错的。
网络会,而且忘得极彻底——
约 98% 直接掉到 50% 上下。 第二个:「学得越多总能力越强」也是错的。 对共享参数的网络,多学一个任务可能让旧任务能力下降,总能力反而退步。 第三个细节:忘得彻底并不需要大模型——33 个参数就够。 这让人难以接受:我们以为「遗忘」是容量不够,它其实是更新方式的问题 |
它接住了上一章的什么:《自适应计算》让「算多少」跟着输入变;这一章接着问:记住什么、忘记什么也能变吗?
它给下一章留了什么:旧知识存在哪、怎么被擦掉,光看曲线说不清——《机械可解释性》要把模型打开看。
三大类解法(正则化 / 回放 / 参数隔离)都绕不开稳定性-可塑性困境——
保护旧知识的力量,必然也是阻止新知识进入的力量;所以到今天,
上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。