多任务与元学习
机器人要做的从来不止一件事,而新任务总是不断出现:换一个负载、换一个物体、换一块地面。多任务学习让一个网络同时学很多任务,共享的部分从所有任务的数据里学;元学习更进一步,在许多任务上训练“怎样快速学会一个新任务”,让机器人只凭几个样本、几步梯度就适应。本节在浏览器里现场训练:共享特征如何节省数据、又如何被不相关的任务拖累,告诉网络“做哪个任务”的几种方式,任务之间的梯度冲突,MAML、一阶 MAML 与 Reptile 在一族负载上的元训练,它们在二次问题上到底优化了什么,以及把“学习”放进前向传播里的上下文学习。
1为什么机器人需要它
一台厨房机器人要开抽屉、倒水、擦桌子、把杯子放进洗碗机。给每个任务单独训练一个策略,每个任务分到的示教就很少;可这些任务要学的东西大部分是相同的:认出物体、控制手臂、处理接触。多任务学习(multi-task learning)用一个模型同时学所有任务,让共享的那部分从全部数据里学,每个任务自己特有的那一小部分再从自己的数据里学。这就是最早把它系统化的 Caruana(1997)的论点:相关任务的训练信号互相充当“归纳偏置”。
第二个问题更难:新任务不断出现。机械臂抓起一个没见过的工具,负载变了,重力补偿要重新标定;足式机器人走上沙地,动力学变了。我们希望它只凭几个样本、最好几秒钟就适应。21.1 节的预训练加微调是一种答案;元学习(meta-learning,“学会学习”)走得更远:在一族任务上训练,训练目标不是“在这些任务上做得好”,而是“拿到一个新任务的少量数据后,适应之后做得好”。
本节的顺序是:先看共享表示为什么省数据、什么时候反而有害(第 2 节),怎样告诉网络现在做哪个任务(第 3 节),任务之间的梯度冲突(第 4 节);然后动手元训练 MAML 及其近亲(第 5 节),在二次问题上看清它们到底优化了什么(第 6 节),最后看“上下文学习”:把适应过程本身也交给一个网络的前向传播(第 7 节)。
2直觉:共享的部分从所有数据里学
一台机械臂里装着 6 个同型号的电机。16.2 节 FIG 3 里的关节摩擦曲线(库仑摩擦 + 低速 Stribeck 峰 + 粘性摩擦)对它们是同一个形状 \(h(v)\),但每个电机的润滑和温度不同,曲线被放大了 \(a_t\) 倍(0.6 到 1.6 之间),力矩传感器还有一个偏置 \(b_t\)(±0.2 N·m):电机 \(t\) 的摩擦力矩是 \(a_t\,h(v)+b_t\)。每个电机只测了 \(n=4\) 个点(噪声 σ = 0.03 N·m)。
两种学法。分开学:每个电机一个网络 \(\hl{sep}{f_{\theta_t}}(v)\)(两层隐藏层、每层 16 个 tanh 单元,321 个参数),只用自己的 4 个点。共享学(hard parameter sharing):所有电机共用一个“主干”网络 \(\hl{trunk}{h_\phi}(v)\),它输出 \(F\) 个特征,每个电机只有一个线性“头” \(\hat y_t=\mathbf w_t^\top h_\phi(v)+c_t\),只有 \(F+1\) 个参数。主干用所有 24 个点训练;每个头的 \(F+1\) 个数才由自己的 4 个点决定。下图把两种学法放在一起现场训练(Adam,学习率 0.01,全批量,训练 1500 步)。
- 默认设置(6 个电机、每个 4 个点、特征宽度 \(F=1\))下按“训练”,训练满 1500 步:共享模型的误差不到分开训练的 1/5(约 0.0013 对 0.024 N·m²)。
- 保持 \(F=1\),勾选“加一个不相关的任务”,训练满 1500 步:6 个电机的共享误差变得比分开训练还大(约 0.64 对 0.024):负迁移。再把宽度改成 \(F=4\) 重新训练,看它降回多少。
默认运行里,分开训练的紫色曲线只能用 4 个点“猜”曲线的形状:两点之间要么直接连过去,要么弯得莫名其妙,低速的 Stribeck 峰基本丢了。共享的琥珀色曲线几乎和真值重合:主干从 24 个点里学到了“这一型电机的摩擦长什么样”,每个头只需要定一个比例和一个偏置。数据越少,共享的好处越大:每个电机 3 个点时误差约 0.0073 对 0.19(差 26 倍),12 个点时约 0.0003 对 0.0009(只差 3 倍):数据够多时,每个任务自己也能学会。只有 1 个电机时共享没有任何可借的数据,\(F=1\) 的瓶颈反而只是限制(约 0.029 对 0.012)。
加入不相关的任务后,情况反过来。主干只有一个特征,它既要表示摩擦曲线,又要表示余弦形的重力力矩;梯度下降找到的折中让 6 个电机的误差涨到约 0.64,远大于分开训练的 0.024:这就是负迁移(negative transfer)。分开训练的紫色曲线完全不受影响,它们本来就互不相干。把主干加宽到 \(F=2\) 误差降到约 0.070,\(F=4\) 降到约 0.015,又比分开训练好了,但仍比没有这个任务时(\(F=4\) 约 0.005)差。按“换一组数据”试几个种子:大多数种子上都能看到同样的现象,个别种子上优化恰好找到了能兼顾两者的特征。
共享表示是一个赌注:赌任务之间有共同的结构。赌对了,每个任务只需要学“自己的那一点点”,数据效率成倍提高;赌错了,或者共享部分的容量不够,任务就互相争抢,比分开学还差。窄瓶颈(\(F=1\))在任务相关时是最强的归纳偏置,在任务不相关时也是最大的伤害。
3告诉网络做哪个任务:任务 ID、目标与语言
FIG 1 的“每个任务一个头”需要事先知道任务的个数,新任务就得加一个新头。更常见的做法是把任务描述 \(\mathbf z\) 当作网络的另一个输入:策略 \(\pi_\theta(\mathbf a\mid\mathbf s,\mathbf z)\),所有任务共用全部参数。\(\mathbf z\) 有几种选法:
- one-hot 任务编号 \(\mathbf z=\mathbf e_t\):最简单,但它只是一个名字,不包含任务之间的任何关系;
- 目标(goal):要到达的位置、目标物体的位姿,或者一张“完成后应该长什么样”的目标图像;
- 语言:“把红色的杯子放进抽屉”,用预训练的文本编码器(例如 18.3 节的 CLIP 文本塔)变成一个向量。
后两种是有意义的坐标:相近的任务有相近的 \(\mathbf z\),网络就有机会在任务之间插值,对训练时没见过的任务“零样本”泛化。下图是一个平面上的点机器人(也可以想成末端执行器在一个平面里运动),专家的速度指令是“朝目标走,速度上限 1”。我们只在少数几个训练目标上采示教,训练两个策略(两层隐藏层、每层 32 个 tanh 单元,Adam 学习率 0.003,每步 32 个随机状态,共 2000 步):一个输入目标坐标 \(\hl{goal}{\mathbf g}\),一个输入 one-hot 编号。然后拖动琥珀色的测试目标,看它们能不能到达没训练过的目标。
- 用 2 个训练目标训练满 2000 步。先把测试目标放到离两目标连线 0.3 以上的地方:目标条件策略的偏差大约等于这个距离(它停在了连线上);再把测试目标拖到连线附近(距离 < 0.05):偏差降到 0.05 以下。两种情况都要出现。
- 改成 3 个训练目标(不在一条直线上),训练满 2000 步:25 个测试目标的平均偏差降到 0.05 以下(约 0.018),而 one-hot 策略仍约 0.50。
2 个训练目标时,目标条件策略在两个目标的连线上表现完美(连线中点偏差约 0.002),离开连线就差了:默认测试目标 (0.5, 0.3) 离连线 0.41,策略的偏差是 0.42,它几乎精确地走到测试目标在连线上的投影。数据只告诉了网络“目标沿这条线变化时动作怎样变”,垂直方向上它从没见过变化,于是就当作没有变化。加到 3 个不共线的目标,训练目标张成了整个平面,平均偏差从约 0.51 降到约 0.018;6 个目标约 0.007。one-hot 策略在 1、2、3、6 个目标时的平均偏差分别约为 1.04、0.65、0.50、0.35,它只能更密地“查表”,永远到不了表里没有的目标。
这正是语言条件和目标图像条件策略的逻辑:训练任务要足够多样,把描述空间“撑开”,新任务落在撑开的范围里才可能零样本成功。描述的维度越高(语言嵌入有几百维),需要的任务就越多。
第一层看到的是 \(W[\mathbf s;\mathbf e_t]=W_s\mathbf s+\mathbf w_t\),其中 \(\mathbf w_t\) 是 \(W\) 的第 \(t\) 列:one-hot 输入等价于给每个任务学一个任务嵌入 \(\mathbf w_t\),加在第一层上。新任务没有对应的列,也就没有嵌入。目标或语言条件则让嵌入成为描述的函数 \(\mathbf w(\mathbf z)\),新描述自动得到一个嵌入。更强的条件方式是 FiLM(Perez 等,2018):用 \(\mathbf z\) 生成每一层特征的缩放和平移 \(\boldsymbol\gamma(\mathbf z)\odot\mathbf h+\boldsymbol\beta(\mathbf z)\),RT-1 就用它把语言指令注入图像编码器。
4任务打架时:梯度冲突与损失尺度
多任务训练通常最小化加权和 \(\sum_t w_t\mathcal L_t(\boldsymbol\theta)\),一步梯度下降走的是 \(-\eta\sum_t w_t\mathbf g_t\)。把它代入任务 1 的一阶展开:\(\Delta\mathcal L_1\approx-\eta\,(w_1\|\mathbf g_1\|^2+w_2\,\mathbf g_1^\top\mathbf g_2)\)。如果两个梯度夹角大于 90°(梯度冲突,\(\cos<0\)),而任务 2 的梯度又大得多,任务 1 的损失就会上升:一个任务的进步以另一个任务的退步为代价。
下图把这件事缩小到二维参数空间:两个二次损失 \(\mathcal L_1,\mathcal L_2\),最小值点可以拖动。绿色曲线是 Pareto 集:在这些点上,任何移动都不可能同时降低两个损失。PCGrad(Yu 等,2020)的做法是:如果 \(\hl{g1}{\mathbf g_1}\) 和 \(\hl{g2}{\mathbf g_2}\) 冲突,就把每个梯度在对方方向上的分量去掉(投影到对方的法平面上)再相加。拖动起点、改变任务 2 的损失尺度 \(w\),比较两种更新走到了哪里。
- 拖动起点,找一个两个梯度强烈冲突的位置:读数里 \(\cos(\mathbf g_1,\mathbf g_2)<-0.5\)(默认起点是 0.22)。冲突的点在哪一带?
- 把任务 2 的损失尺度调到 \(w\ge8\):加权和的终点上任务 1 的损失变成 \(w=1\) 时的 3 倍以上(默认位置约 0.95 对 0.23),而 PCGrad 的终点基本不动(约 0.29)。
几点观察。(1) 冲突发生在两个最小值点“之间”的那一带:在那里两个任务想往相反方向走,这一带包括整个 Pareto 集,在 Pareto 集上两个梯度恰好反向(\(\cos=-1\))。默认设置下,两种方法走过的 600 步里几乎每一步都在冲突。(2) 加权和总收敛到同一个点:\(\mathcal L_1+w\mathcal L_2\) 的唯一最小值点。\(w\) 从 1 增到 10,这个点沿绿色曲线滑向任务 2 的最小值,任务 1 的损失从约 0.23 涨到约 0.95,任务 2 从约 0.25 降到约 0.03。在真实的多任务网络里,\(w\) 往往不是你有意设置的,而是单位带来的:一个任务用牛顿,另一个用弧度,一个是回归,一个是交叉熵。(3) PCGrad 在这里对 \(w\) 不敏感(\(w=10\) 时任务 1 约 0.29、任务 2 约 0.21),但它也只是停在 Pareto 集上第一次碰到的地方:把起点拖到左上角或右上角,终点会沿绿色曲线跑到另一头(例如 \(w=1\) 时从 (1.8, 1.2) 出发,任务 1 约 1.13、任务 2 约 0.02)。
结论要说得谨慎:在凸问题上,每种合理的方法都停在 Pareto 集上,区别只是停在哪里;“哪个折中是对的”是你的选择,不是优化器能替你决定的。在深度网络这种非凸问题上,冲突还会把训练带进对某些任务很差的区域,PCGrad、GradNorm(Chen 等,2018)、按不确定性加权(Kendall 等,2018)这类方法报告了改进,但它们的收益随问题而变;先把各任务的损失尺度调到可比(归一化目标、按初始损失除),往往就解决了一大半。
5动手:用 MAML 学会快速适应
现在换一个问题:不是同时做好很多任务,而是拿到一个新任务后很快学会。机械臂的一个关节抓着一个未知的负载,保持关节角 \(q\) 所需的重力力矩是 \(\tau(q)=A\sin(q+\varphi)\):幅值 \(A=mg\ell\)(N·m)取决于负载的质量和力臂,相位 \(\varphi\) 取决于负载质心相对连杆的方向。每个负载是一个任务 \(\mathcal T\),任务分布是 \(A\in[0.5,2]\) N·m、\(\varphi\in[0,2\pi)\) 均匀分布。拿到一个新负载,机器人在 \(K=10\) 个随机姿态上测力矩(这叫支持集 \(\mathcal D^{\text{tr}}\)),然后要预测所有姿态上的力矩。
网络 \(f_{\boldsymbol\theta}(q)\) 有两层隐藏层、每层 32 个 tanh 单元(1153 个参数)。适应的方法固定为:从初始参数 \(\boldsymbol\theta\) 出发,在支持集上做几步学习率 \(\alpha=0.03\) 的普通梯度下降,\(\hl{inner}{\boldsymbol\theta'=\boldsymbol\theta-\alpha\nabla_{\boldsymbol\theta}\mathcal L^{\text{tr}}_{\mathcal T}(\boldsymbol\theta)}\)。问题是:初始参数 \(\boldsymbol\theta\) 应该取什么?
- 联合训练(“在所有任务上预训练,再微调”,21.1 节的做法):让 \(f_{\boldsymbol\theta}\) 拟合所有负载混在一起的数据。
- MAML(Model-Agnostic Meta-Learning,Finn 等,2017):直接优化“适应一步之后”的表现。每次抽 4 个负载,每个负载取 10 个支持点和另外 10 个查询点 \(\mathcal D^{\text{val}}\);内循环在支持点上走一步得到 \(\boldsymbol\theta'\),外循环用查询点上的损失 \(\mathcal L^{\text{val}}(\boldsymbol\theta')\) 对 \(\boldsymbol\theta\) 求梯度,用 Adam(学习率 0.003)更新 \(\boldsymbol\theta\)。
- 一阶 MAML(FOMAML)和 Reptile(Nichol 等,2018):MAML 的两种便宜近似,第 6、8 节解释。
下图同时训练一个元学习模型和一个联合训练的基线,各 2000 次外循环迭代。右上是元测试:在 50 个从未见过的负载上,从各自的初始参数出发适应 0 到 10 步后的平均均方误差。
- 选 MAML,按“元训练”,训练到第 1000 次迭代以后:元测试里适应 1 步后的误差低于 0.25(2000 次时约 0.21),而联合训练的模型适应 1 步后仍高于 0.8。
- 换成 Reptile,训练满 2000 次:它适应 1 步后的元测试误差也低于 0.25(约 0.22),可它从不计算查询集上适应后的梯度,只是把参数往适应后的位置拉。
训练完以后的元测试数字(2000 次迭代,50 个测试负载上的平均均方误差;作为参照,在这 50 个负载上一直预测 0 的误差是 0.85,也就是力矩本身的平均方差):
| 初始参数 | 0 步 | 1 步 | 10 步 |
|---|---|---|---|
| 随机初始化(未训练) | 0.84 | 0.79 | 0.75 |
| 联合训练 | 0.86 | 0.86 | 0.88 |
| MAML | 0.95 | 0.21 | 0.068 |
| 一阶 MAML | 1.27 | 0.26 | 0.083 |
| Reptile | 0.85 | 0.22 | 0.078 |
三件值得注意的事。(1) 联合训练几乎学不到东西。相位在 \([0,2\pi)\) 上均匀分布,所有负载的平均力矩在每个姿态上都是 0,所以联合训练的模型学到的接近常数 0(误差 0.86,和一直预测 0 的 0.85 几乎一样);更糟的是,从这个点出发微调,10 步之后反而略差(0.88):它的隐藏单元学成了对“平均任务”最好的样子,而不是对“快速区分任务”最好的样子,甚至不如一个随机初始化(0.75)。(2) MAML 的初始参数本身是一个很差的模型(0 步 0.95,比联合训练还差),把 \(k\) 拖到 0 可以看到那条细虚线和任何负载都不像。可它只要一步梯度就降到 0.21,十步 0.068:MAML 把参数放在了一个“离所有任务都只差一步”的位置,代价是这个位置本身不对应任何任务。(3) 训练满 2000 次后,一阶近似几乎一样好(1 步 0.26 对 0.21),只是 0 步误差更大,而且学得更慢、更不平稳(右下:第 1000 次时 0.49,MAML 已是 0.22);Reptile 起步也更慢,但最后和 MAML 持平。这和原论文的报告一致:在 MiniImagenet 少样本分类上,一阶近似的成绩几乎和完整 MAML 一样。
在这个任务族上,元学习的优势被放大了:平均任务是 0,联合训练什么有用的都学不到。如果各任务有一个很强的共同成分(例如所有负载的相位都差不多),联合训练再微调会好得多,差距会缩小:这是第 10 节误区 4 要说的。
元学习有两层“学习”。内循环(适应)只用一个任务的少量数据,步数少,在部署时运行;外循环(元训练)跨越许多任务,优化的是内循环的起点,在训练时运行。元训练数据的单位不是一个样本,而是一个任务(一组支持集 + 查询集);任务分布 \(p(\mathcal T)\) 扮演了普通学习里数据分布的角色。
6另一种视角:MAML 和 Reptile 把起点放在哪里
神经网络太复杂,看不清。把每个任务换成一个二维的二次损失 \(\mathcal L_t(\boldsymbol\theta)=\tfrac12(\boldsymbol\theta-\mathbf c_t)^\top A_t(\boldsymbol\theta-\mathbf c_t)\),所有东西都能精确算出来(推导在第 8 节):
- 联合训练最小化平均损失,起点是按曲率 \(A_t\) 加权的平均:\(\big(\sum A_t\big)^{-1}\sum A_t\mathbf c_t\);
- MAML最小化“走一步之后”的平均损失,起点是按 \(B_t=(I-\alpha A_t)A_t(I-\alpha A_t)\) 加权的平均;
- Reptile(内循环走 \(k\) 步)的不动点按 \(I-(I-\alpha A_t)^k\) 加权。
三个任务:红色任务很“陡”(各向同性,曲率 8),绿色任务很“平”(曲率 1),蓝色任务各向异性(曲率 3 和 0.4)。拖动它们的中心,调内循环学习率 \(\alpha\) 和 Reptile 的步数 \(k\)。
- 把 \(\alpha\) 调到使红色任务 \(|1-8\alpha|<0.04\)(\(\alpha\) 约 0.125):红色任务的权重 \(B_1\) 变成 0,MAML 的起点跑到另外两个任务的加权平均上,红色的那一步箭头仍然正好落在红点上。
- 把 Reptile 的内循环步数调到 \(k=1\):青色菱形和紫色方块重合,单步的 Reptile 就是联合训练。再把 \(k\) 调大,看它向 MAML 的方向移动多少。
默认设置(\(\alpha=0.08\))下,联合训练的起点在 (0.65, 0.49),被陡的红色任务拉过去:红色任务曲率最大,在平均损失里分量最重。MAML 的起点在 (−0.03, 0.19),明显远离红色任务:从任何地方出发,在红色任务上走一步都会走掉 \(8\alpha=64\%\) 的距离,红色任务“自己就能学会”,不需要起点靠近它。结果是,适应前 MAML 起点的平均损失更大(2.88 对联合训练的 1.79),适应一步后却更小(0.61 对 0.94):和 FIG 4 里“初始模型差、一步后好”是同一回事。\(\alpha=0.125\) 时红色任务一步就精确到达,MAML 完全不管它,一步后平均损失 0.14,联合训练 0.69。
反过来也成立:曲率很小、一步走不了多远的任务(绿色),MAML 会让起点尽量靠近它。这就是 MAML 的本质:把起点花在难以快速适应的任务上。Reptile 介于两者之间:\(k=1\) 时等于联合训练,\(k\) 越大越像“适应很多步之后”的目标,\(k=5\) 时它的不动点在 (0.31, 0.33)。
7上下文学习:把适应放进前向传播
MAML 的内循环是固定的梯度下降。为什么不让一个网络把整个“适应”也学了?给网络一个函数 \(f_{\boldsymbol\theta}(x^{*},\mathcal D)\),它同时读入查询点 \(x^{*}\) 和整个支持集 \(\mathcal D=\{(x_i,y_i)\}\),直接输出预测;在许多任务上用普通的监督学习训练它。部署时没有任何梯度步:新任务的数据作为上下文喂进去,一次前向传播就“学会”了。这就是上下文学习(in-context learning):GPT-3(Brown 等,2020)在提示里放几个例子就能做新任务,是同一种机制在语言上的表现;机器人里,23.2 节的 RMA 用最近一段状态–动作历史推断地形和负载,也是在上下文里适应。
下图用最简单的一种:条件神经过程(CNP,Garnelo 等,2018)。编码器 \(e_{\boldsymbol\theta}\) 把每个上下文点 \((q_i,\tau_i)\) 变成一个 32 维向量,取平均得到任务表示 \(\hl{ctx}{\mathbf r=\tfrac1K\sum_i e_{\boldsymbol\theta}(q_i,\tau_i)}\)(取平均使它与点的顺序无关),解码器 \(\hl{cnp}{d_{\boldsymbol\theta}(q^{*},\mathbf r)}\) 输出预测。它在和 FIG 4 相同的负载分布上训练(每次 4 个负载,上下文点数在 3 到 10 之间随机,15000 次迭代),然后和 FIG 4 的元学习模型比较。为了看泛化,测试负载的幅值可以拖到 3.5 N·m,超出训练范围 [0.5, 2]。
- 训练 CNP 满 15000 次迭代,保持 \(K=10\),用一个幅值在训练范围内(\(A\le2\))的负载:CNP 的误差低于 0.25(默认负载约 0.02 到 0.05,随浏览器略有不同),而它一步梯度也没走。不同负载差别很大(约 0.01 到 2),按“换一个负载”多看几个。
- 两者都训练完后,把负载幅值拖到 \(A\ge2.8\),MAML 步数 \(k\ge10\):CNP 的误差超过 MAML 的 2 倍。CNP 的绿色曲线被“压”在训练见过的幅值附近,梯度适应却能继续往上拟合。
训练范围之内,CNP 在 50 个测试负载上的平均误差最后约 0.15 到 0.18(训练末段在约 0.12 到 0.23 之间波动),介于 MAML 适应 1 步(0.21)和 10 步(0.068)之间;它的代价是 10 次编码,加上每个查询点一次解码,没有反向传播。右图和 FIG 4 最后训练的那个模型比较;FIG 4 选 MAML 时:幅值 1 N·m 时 CNP 约 0.07 到 0.11、MAML 10 步 0.034;2 N·m 时约 0.29 对 0.12;到 3 N·m,CNP 涨到约 1.7,MAML 10 步 0.40、30 步 0.21;3.5 N·m 时约 3.4 对 0.65(10 步)。(每个幅值 20 个相位;误差本身随 \(A^2\) 增长,所以要看两者的比值。CNP 的数字在不同浏览器里略有不同:15000 次迭代会把浮点运算最后几位的微小差别放大成看得出的权重差别;MAML 的数字是可复现的。)
原因在于两者“学会”的东西不同。CNP 的适应完全由训练过的权重决定,它从没见过 3 N·m 的力矩,编码器和解码器也就不知道该输出这么大的数,再多的上下文也没用。MAML 的内循环是真正的梯度下降:只要数据要求,参数就会一直往拟合数据的方向走,即使任务在训练分布之外(Finn 和 Levine 2018 年专门讨论过这种基于梯度的元学习的泛化性)。这是一个普遍的取舍:上下文学习快、表达力强,但分布外没有保障;基于梯度的适应慢,却“至少还在学”。大模型里的上下文学习与梯度下降之间还有更深的联系,有工作表明 Transformer 在上下文里实现的就是某种梯度下降(von Oswald 等,2023)。
8数学
多任务目标与硬共享。主干参数 \(\boldsymbol\phi\),任务 \(t\) 的头参数 \(\boldsymbol\psi_t\),损失权重 \(w_t\):
主干的梯度是所有任务梯度的和,所以它“看到”全部 \(\sum_t n_t\) 个样本;每个头只看到自己的 \(n_t\) 个。FIG 1 里分开训练要从 4 个点定 321 个参数,共享时 6 个电机一共 \(321+6\times2=333\) 个参数(\(F=1\) 时主干正好也是 321 个,每个头 2 个),由全部 24 个点一起决定,每个头只需要 2 个数:参数个数差不多,被数据约束的程度却完全不同。Baxter(2000)给出了这件事的理论版本:任务越多,学到一个对整个任务族都好的表示所需的每任务样本数越少。
梯度冲突与 PCGrad。对 \(\sum_t w_t\mathcal L_t\) 走一步 \(\Delta\boldsymbol\theta=-\eta\sum_j w_j\mathbf g_j\),任务 \(t\) 损失的一阶变化是
右边是 PCGrad 的投影,只在两个梯度冲突(括号里的条件)时使用。投影后 \(\mathbf g_i^\top\mathbf g_j=0\):这一步至少不会在一阶意义上直接伤害对方。两个任务的点 \(\boldsymbol\theta\) 是 Pareto 驻点,当且仅当存在 \(\lambda\in[0,1]\) 使 \(\lambda\mathbf g_1+(1-\lambda)\mathbf g_2=0\),也就是两个梯度反向(或其中一个为零)。对 FIG 3 的二次损失,Pareto 集是 \(\boldsymbol\theta(\lambda)=\big(\lambda A_1+(1-\lambda)A_2\big)^{-1}\big(\lambda A_1\mathbf c_1+(1-\lambda)A_2\mathbf c_2\big)\),加权和 \(\mathcal L_1+w\mathcal L_2\) 的最小值点就是 \(\lambda=1/(1+w)\) 的那一点。
MAML。内循环一步 \(\boldsymbol\theta'_{\mathcal T}=\boldsymbol\theta-\alpha\nabla\mathcal L^{\text{tr}}_{\mathcal T}(\boldsymbol\theta)\),外循环的目标和梯度(链式法则,2.2 节;\(\nabla^2\) 是 3.5 节的 Hessian,对称):
Hessian 从不需要显式构造,只需要它乘一个向量 \(\mathbf v=\nabla\mathcal L^{\text{val}}(\boldsymbol\theta')\)。PyTorch 里对梯度再求一次梯度(create_graph=True)就得到它;FIG 4 用中心差分 \(H\mathbf v\approx\big[\nabla\mathcal L^{\text{tr}}(\boldsymbol\theta+\varepsilon\mathbf v)-\nabla\mathcal L^{\text{tr}}(\boldsymbol\theta-\varepsilon\mathbf v)\big]/(2\varepsilon)\),\(\varepsilon=10^{-3}/\|\mathbf v\|\),每个任务多花两次梯度计算。一阶 MAML 直接丢掉 \(\alpha\nabla^2\) 这一项,用 \(\nabla\mathcal L^{\text{val}}(\boldsymbol\theta')\) 作为元梯度。内循环走 \(k\) 步时,完整的元梯度要乘 \(k\) 个 \((I-\alpha\nabla^2\mathcal L)\),计算和内存随 \(k\) 增长,这正是一阶方法和隐式梯度方法(iMAML,Rajeswaran 等,2019)要解决的问题。
Reptile。在任务上做 \(k\) 步 SGD 得到 \(\tilde{\boldsymbol\theta}_k\),然后 \(\boldsymbol\theta\leftarrow\boldsymbol\theta+\beta(\tilde{\boldsymbol\theta}_k-\boldsymbol\theta)\)(FIG 4 用 \(k=5\),把 \(\boldsymbol\theta-\tilde{\boldsymbol\theta}_k\) 当作梯度交给 Adam,每步内循环都用同样的 10 个支持点)。\(k=1\) 时 \(\tilde{\boldsymbol\theta}_1-\boldsymbol\theta=-\alpha\mathbf g\),Reptile 就是在平均损失上做 SGD,即联合训练。\(k=2\),两步用两个不同的小批量(梯度 \(\mathbf g_1,\mathbf g_2\)、Hessian \(H_1,H_2\),都在 \(\boldsymbol\theta\) 处取值),做 Taylor 展开:
其中用了两个小批量可交换,\(\mathbb E[H_2\mathbf g_1]=\tfrac12\mathbb E[H_2\mathbf g_1+H_1\mathbf g_2]=\tfrac12\nabla\mathbb E[\mathbf g_1^\top\mathbf g_2]\)。Reptile 沿这个方向的反方向走:除了降低平均损失,还增大同一任务不同小批量梯度的内积,即让在一部分数据上走一步也能改善另一部分数据。Nichol 等(2018)证明 MAML 和一阶 MAML 的期望更新里也有同样两项,只是系数不同。
二次任务(FIG 5)。\(\mathcal L_t=\tfrac12(\boldsymbol\theta-\mathbf c_t)^\top A_t(\boldsymbol\theta-\mathbf c_t)\),梯度 \(A_t(\boldsymbol\theta-\mathbf c_t)\),走一步后 \(\boldsymbol\theta'-\mathbf c_t=(I-\alpha A_t)(\boldsymbol\theta-\mathbf c_t)\),于是
这里 \(\boldsymbol\theta^\star_{\mathrm{M}}\) 是 MAML 的起点,\(\boldsymbol\theta^\star_{\Sigma}\) 是联合训练的起点。对各向同性的 \(A_t=\lambda_tI\),\(B_t=\lambda_t(1-\alpha\lambda_t)^2I\):在 \(\alpha\lambda_t=1\) 时为零(一步正好到达,起点放在哪里都一样),在 \(\alpha\lambda_t\) 很小时约等于 \(\lambda_t\)(MAML 退化为联合训练,\(\alpha=0\) 时完全相同)。Reptile 的不动点满足 \(\sum_t(\tilde{\boldsymbol\theta}_{t,k}-\boldsymbol\theta)=0\),而 \(\tilde{\boldsymbol\theta}_{t,k}-\boldsymbol\theta=-\big(I-(I-\alpha A_t)^k\big)(\boldsymbol\theta-\mathbf c_t)\),所以 Reptile 的不动点 \(\hl{rep}{\boldsymbol\theta^\star_{\mathrm{R}}}\) 是按 \(M_t=I-(I-\alpha A_t)^k\) 加权的平均;\(k=1\) 时 \(M_t=\alpha A_t\),与联合训练相同。
上下文学习。训练一个以整个数据集为输入的预测器(右边是 CNP 的具体形式):
用平方损失时,这个目标的最优解是后验预测均值 \(\mathbb E[y^{*}\mid x^{*},\mathcal D]\),期望取在任务分布 \(p(\mathcal T)\) 下(平方误差的最小值点是条件均值,和 19.6 节去噪器的道理相同):上下文学习器学到的是对这个任务族的贝叶斯推断的一个近似。这也说明了 FIG 6 的分布外失败:\(p(\mathcal T)\) 里没有 3 N·m 的负载,这样的上下文在训练目标里根本不出现,网络在那里输出什么都不受约束。
| 怎样适应新任务 | 部署时的代价 | 训练分布之外 | |
|---|---|---|---|
| 多任务 + 条件输入 | 给一个新的描述 \(\mathbf z\)(零样本) | 一次前向 | 只在训练任务张成的范围内可靠(FIG 2) |
| 预训练 + 微调 | 在新数据上做很多步梯度下降 | 一次训练 | 数据够多就能学会 |
| MAML / Reptile | 从元学习的起点做几步梯度下降 | 几次反向传播 | 变差,但步数越多越接近(FIG 6) |
| 上下文学习 | 把数据当作输入 | 一次前向(上下文越长越贵) | 没有保障(FIG 6) |
9机器人中的它
多任务、语言条件的模仿学习是今天操作策略的主流形式。BC-Z(Jang 等,CoRL 2021)用一条语言指令或一段人类示范视频作为任务条件,并在一部分训练中没出现的任务上零样本成功。RT-1(Brohan 等,2022)在 13 台 Everyday Robots 机器人、17 个月采集的约 13 万条示教上训练,覆盖 700 多条指令;指令用 Universal Sentence Encoder 编码,通过 FiLM 层注入 EfficientNet 图像编码器(第 3 节的 FiLM)。Octo(Octo Model Team,RSS 2024)既可以用语言、也可以用目标图像作为条件。这些系统都押注于 FIG 1 和 FIG 2 的逻辑:任务越多样,共享的视觉与运动表示越好,新指令越可能落在已覆盖的范围里。
目标条件强化学习:UVFA(Schaul 等,2015)把价值函数写成 \(V(\mathbf s,\mathbf g)\),HER(Andrychowicz 等,2017)把一条没到达目标的轨迹“重新标注”成到达了它实际到达的那个点:一条失败轨迹变成了另一个任务的成功示范,目标空间被免费地“撑开”。Lynch 等(CoRL 2019)用同样的事后重标注,从遥操作的“自由玩耍”数据学目标条件策略。
基准:Meta-World(Yu 等,CoRL 2019)在仿真的 Sawyer 机械臂上提供 50 个操作任务,MT10/MT50 用来评测多任务学习,ML1/ML10/ML45 用来评测元学习(在训练任务上元训练,在留出的任务上测试适应)。
元学习用于快速适应:Nagabandi 等(ICLR 2019)元学习一个动力学模型,让一台真实的小型足式机器人在几步之内在线适应地形变化、腿部损伤等扰动;单样本模仿学习(Duan 等,NeurIPS 2017)把一条示范作为上下文;Finn 等(CoRL 2017)用 MAML 让机器人从单条视觉示范学会新的放置任务。PEARL(Rakelly 等,ICML 2019)推断一个任务隐变量,是强化学习里的上下文适应;23.2 节的 RMA 用历史编码器在线估计地形与负载,属于同一类。
对大模型来说,显式的双层优化(MAML 那样对内循环求导)代价太高,用得越来越少。今天常见的组合是:在尽可能多样的多任务数据上预训练一个条件策略(FIG 1、FIG 2),新任务在上下文里给出(语言、目标图像、几条示范或一段历史,FIG 6),不够时再用几十到几百条示教微调(21.1 节,例如 LoRA)。元学习的思想并没有消失:它体现在“按任务组织训练数据”“在留出的任务上评测”以及上下文适应的训练方式里。
10常见误区
只有任务真的共享结构、共享部分又有足够容量时才成立。FIG 1 里一个不相关的任务就让共享模型在 6 个电机上的误差从约 0.0013 涨到约 0.64,比分开训练还差 25 倍以上。每个任务都要和它自己的单任务基线比较;负迁移出现时,可以加宽共享部分、给任务加专属的适配器(21.1 节的 LoRA 也能按任务各用一份),或者把任务分组,只让相关的任务共享(Standley 等,2020)。
损失的尺度由单位和损失类型决定:力用牛顿还是千牛,角度用弧度还是度,回归还是交叉熵。加权和会偏向梯度大的任务(FIG 3:\(w=10\) 时任务 1 的损失涨到 4 倍)。先把目标归一化、让各任务的初始损失可比,再考虑 GradNorm、不确定性加权或 PCGrad;并且记住,选哪个折中是一个设计决定。
元学习学到的是对任务分布 \(p(\mathcal T)\) 的先验。部署时的任务不在这个分布里(更重的负载、新类别的物体、另一台机器人),优势就会缩小甚至消失;上下文学习器尤其如此(FIG 6)。元训练的任务分布要设计得比你预期的部署任务更宽;评测要在留出的任务上做,而不是同一批任务的留出样本上。元训练任务太少时,模型还可能直接“记住”每个任务而不去读支持集(Yin 等,2020)。
FIG 4 的联合训练基线是被任务族“设计”得很弱的:平均任务恰好是 0。在少样本图像分类上,Chen 等(ICLR 2019)和 Tian 等(ECCV 2020)发现,一个训练得好的预训练表示加上简单的微调或线性分类器,常常和元学习方法一样好甚至更好;Raghu 等(ICLR 2020)发现 MAML 的效果主要来自“复用特征”,内循环只更新最后一层(ANIL)几乎一样好。和调好的“预训练 + 微调”比,才说明问题。
MAML 的起点是为那个内循环优化的:特定的学习率 \(\alpha\)、步数、批量大小、优化器。部署时把 \(\alpha\) 调大或换成 Adam,起点就不再“离每个任务一步之遥”,甚至会因为起点附近曲率很大而发散(FIG 5:\(\alpha\lambda>2\) 时这一步会越过最优点更远)。测试时用和元训练相同的内循环;如果需要更多步,就在元训练时也用更多步。
11小练习
12延伸阅读
- R. Caruana, Multitask Learning, Machine Learning, 1997 — 多任务学习的经典起点
- J. Baxter, A Model of Inductive Bias Learning, Journal of Artificial Intelligence Research, 2000 — 共享表示为什么能减少每任务所需样本的理论
- S. Thrun & L. Pratt (eds.), Learning to Learn, Kluwer, 1998 — “学会学习”的早期文集
- S. Ruder, An Overview of Multi-Task Learning in Deep Neural Networks, arXiv, 2017 — 易读的综述:硬共享与软共享
- E. Perez, F. Strub, H. de Vries, V. Dumoulin & A. Courville, FiLM: Visual Reasoning with a General Conditioning Layer, AAAI 2018
- Z. Chen, V. Badrinarayanan, C.-Y. Lee & A. Rabinovich, GradNorm, ICML 2018; A. Kendall, Y. Gal & R. Cipolla, Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics, CVPR 2018 — 平衡任务损失
- O. Sener & V. Koltun, Multi-Task Learning as Multi-Objective Optimization, NeurIPS 2018 — Pareto 视角
- T. Yu, S. Kumar, A. Gupta, S. Levine, K. Hausman & C. Finn, Gradient Surgery for Multi-Task Learning, NeurIPS 2020 — PCGrad
- T. Standley, A. Zamir, D. Chen, L. Guibas, J. Malik & S. Savarese, Which Tasks Should Be Learned Together in Multi-task Learning?, ICML 2020
- C. Finn, P. Abbeel & S. Levine, Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks, ICML 2017 — MAML,包括 FIG 4 所仿照的正弦回归实验
- A. Nichol, J. Achiam & J. Schulman, On First-Order Meta-Learning Algorithms, arXiv, 2018 — Reptile 与第 8 节的 Taylor 分析
- C. Finn & S. Levine, Meta-Learning and Universality: Deep Representations and Gradient Descent can Approximate any Learning Algorithm, ICLR 2018
- A. Rajeswaran, C. Finn, S. Kakade & S. Levine, Meta-Learning with Implicit Gradients, NeurIPS 2019 — iMAML
- A. Raghu, M. Raghu, S. Bengio & O. Vinyals, Rapid Learning or Feature Reuse? Towards Understanding the Effectiveness of MAML, ICLR 2020
- W.-Y. Chen, Y.-C. Liu, Z. Kira, Y.-C. F. Wang & J.-B. Huang, A Closer Look at Few-shot Classification, ICLR 2019; Y. Tian, Y. Wang, D. Krishnan, J. Tenenbaum & P. Isola, Rethinking Few-Shot Image Classification: a Good Embedding Is All You Need?, ECCV 2020 — 强基线
- M. Yin, G. Tucker, M. Zhou, S. Levine & C. Finn, Meta-Learning without Memorization, ICLR 2020
- M. Garnelo et al., Conditional Neural Processes, ICML 2018 — FIG 6 的上下文学习器
- T. Brown et al., Language Models are Few-Shot Learners, NeurIPS 2020; J. von Oswald et al., Transformers Learn In-Context by Gradient Descent, ICML 2023
- T. Hospedales, A. Antoniou, P. Micaelli & A. Storkey, Meta-Learning in Neural Networks: A Survey, IEEE TPAMI — 全面的综述
- T. Schaul, D. Horgan, K. Gregor & D. Silver, Universal Value Function Approximators, ICML 2015; M. Andrychowicz et al., Hindsight Experience Replay, NeurIPS 2017 — 目标条件强化学习
- T. Yu et al., Meta-World: A Benchmark and Evaluation for Multi-Task and Meta Reinforcement Learning, CoRL 2019
- A. Nagabandi et al., Learning to Adapt in Dynamic, Real-World Environments Through Meta-Reinforcement Learning, ICLR 2019
- Y. Duan et al., One-Shot Imitation Learning, NeurIPS 2017; C. Finn, T. Yu, T. Zhang, P. Abbeel & S. Levine, One-Shot Visual Imitation Learning via Meta-Learning, CoRL 2017
- K. Rakelly, A. Zhou, D. Quillen, C. Finn & S. Levine, Efficient Off-Policy Meta-Reinforcement Learning via Probabilistic Context Variables, ICML 2019 — PEARL
- E. Jang et al., BC-Z: Zero-Shot Task Generalization with Robotic Imitation Learning, CoRL 2021; A. Brohan et al., RT-1: Robotics Transformer for Real-World Control at Scale, 2022; Octo Model Team, Octo: An Open-Source Generalist Robot Policy, RSS 2024
- C. Lynch et al., Learning Latent Plans from Play, CoRL 2019