Part VI · 第 24 章 Model-based 方法 · 24.1

学习动力学模型

动力学模型回答“在状态 s 下施加动作 a,下一刻会怎样”。写不出准确方程的时候(摩擦、负载、软体、接触),可以从机器人自己记录的数据里把它学出来,再拿它做预测、规划和控制。本节用一个电机驱动的单关节摆,在浏览器里现场训练这样的模型:为什么要预测变化量而不是下一个状态,为什么要归一化,为什么一步误差很小的模型滚动几十步就会离谱,多步损失怎样缓解这个问题,在物理模型上学残差为什么省数据、外推也更稳,以及怎样只看像素就学出一个隐空间里的动力学。

约 55 分钟 前置:13.2 状态空间与稳定性 · 16.2 损失、泛化与正则化 · 17.2 RNN 与状态空间模型 · 21.3 不确定性估计 6 个交互

    1为什么机器人需要它

    Part IV 的控制器几乎都要一个模型:LQR(13.3 节)要 \(A,B\),MPC(13.4 节)要在每个控制周期里把模型往前滚几十步。13.2 节从牛顿定律写出了摆的状态方程;8.3 节把多关节机械臂写成 \(M(\mathbf q)\ddot{\mathbf q}+\mathbf b=\boldsymbol\tau\)。这些方程都假设我们知道所有参数,而且所有力都在方程里。

    真实机器人不是这样。减速器里的摩擦随温度变,夹爪上多了一个没称过的工件,腿踩在泥地上,手里揉着一块面团,空气在桨叶下面打旋。这些东西要么很难写成方程,要么方程里的参数测不准。另一条路是从数据里学:让机器人动一动,记录下大量的 \((s_t,a_t,s_{t+1})\),训练一个函数 \(s_{t+1}\approx f_\theta(s_t,a_t)\)。这就是学习动力学模型,也是所有 model-based 强化学习(本章的 24.2、24.3、24.4 节)的第一步。

    它看上去只是一个回归问题(16.1 节),可动力学模型的用法和普通回归不同:它的输出会被再喂回给它自己,一步接一步地滚动。一步上的一点点误差会被下一步当成输入,误差会累积,模型还会被带到训练数据没覆盖的状态。本节的大部分内容都是在处理这个“自己喂自己”带来的问题。

    2直觉:模型是相平面上的一张“箭头图”

    本节的例子是一个单关节机械臂:电机通过减速器驱动一根带负载的杆,相当于 13.2 节里的摆加上一个力矩输入。状态 \(s=(\theta,\omega)\):\(\theta\) 是从竖直向下量起的角度(rad),\(\omega\) 是角速度(rad/s);动作 \(a=\tau\) 是电机力矩,限制在 ±2 N·m。“真实世界”(我们假装不知道它)是

    $$ I\,\dot\omega=\tau-mgl\sin\theta-b\,\omega-\tau_c\tanh(\omega/0.1),\qquad I=0.25\ \mathrm{kg\,m^2},\ mgl=4.905\ \mathrm{N\,m},\ b=0.05,\ \tau_c=0.15\ \mathrm{N\,m} $$

    最后两项是黏性摩擦和(平滑过的)库仑摩擦。电机最多 2 N·m,小于把杆水平举住所需的 4.9 N·m,所以要把杆甩过头顶,只能来回“泵”能量。控制器每 \(\Delta t=0.05\) s(20 Hz)读一次状态、发一次力矩,力矩在一个周期内保持不变(13.2 节的零阶保持)。所以我们要学的是一个离散时间的映射:

    $$ s_{t+1}=\hl{f}{f_\theta(s_t,a_t)},\qquad \text{e.g.}\quad f_\theta(s,a)=s+\mathrm{MLP}_\theta(s,a) $$

    训练数据是 40 段、每段 2.5 s 的随机运动:从 \(|\theta|<1.5\)、\(|\omega|<2\) 内的随机状态出发,每 0.2 s 换一个 [−2, 2] 内均匀随机的力矩,一共 2000 个转移。下图把模型画成相平面上的箭头:每个格点上,青色箭头是真实的一步变化 \((\Delta\theta,\Delta\omega)\),琥珀色箭头是模型预测的。底色表示模型的一步误差。先按“训练”,再把探针拖到数据覆盖的区域内外比较。鼠标放在公式里的 \(f_\theta\) 上,琥珀色箭头会加粗。

    FIG 1学到的一步模型:数据里准,数据外乱猜
    横轴 θ(rad),纵轴 ω(rad/s)。小点是 2000 个训练状态。底色是模型在当前力矩 τ 下的相对一步误差(误差除以数据里一步变化的典型大小,两个分量取较大者),越红误差越大,100% 及以上为最深。青色箭头是真实的一步变化,琥珀色箭头是预测(两者都放大 2 倍画出)。拖紫色圆圈移动探针。MLP 为 [3, 32, 32, 2] tanh 网络,输入和目标都按数据的均值、标准差归一化,预测变化量 Δs,Adam,学习率 0.003,小批量 32,共 3000 步;线性模型 \(\Delta s=W[\theta,\omega,\tau,1]^\top\) 用最小二乘一次解出。只有画面在屏幕上时才训练。
    试一试
    • 训练 MLP 满 3000 步(测试集上相对误差约为 θ 1.7%、ω 3.0%),然后把探针拖到离训练数据较远的地方(读数里的“离数据”≥ 1):找到一处相对误差 ≥ 50% 的状态,例如 τ = 0 时的 (2.8, 0),误差约 111%,而 (0.3, 1) 处不到 1%。
    • MLP 训练完后,切到“线性(最小二乘)”,把探针放在数据内部但角度较大的地方(|θ| ≥ 1.5,离数据 < 0.3):线性模型的误差超过 50%,而 MLP 在同一处低于 25%(τ = 0 时 (1.8, 0) 处为 86% 对 13%)。线性模型相当于 13.2 节线性化的数据版(一个全局的仿射拟合),sin θ 弯得厉害的地方它跟不上。
    核心洞见

    一个学出来的动力学模型只是“在训练数据附近”的一张箭头图。数据内它可以比手写的线性模型准得多;数据外它不知道自己不知道(FIG 1 里离数据较远的地方,红色几乎连成一片)。后面所有的问题,例如滚动时误差累积、规划器钻模型的空子,根源都在这里:使用模型的时候,状态未必还在训练数据附近。

    3动手:预测什么、用什么单位

    FIG 1 的网络预测的是变化量 \(\Delta s=s_{t+1}-s_t\),而且输入、输出都做了归一化。这两个选择看似细节,却往往决定了模型能不能用。原因很简单:控制周期很短,下一刻的状态和这一刻几乎一样。直接预测 \(s_{t+1}\) 时,网络大部分容量都花在“把输入原样抄过去”上,而我们真正关心的那一小点变化,在损失里只占很小的比例。预测 \(\hl{delta}{\Delta s}\) 则把“抄过去”写死在结构里,网络只学变化本身:

    $$ \hat s_{t+1}=s_t+\sigma_\Delta\odot\hl{delta}{\mathrm{MLP}_\theta\!\Big(\frac{(s_t,a_t)-\mu_x}{\sigma_x}\Big)}+\mu_\Delta,\qquad L(\theta)=\frac1n\sum_i\Big\|\frac{\Delta s_i-\mu_\Delta}{\sigma_\Delta}-\mathrm{MLP}_\theta(\cdot)\Big\|^2 $$

    \(\mu_x,\sigma_x\) 是输入在数据上的均值和标准差,\(\mu_\Delta,\sigma_\Delta\) 是变化量的均值和标准差,\(\odot\) 表示逐分量相乘。归一化有两个作用:输入的各个分量尺度相近,优化更顺;输出的各个分量在损失里权重相当。不归一化时,\(\Delta\omega\) 的典型大小(0.58 rad/s)是 \(\Delta\theta\)(0.13 rad)的 4 倍多,平方误差里它占了约 20 倍的权重,角度那一维几乎没人管。下图同时训练四个只在这两点上不同的网络(结构、初值、数据、小批量顺序都相同),比较它们在测试数据上的相对一步误差。

    FIG 2四个网络比赛:预测 s′ 还是 Δs,归一化还是原始单位
    左:测试数据上 θ 分量的相对一步误差(RMS 误差除以 Δθ 的标准差,对数坐标)随训练步数的变化,每 250 步评估一次。红 = 预测 s′、原始单位;紫 = 预测 s′、归一化;蓝 = 预测 Δs、原始单位;绿 = 预测 Δs、归一化。右:一段 2 s 的测试运动,用记录下来的力矩序列开环滚动四个模型得到的 θ(t),青色虚线是真实值。四个网络都是 [3, 32, 32, 2] tanh,Adam,学习率 0.003,小批量 32,各训练 3000 步;每种控制频率的数据都是 40 段 2.5 s 的随机运动。
    • 20 Hz 下按“训练”跑满 3000 步:绿线(Δs、归一化)的 θ 相对误差不到红线(s′、原始单位)的四分之一(约 1.7% 对 7.6%)。
    • 切到 50 Hz 再训练 3000 步:红线(s′、原始单位)和蓝线(Δs、原始单位)的 θ 误差都超过绿线的 3 倍(约 11.4% 和 12.1%,绿线约 1.8%)。控制越快,Δθ 越小,不归一化时它在损失里越不显眼。

    几点观察。(1) 归一化不是让模型“整体更好”,而是决定损失在乎哪一维:20 Hz 下,Δs 原始单位(蓝)的 ω 误差(2.4%)其实比归一化(绿,3.0%)还低一点,代价是 θ 误差几乎翻倍(3.1% 对 1.7%)。(2) 预测 s′ 时就算归一化(紫)也不行:归一化把 s′ 的整个范围(θ 的标准差 0.66 rad)缩成 1,可我们关心的变化只有它的五分之一。(3) 右图单条轨迹的滚动结果会随运气起伏,比较模型要看很多条轨迹,下一节专门讲这件事。

    4另外几个视角:滚动、多步损失、物理残差、隐空间

    误差在滚动中累积,模型被带出数据

    规划器(13.4 节的 MPC、6.11 节的 CEM/MPPI)用模型的方式是开环滚动:给定起点和一串动作,\(\hat s_{t+1}=f_\theta(\hat s_t,a_t)\),每一步都把自己上一步的预测当输入。一步误差 \(\varepsilon\) 很小,并不说明 H 步后误差也小:误差会被动力学放大,而一旦预测的状态离开数据,每一步的 \(\varepsilon\) 本身也变大。

    怎么知道什么时候不能再信模型?21.3 节的办法:训练几个只有初值和小批量顺序不同的模型(集成),看它们的分歧 \(\hl{spread}{\sigma_{\mathrm{ens}}}\)。下图用 5 个一步模型从同一个起点、按同一串力矩滚动,与真实轨迹比较。

    FIG 3开环滚动:留在数据里一切都好,泵出数据就崩
    左:相平面(θ 折回到 [−π, π]),小点是训练状态。青色虚线是真实轨迹,紫色细线是 5 个成员各自的滚动,琥珀色是它们的平均;拖琥珀圈改变起点。右:随时间(步数,每步 0.05 s)变化的 θ 误差(集成平均与真值之差,折回到 [−π, π] 后取绝对值,琥珀色)和集成的标准差(紫色),对数坐标;红色竖虚线标出真实轨迹第一次离开训练数据(离最近训练状态的归一化距离超过 1)的时刻。力矩序列三选一:像训练数据那样每 0.2 s 换一个随机力矩;零力矩;共振“泵能量”τ = 2·sign(ω)。力矩序列先在真实系统上产生,再原样喂给模型。成员都是 FIG 1 那样的 Δs 归一化 MLP,种子不同,各训练 3000 步。
    • 训练集成(5 × 3000 步),力矩选“随机(像数据)”,地平线 ≥ 60 步:整个滚动中真实轨迹都没离开数据,最大 θ 误差 < 0.15 rad(默认起点 (0.3, 0) 处 80 步内最大约 0.03–0.04 rad)。
    • 换成“泵能量”,地平线 80 步:真实的摆在约第 47 步离开数据、随后甩过头顶,模型误差冲到 1 rad 以上(第 60 步约 2.4 rad),而那一刻集成标准差不到误差的四分之一(约 0.27 rad)。分歧确实在涨,但远远低估了真实误差。

    “泵能量”的那条轨迹说明了 model-based 方法最大的麻烦:规划器正是会去找这种轨迹的。如果目标是把杆甩上去,优化器会在模型里寻找能量涨得最快的动作,而模型在高能量区没有数据,它的回答是乱猜,甚至可能比真实系统“更容易”甩上去。这叫模型被利用(model exploitation)。常见的对策都在本章后面:让轨迹样本在集成的各个成员中传播、对它们的代价取平均,使计划必须在每个成员的预测下都行得通(PETS,24.2 节),只做很短的模型滚动(MBPO,同一节),以及用新控制器采到的数据不断重训模型、每步重新规划(24.2 节的数据循环,24.4 节的 MPC)。

    多步损失:按使用方式训练

    一步损失只问“从真实状态出发,下一步预测得准不准”,可使用时模型的输入是它自己的预测。一个自然的修正是把训练也做成滚动:从记录的状态 \(s_t\) 出发,用记录的动作滚 k 步,每一步都和记录的状态比较,

    $$ L_k(\theta)=\hl{kstep}{\frac1k\sum_{j=1}^{k}\big\|\hat s_{t+j}-s_{t+j}\big\|^2_{\sigma_\Delta}},\qquad \hat s_t=s_t,\quad \hat s_{t+j}=f_\theta(\hat s_{t+j-1},a_{t+j-1}) $$

    其中 \(\|\cdot\|_{\sigma_\Delta}\) 表示先逐分量除以 \(\sigma_\Delta\) 再取范数。梯度要穿过整串滚动,这和 17.2 节的随时间反向传播(BPTT)完全一样:模型就是一个以 \(a_t\) 为输入、以状态为隐藏状态的 RNN。k = 1 时它就是一步损失。代价是每个样本要做 k 次前向和反向。下图在带传感器噪声的数据上比较两者:编码器读数有 0.02 rad 的噪声,角速度由差分估计,噪声 0.2 rad/s,这在真实机器人上很常见。

    FIG 4一步损失对多步损失:比的是几秒后的误差
    上:30 段无噪声的测试运动上,开环滚动 H 步后的 RMS θ 误差(折回到 [−π, π],对数坐标),蓝 = 一步损失训练的模型,琥珀 = k 步损失训练的模型。下:其中一段测试运动的 θ(t),青色虚线为真值。两个模型都是 [3, 16, 16, 2] tanh 网络,预测归一化的 Δs,同样的初值,Adam,学习率 0.003,每步 32 个样本(一步模型每个样本是一个转移,k 步模型每个样本是一段 k 步的子轨迹),各训练 3000 步。训练数据:40 段 2.5 s 的随机运动。
    • 数据选“带噪声”,k = 4 或 8,两个模型都训练满 3000 步:60 步(3 s)后,k 步模型的误差不到一步模型的 0.7 倍(k = 4:0.099 对 0.188 rad;k = 8:0.121 rad)。
    • 换成“无噪声”数据再训练满 3000 步:多步损失不再占优,k 步模型 60 步后的误差不低于一步模型的 0.9 倍(k = 8 时 0.068 对 0.067 rad,k = 4 时 0.119 rad,反而更差)。

    为什么噪声让多步损失占优?一步损失把带噪声的 \(s_t\) 当作输入、带噪声的 \(s_{t+1}\) 当作目标;输入里的噪声会让回归系数系统性地偏小(统计里的“变量含误差”偏差),网络学到的动力学偏“迟钝”,这个偏差每一步都同向,滚动时就累积起来。k 步损失只在起点用一次带噪声的输入,后面的输入都是模型自己的平滑预测,偏差小得多。数据干净时,一步损失已经找到了好模型,多步损失只是多了一份更难的优化。所以多步损失不是免费的午餐:它是在“模型必然有误差”时,把误差往对滚动更无害的方向推。

    在物理模型上学残差

    我们其实不是对这个机械臂一无所知:CAD 图纸给出了连杆的质量和长度,只是没算夹爪上的负载,也没有摩擦。与其让网络从零学起,不如让它只学物理模型漏掉的那部分,即残差:

    $$ \hat s_{t+1}=f_{\mathrm{phys}}(s_t,a_t)+\hl{resid}{r_\theta(s_t,a_t)},\qquad L(\theta)=\frac1n\sum_i\big\|s_{i+1}-f_{\mathrm{phys}}(s_i,a_i)-r_\theta(s_i,a_i)\big\|^2 $$

    这里的名义模型 \(f_{\mathrm{phys}}\) 把惯量和重力矩都低估了 20%(\(I=0.2\)、\(mgl=3.924\)),没有摩擦,用 5 ms 的半隐式欧拉法积分一个控制周期。下图比较“黑箱”(从零学 Δs)和“残差”两种模型,看训练数据从 20 个转移加到 1000 个时,1 s(20 步)开环滚动的误差怎样变化;测试分为与训练数据同一范围的运动,以及从更大摆角、更高速度出发(\(|\theta_0|<2.8\)、\(|\omega_0|<6\))的运动。

    FIG 5残差模型:更省数据,出了数据范围也有物理兜底
    左:一段 1 s 测试运动的 θ(t),青色虚线为真值,紫色为名义物理模型,红色为黑箱模型,绿色为残差模型(后两者是当前 N 下训练的);“测试”切换同范围与大范围的运动,“换一段”换一条测试运动。右:1 s 滚动的 RMS θ 误差(30 段测试运动,对数坐标)对训练转移数 N(对数坐标),实心点为同范围、空心圈为大范围,红 = 黑箱,绿 = 残差;紫色实线和虚线是名义模型在同范围和大范围上的误差(不随 N 变)。两个网络都是 [3, 32, 32, 2] tanh,输入和输出按固定尺度缩放,Adam,学习率 0.003,小批量 32,训练 2000 步。训练数据是 20 步一段的随机运动,取前 N 个转移。
    • 选 N = 20 或 50,按“训练两个模型”:同范围测试上残差模型的误差不到黑箱的 0.6 倍(N = 20:0.115 对 0.199 rad)。这么少的数据,黑箱只比名义模型(0.260 rad)好一点点。
    • 选 N ≥ 200 再训练:同范围上两者都很准(N = 200:黑箱 0.027,残差 0.008 rad),但在大范围测试上黑箱的误差超过残差的 5 倍(0.902 对 0.099 rad),甚至比名义模型(0.664 rad)还差。

    残差模型在大范围上也不完美(网络在那里同样是外推),但它出错时退回的是“略有偏差的物理”,而黑箱退回的是“随便什么”。这就是把已知结构放进模型的价值,也解释了为什么实践中常常先做参数辨识(8.3 节:动力学对惯性参数是线性的,可以用最小二乘估计),再用网络学剩下的摩擦(8.4 节)、柔性和气动这些难以建模的部分。

    隐空间动力学:只看像素

    到目前为止状态 \((\theta,\omega)\) 都是直接测到的。如果机器人只有一个摄像头呢?图像有几百上千个像素,而且一帧图像里看不到速度。做法是学一个编码器把最近两帧压缩成一个小的隐状态 \(\hl{latent}{z}\),在隐空间里学动力学,再用解码器把预测的 \(z\) 变回图像来和真实画面比较(编码器、解码器见 18.2 节):

    $$ \hl{latent}{z_t}=e_\phi(o_{t-1},o_t),\quad \hat z_{t+j+1}=\hat z_{t+j}+g_\theta(\hat z_{t+j},a_{t+j}),\quad L=\frac{1}{k+1}\sum_{j=0}^{k}\big\|d_\psi(\hat z_{t+j})-o_{t+j}\big\|^2\ \ (\hat z_t=z_t) $$

    下图的“相机”是 10×10 像素的灰度图,画的是摆杆。编码器 [200, 32, 3],隐动力学 [4, 32, 3],解码器 [3, 32, 100],都是 tanh 网络(解码器输出层为 sigmoid),三者一起用上面的损失训练。注意没有任何地方告诉网络角度或角速度是什么。

    FIG 6从 10×10 像素学隐空间动力学,并在隐空间里“做梦”
    上:一段测试运动,第一行是相机真实拍到的第 2、4、…、20 帧(从第 1 帧之后算起),第二行是模型只看最初两帧、再按记录的力矩在隐空间里滚动后解码出来的画面;琥珀色越浓表示像素值越大。下:10 段测试运动上解码图像的均方误差随滚动步数 H 的变化(对数坐标),红 = k = 1 训练的模型,绿 = k = 8 训练的模型(训练过的才显示),青色虚线是“一直照抄最后一帧”的基线。训练数据:60 段 2 s 的随机运动的图像,Adam,学习率 0.002,每步 8 段子轨迹,共 6000 步。读数里的 R² 是用 z 的线性函数(最小二乘)拟合真实 θ 和 ω 的决定系数。
    • 用 k = 8 训练满 6000 步:滚动 10 步(0.5 s)后的图像误差不到“照抄最后一帧”的四分之一(约 0.004–0.005 对 0.058),而且 ω 的线性 R² 超过 0.6(约 0.76):网络自己在 z 里编进了速度。
    • 切到 k = 1 训练满 6000 步:它的一步预测同样很好,但滚动 5 步后的误差就超过了照抄基线(约 0.13 对 0.049),ω 的 R² 低于 0.3(约 0.11)。只训练一步的隐模型不需要真正弄懂速度。

    这是一个很小的“世界模型”。它也说明了两点:隐状态只有在多步预测的压力下才会变成好用的状态;即使 k = 8,滚动到 20 步时误差也回升到基线附近(约 0.04),超过训练时的预测长度后模型照样会漂。真正的世界模型(PlaNet 和 Dreamer 的 RSSM、TD-MPC 的无解码器隐模型)在此基础上加了随机隐变量、循环网络和奖励预测,见 24.3 节。

    5再看数学

    提示:公式里带底色的符号可以悬停:\(f_\theta\) 加粗 FIG 1 的琥珀色箭头,\(\Delta s\) 加粗 FIG 2 的蓝、绿两条线,\(\sigma_{\mathrm{ens}}\) 加粗 FIG 3 的紫色标准差曲线,\(L_k\) 那一项加粗 FIG 4 的琥珀色曲线,\(r_\theta\) 加粗 FIG 5 的绿色曲线,\(z\) 给 FIG 6 的预测画面加上琥珀色边框。

    学模型就是最大似然

    把转移写成概率模型 \(p_\theta(s'\mid s,a)\),这正是 20.1 节 MDP 里的 \(P(s'\mid s,a)\)。假设 \(s'=f_\theta(s,a)+\varepsilon\),\(\varepsilon\sim\mathcal N(0,\Sigma)\),则数据的负对数似然是

    $$ -\log p_\theta(\mathcal D)=\frac12\sum_i\big(s_i'-f_\theta(s_i,a_i)\big)^{\!\top}\Sigma^{-1}\big(s_i'-f_\theta(s_i,a_i)\big)+\frac n2\log\det\Sigma+\text{const} $$

    \(\Sigma\) 固定为对角阵 \(\operatorname{diag}(\sigma_\Delta^2)\) 时,这正好是归一化的均方误差(16.2 节“损失 = 负对数似然”)。所以“对输出做归一化”其实是在声明“每一维的误差按它典型变化的大小来衡量”。如果让网络同时输出 \(\Sigma_\theta(s,a)\)(异方差,21.3 节 FIG 2),模型就能说“在这里我的预测本身就更不确定”,PETS 的概率集成就是这样做的(24.2 节)。

    为什么预测 Δs:与积分器和 ResNet 的关系

    连续系统 \(\dot s=F(s,a)\) 在一个周期上的精确离散化是 \(s_{t+1}=s_t+\int_0^{\Delta t}F\,dt=s_t+\Delta t\,F(s_t,a_t)+O(\Delta t^2)\)(13.2 节的离散化)。所以 \(\Delta s\) 的大小正比于 \(\Delta t\),而 \(s_{t+1}\) 本身的大小与 \(\Delta t\) 无关。直接预测 \(s_{t+1}\) 时,绝对误差 \(\epsilon\) 相对于变化量的比例是 \(\epsilon/(\Delta t\,|F|)\):控制频率翻倍,同样的网络误差在“变化量”上就翻倍。预测 \(\Delta s\) 就是让网络学 \(\Delta t\,F\),和欧拉积分、和残差网络(ResNet 的 \(x+g(x)\))、和神经 ODE 是同一个结构。

    FIG 1 的线性模型 \(\Delta s=W[s;a;1]\) 则是 13.2 节线性化的数据版:\(A_d=I+W_{:,1:2}\),\(B_d=W_{:,3}\)。用最小二乘从数据拟合 \(A_d,B_d\) 是经典的系统辨识,在工作点附近往往已经够 LQR 用;它的局限正是 FIG 1 里大角度处 sin θ 的弯曲。

    误差如何累积

    记 \(e_t=\|\hat s_t-s_t\|\),真实的下一步是 \(s_{t+1}=f(s_t,a_t)\)。若模型在滚动所到的每个(预测)状态上的一步误差不超过 \(\varepsilon\),且真实动力学对状态是 \(\Lambda\)-Lipschitz 的,那么

    $$ e_{t+1}\le\|f_\theta(\hat s_t,a_t)-f(\hat s_t,a_t)\|+\|f(\hat s_t,a_t)-f(s_t,a_t)\|\le\varepsilon+\Lambda\,e_t\ \ \Rightarrow\ \ e_H\le\varepsilon\,\frac{\Lambda^H-1}{\Lambda-1} $$

    \(\Lambda<1\)(收缩、强阻尼)时误差有界,约为 \(\varepsilon/(1-\Lambda)\);\(\Lambda=1\) 时线性增长 \(H\varepsilon\);\(\Lambda>1\)(不稳定或混沌)时指数增长。几乎无阻尼的摆接近 \(\Lambda\approx1\):小的频率误差变成随时间线性增长的相位误差。更糟的是前提“所到之处 \(\varepsilon\) 都小”:预测状态一旦离开数据,\(\varepsilon\) 本身就变大(FIG 3)。这和行为克隆的复合误差(22.1 节)是同一种机制:训练时的输入来自数据分布,使用时的输入来自模型自己。

    多步损失的梯度

    对 \(L_k\) 求导时,第 \(j\) 步的误差通过所有更早的步影响参数。记状态雅可比 \(J_i=\partial f_\theta/\partial s\big|_{(\hat s_i,a_i)}\)(连乘里时间越晚的雅可比越靠左):

    $$ \frac{\partial\hat s_{t+j}}{\partial\theta}=\sum_{i=0}^{j-1}\Big(\prod_{l=i+1}^{j-1}J_{t+l}\Big)\frac{\partial f_\theta}{\partial\theta}\Big|_{(\hat s_{t+i},a_{t+i})} $$

    雅可比的连乘和 17.2 节 RNN 里的一样:\(\|J\|>1\) 时梯度爆炸,\(<1\) 时消失,所以 k 不能太大,常用梯度裁剪;FIG 4 和 FIG 6 的代码里,\(\partial L/\partial\hat s\) 正是用 nn.js 的 net.backward 返回的输入梯度一步步往回传的。另一种做法是 DaD(Data as Demonstrator,Venkatraman 等 2015):先滚动,再把“从预测状态回到真实轨迹”的修正作为新的一步训练样本加入数据,就像 DAgger 之于行为克隆。

    模型的不确定性

    21.3 节的分解直接适用:\(K\) 个成员,各自输出 \(\mu_k(s,a)\)(以及可选的 \(\Sigma_k\)),

    $$ \operatorname{Var}[s'\mid s,a]\approx\frac1K\sum_k\Sigma_k(s,a)+\hl{spread}{\frac1K\sum_k\big(\mu_k(s,a)-\bar\mu(s,a)\big)^2} $$

    第一项是偶然部分(过程噪声、没观测到的因素),第二项是认知部分(数据不够)。滚动时有两种传播方式:每个成员各滚各的(FIG 3 的做法),或者每一步随机重挑一个成员;PETS 的“轨迹采样”两种都考察过(24.2 节)。无论哪种,FIG 3 已经提醒过:成员共享结构和数据,在远离数据处往往一起错,分歧只是认知不确定性的一个偏乐观的估计。

    残差与隐空间模型

    残差模型可以写在不同层次上:加在下一状态上(FIG 5 的 \(f_{\mathrm{phys}}+r_\theta\)),或加在力矩上,\(M(\mathbf q)\ddot{\mathbf q}+\mathbf b(\mathbf q,\dot{\mathbf q})=\boldsymbol\tau+\boldsymbol\tau_\theta(\mathbf q,\dot{\mathbf q},\boldsymbol\tau)\),后者让网络只补“未建模的力”,再交给积分器。物理参数 \(\varphi\) 也可以和 \(\theta\) 一起拟合,但要小心两者“抢”同一部分误差,常见做法是先辨识 \(\varphi\) 再学 \(\theta\),或者对 \(r_\theta\) 加正则让它尽量小。隐空间模型的损失(FIG 6)里,解码器的重建项防止所有 \(z\) 塌缩到同一点(18.4 节讲过的“塌缩”);不用解码器的做法(TD-MPC)改用奖励和价值预测加上隐状态的一致性来防止塌缩,见 24.3 节。

    6机器人中的它

    学到的模型在机器人里有三种典型用法。当仿真器用:在里面训练策略或做规划,省下真实机器人的时间(24.2、24.3 节)。放进控制器:MPC 每个周期在模型上滚动、优化动作(24.4 节),或者用模型做前馈补偿。补全仿真器:把学到的部件插进物理仿真器,缩小仿真和现实的差距(23.1 节)。数据通常就是机器人日常运行时的日志:关节编码器、电流(力矩)、IMU、相机,频率从几十 Hz 到上千 Hz。

    真实系统里

    预测变化量与归一化:Nagabandi 等(ICRA 2018)用神经网络学动力学再接随机打靶 MPC,网络预测的正是状态差 \(s_{t+1}-s_t\),输入和输出都按均值、标准差归一化,这两点在后来的 model-based RL 代码里几乎成了默认设置(例如 MBRL-Lib,Pineda 等 2021)。 学出来的执行器模型:Hwangbo 等(Science Robotics 2019)为四足机器人 ANYmal 训练了一个“执行器网络”,根据最近的位置误差和速度历史预测串联弹性驱动器实际输出的力矩,把它插进刚体仿真器后,在仿真里训练的策略才能直接用在真机上(23.1 节)。 残差物理:Neural Lander(Shi 等,ICRA 2019)在四旋翼的名义动力学上用网络学贴近地面时的气动残差力(并用谱归一化约束网络的 Lipschitz 常数,以保证控制器稳定);TossingBot(Zeng 等,RSS 2019 / T-RO 2020)先用抛体物理算出投掷速度,再由网络预测一个残差修正。 学出来的仿真器:Sanchez-Gonzalez 等(ICML 2020)用图网络学流体、沙子和黏性材料的粒子动力学,滚动数千步(17.4 节),训练时给输入加噪声以减小滚动误差的累积。 从像素学:Embed to Control(Watter 等,NeurIPS 2015)学局部线性的隐空间动力学;PlaNet(Hafner 等,ICML 2019)用 RSSM 和多步的“隐空间超前预测”(latent overshooting)从图像学模型并直接在隐空间规划,后来的 Dreamer 系列在此基础上训练策略(24.3 节)。

    选择常见做法本节对应
    预测目标Δs(或加速度、力矩残差)FIG 2
    尺度输入、输出按训练数据的均值和标准差归一化,统计量和模型一起保存FIG 2
    角度表示输入用 (sin θ, cos θ),三维姿态用旋转矩阵或四元数;误差用折回后的角度差误区 3
    评估留出轨迹上的多步滚动误差,而不只是一步验证损失FIG 3, FIG 4
    不确定性5–7 个成员的(概率)集成FIG 3,21.3 节,24.2 节
    先验结构先辨识物理参数,再学残差FIG 5

    7常见误区

    误区 1:只看一步验证损失

    一步误差 1–3% 的模型(FIG 1)照样会在 3 s 后错出 2 rad(FIG 3 泵能量),而 FIG 4 里(带噪声数据,k = 4)两个一步误差差不多的模型(0.009 对 0.007 rad),3 s 后的误差差了将近一倍(0.188 对 0.099 rad)。模型是拿来滚动的,就要在留出的轨迹上按实际使用的地平线、实际使用的动作分布评估滚动误差。

    误区 2:预测 s′、忘了归一化,或者部署时用错了统计量

    FIG 2:用原始单位预测 s′ 时,θ 的相对误差是预测 Δs 加归一化时的 4 倍以上(归一化后预测 s′ 也还有约 3 倍),控制频率越高越糟。归一化用的均值、标准差是模型的一部分,必须和权重一起保存;在新数据上重算统计量而不重新训练,等于悄悄换了一个模型。还要防止某一维标准差接近 0(例如一个几乎不动的关节)时除以零。

    误区 3:把角度当成普通数字

    本节为了简单直接把 θ 喂给网络,所以网络不知道 θ 和 θ + 2π 是同一个姿态:FIG 3 里摆甩过头顶后,θ 超出了训练时见过的任何数值,误差立刻暴涨。实际中应输入 (sin θ, cos θ),三维姿态用旋转矩阵或四元数(注意 q 和 −q 是同一个旋转),误差用折回后的角度差或 5.6 节的对数映射计算。

    误区 4:以为用一个策略采的数据能评估任何策略

    模型只在采数据的那个策略到过的地方可信。一旦用它来优化新策略,优化器就会去模型最不可靠、却看起来最有利的地方(FIG 3 的泵能量)。对策:用集成的不确定性给规划加惩罚或约束,用新策略的数据不断重训模型(“采数据—学模型—规划”循环),并且只信任短的滚动。

    误区 5:忽略延迟、噪声和“状态”是否完整

    真实机器人的力矩命令往往要一两个周期后才起作用,差分出来的速度很吵(FIG 4),减速器的间隙、电机温度这些量没被测到。这时 \((s_t,a_t)\) 并不能决定 \(s_{t+1}\),模型只能学到平均效果。办法是把最近几步的状态和动作历史一起作为输入(17.2 节的历史编码器),或者学一个隐状态(FIG 6);而噪声大时,多步损失能减轻输入噪声造成的偏差(FIG 4)。

    8小练习

    1. 机械臂的控制频率从 100 Hz 提高到 1 kHz。你的网络直接预测下一个状态 \(s_{t+1}\),绝对误差大致不变。模型会怎样?
    选项 B。\(\Delta s\approx\Delta t\,F(s,a)\) 随 \(\Delta t\) 缩小,而 \(s_{t+1}\) 本身不缩小,所以“抄输入”的那部分占了网络输出的绝大部分,有用的变化淹没在误差里(FIG 2:从 20 Hz 到 50 Hz,预测 s′ 的模型更差);更多的步数又让误差有更多次机会累积。改为预测归一化的 \(\Delta s\) 才能解决,只归一化输入不够(选项 D 错)。
    2. 你的动力学模型在验证集上的一步误差只有 1%,可 MPC 用它规划出的甩摆动作在真机上完全失败。最可能的原因是?
    选项 D。验证集与训练数据同分布,它的 1% 只说明“在数据附近”的一步误差。甩摆恰恰需要数据外的状态,规划器还会专门寻找模型(错误地)认为最有利的动作(FIG 3 泵能量:离开数据后误差冲到 2 rad 以上)。解决办法是在新轨迹上采数据重训、用集成不确定性约束规划、只信短的滚动。
    3. 已有一个参数略有偏差、没有摩擦的刚体模型。和从零学的黑箱网络相比,在它上面学残差的主要好处是?
    选项 A。FIG 5:N = 20 时残差模型的同范围误差约为黑箱的 0.58 倍;N = 200 时,在大范围测试上黑箱错 0.902 rad,残差只错 0.099 rad。残差模型在数据外仍会出错(选项 B 错),也仍需数据来学修正(选项 C 错);它反而要多算一次物理模型(选项 D 错)。
    4. 关于把一步损失换成 k 步滚动损失,下列说法哪个正确?
    选项 C。FIG 4:噪声数据上 k = 4 把 3 s 误差从 0.188 降到 0.099 rad;干净数据上 k = 8 与一步模型几乎相同(0.068 对 0.067),k = 4 反而更差。梯度要穿过整串滚动,所以计算量约为 k 倍(选项 A 错),而且需要连续的子轨迹(选项 D 错)。中间步的输入是模型自己的预测而不是真实状态,所以它和一步损失不同(选项 B 错)。
    5. 只训练一步预测(k = 1)的隐空间模型,一步预测的图像几乎完美,滚动 5 步后却比“照抄最后一帧”还差。最好的解释是?
    选项 B。同样的网络、同样的维数和学习率,用 k = 8 训练就能滚动 10 步仍远好于基线,ω 的线性 R² 约 0.76,而 k = 1 只有约 0.11(FIG 6),所以不是分辨率、维数或学习率的问题(选项 A、C、D 错)。这和 FIG 4 是同一个道理,只是在隐空间里更严重:隐状态本身也是学出来的,没有多步预测的压力,它就只编码“够下一帧用”的信息。

    9延伸阅读

    • L. Ljung, System Identification: Theory for the User, 2nd ed., Prentice Hall, 1999 — 系统辨识的经典教材:从数据拟合动力学模型的统计基础
    • D. Nguyen-Tuong & J. Peters, Model Learning for Robot Control: A Survey, Cognitive Processing, 2011 — 机器人模型学习的综述(正向、逆向模型,在线学习)
    • A. Nagabandi, G. Kahn, R. S. Fearing & S. Levine, Neural Network Dynamics for Model-Based Deep Reinforcement Learning with Model-Free Fine-Tuning, ICRA 2018 — 预测状态差、归一化、用 MPC 规划
    • A. Venkatraman, M. Hebert & J. A. Bagnell, Improving Multi-Step Prediction of Learned Time Series Models, AAAI 2015 — DaD:针对多步预测误差的数据增广
    • J. Hwangbo et al., Learning Agile and Dynamic Motor Skills for Legged Robots, Science Robotics, 2019 — 学出来的执行器网络
    • G. Shi et al., Neural Lander: Stable Drone Landing Control Using Learned Dynamics, ICRA 2019; A. Zeng et al., TossingBot: Learning to Throw Arbitrary Objects with Residual Physics, RSS 2019 — 在物理模型上学残差
    • A. Sanchez-Gonzalez et al., Learning to Simulate Complex Physics with Graph Networks, ICML 2020 — 长时间滚动的学习型仿真器
    • M. Watter, J. T. Springenberg, J. Boedecker & M. Riedmiller, Embed to Control: A Locally Linear Latent Dynamics Model for Control from Raw Images, NeurIPS 2015; D. Hafner et al., Learning Latent Dynamics for Planning from Pixels, ICML 2019 — 从像素学隐空间动力学
    • R. T. Q. Chen, Y. Rubanova, J. Bettencourt & D. Duvenaud, Neural Ordinary Differential Equations, NeurIPS 2018 — 把网络当作向量场再积分
    • K. Chua, R. Calandra, R. McAllister & S. Levine, Deep Reinforcement Learning in a Handful of Trials using Probabilistic Dynamics Models, NeurIPS 2018 — 概率集成动力学模型(PETS,24.2 节)
    • N. Lambert, B. Amos, O. Yadan & R. Calandra, Objective Mismatch in Model-based Reinforcement Learning, L4DC 2020 — 模型的似然和控制效果并不总是一致