Skip to the content.

第11章 强化学习:让机器人通过试错学习

原课程: Robots That Learn, UC Berkeley CS294-291, Spring 2026 主讲: Jitendra Malik 本章基于 Lecture 7: Reinforcement Learning 核心参考: Sutton & Barto, Reinforcement Learning: An Introduction, 2nd ed. (2018); Haarnoja et al., “Learning to Walk via Deep RL,” RSS 2019; OpenAI et al., “Learning Dexterous In-Hand Manipulation,” IJRR 2020


一、本章概要

核心问题: 机器人面对连续高维动作空间、非线性动力学和部分可观测的物理环境,如何通过与环境交互、试错来学习最优行为策略?传统控制方法(第8章)依赖精确的系统动力学模型 \(\dot{\mathbf{x}} = f(\mathbf{x}, \mathbf{u})\),而强化学习(Reinforcement Learning, RL)提供了一条根本不同的路径: 让机器人与环境反复交互,直接从原始感知输入中端到端地学习策略,无需显式建模 \(f\)。

与前后章节的逻辑关系: 第8章(机器人动力学与控制)建立了基于模型的控制范式(LQR, MPC)——这些方法在模型精确时表现优异,但在非结构化环境中建模误差会累积。本章引入的无模型(model-free)RL范式恰好弥补了这一缺陷。第10章(视频世界模型)构建环境的预测模型,RL策略可以在学到的世界模型中进行”想象性”训练。第14章(RMA运动控制)和第16章(灵巧操作)中的sim-to-real迁移均以本章的PPO/SAC/域随机化为方法论基础。

本章路线图: 从MDP的形式化定义出发,逐层构建Bellman方程→值迭代的收缩性证明→策略梯度定理的完整推导→GAE的方差-偏差权衡→PPO的裁剪代理目标→SAC的最大熵框架与重参数化,最后深入两个机器人学中的里程碑应用——四足行走(SAC+层次化控制)和五指灵巧手操作(PPO+LSTM+非对称Actor-Critic)。

前置知识提示: 本章假设读者已掌握基本的概率论(期望、条件概率、KL散度)、线性代数(矩阵微分)和深度学习(反向传播、MLP架构)。如果你对RL完全陌生,建议先阅读Sutton & Barto(2018)第3-6章和第13章作为入门。

在正式开始之前,值得记住Richard Sutton在”The Bitter Lesson”中的核心洞察:利用计算能力的大规模方法最终会战胜依赖人类知识的精巧方法。这一原则在机器人RL中体现为: 与其手工设计复杂的控制器,不如让学习算法在海量模拟交互中发现控制策略。但机器人RL也有其独特的”苦涩”: 物理交互不可无限并行化,sim-to-real鸿沟意味着在模拟器中完美的策略不一定在真实世界中工作。本章正是围绕这一核心张力展开。


二、数学基础: 从MDP到SAC的完整推导

2.1 马尔可夫决策过程(MDP)的形式化

RL的数学语言是马尔可夫决策过程(Markov Decision Process, MDP),定义为一个六元组:

\[\mathcal{M} = (\mathcal{S}, \mathcal{A}, P, R, \gamma, \rho_0)\]
符号 数学定义 机器人学中的具体实例
\(\mathcal{S} \subseteq \mathbb{R}^{d_s}\) 状态空间 关节角度 \(\mathbf{q} \in \mathbb{R}^{12}\)、角速度 \(\dot{\mathbf{q}}\)、IMU读数(6维)、足底接触力(4维) → \(d_s \approx 34\)
\(\mathcal{A} \subseteq \mathbb{R}^{d_a}\) 动作空间 关节力矩 \(\boldsymbol{\tau}\) (直接力矩控制) 或目标关节角度 \(\mathbf{q}_{\text{des}}\) (PD控制)
\(P: \mathcal{S} \times \mathcal{A} \to \Delta(\mathcal{S})\) 状态转移概率 物理引擎前向动力学 \(P(\mathbf{s}' \mid \mathbf{s}, \mathbf{a})\) (确定性或加噪声)
\(R: \mathcal{S} \times \mathcal{A} \to \mathbb{R}\) 奖励函数 \(w_v v_x - w_e |\boldsymbol{\tau}|^2 + w_a \cdot \mathbb{1}_{\text{alive}}\)
\(\gamma \in [0, 1)\) 折扣因子 典型值 \(0.99\) (有效时间尺度 \(\frac{1}{1-\gamma} = 100\) 步)
\(\rho_0 \in \Delta(\mathcal{S})\) 初始状态分布 机器人从随机姿态复位

马尔可夫性质的形式化:

\[P(\mathbf{s}_{t+1} \mid \mathbf{s}_t, \mathbf{a}_t, \mathbf{s}_{t-1}, \mathbf{a}_{t-1}, \ldots, \mathbf{s}_0) = P(\mathbf{s}_{t+1} \mid \mathbf{s}_t, \mathbf{a}_t)\]

在真实机器人系统中,这一假设通常不成立。原因有三:(1) 单帧关节角度观测不包含速度信息,速度需要通过差分或滤波推断——需要历史;(2) 地面摩擦系数、负载质量、执行器温度等不能被直接观测,但严重影响动力学;(3) 传感器存在延迟与噪声。应对策略: 用LSTM/GRU将观测历史压缩为隐状态 \(\mathbf{h}_t\),构造增广状态 \(\hat{\mathbf{s}}_t = [\mathbf{o}_t; \mathbf{h}_{t-1}]\) 近似恢复马尔可夫性。

轨迹与回报: 策略 \(\pi: \mathcal{S} \to \Delta(\mathcal{A})\) 产生轨迹 \(\tau = (\mathbf{s}_0, \mathbf{a}_0, r_0, \mathbf{s}_1, \ldots)\),其折扣累积回报为:

\[G_t = \sum_{k=0}^{\infty} \gamma^k R(\mathbf{s}_{t+k}, \mathbf{a}_{t+k})\]

RL的核心目标: \(\pi^* = \arg\max_{\pi} J(\pi) = \arg\max_{\pi} \mathbb{E}_{\tau \sim \pi}[\sum_{t=0}^{\infty} \gamma^t R(\mathbf{s}_t, \mathbf{a}_t)]\)

2.2 Bellman方程与最优性的完整证明

状态值函数 \(V^{\pi}: \mathcal{S} \to \mathbb{R}\):

\[V^{\pi}(\mathbf{s}) = \mathbb{E}_{\pi}\left[\sum_{k=0}^{\infty} \gamma^k R(\mathbf{s}_{t+k}, \mathbf{a}_{t+k}) \;\middle\vert \; \mathbf{s}_t = \mathbf{s}\right]\]

动作值函数 \(Q^{\pi}: \mathcal{S} \times \mathcal{A} \to \mathbb{R}\):

\[Q^{\pi}(\mathbf{s}, \mathbf{a}) = \mathbb{E}_{\pi}\left[\sum_{k=0}^{\infty} \gamma^k R(\mathbf{s}_{t+k}, \mathbf{a}_{t+k}) \;\middle\vert \; \mathbf{s}_t = \mathbf{s}, \mathbf{a}_t = \mathbf{a}\right]\]

两者关系: \(V^{\pi}(\mathbf{s}) = \mathbb{E}_{\mathbf{a} \sim \pi(\cdot \mid \mathbf{s})}[Q^{\pi}(\mathbf{s}, \mathbf{a})]\)

2.2.1 Bellman期望方程的推导

将 \(G_t = R(\mathbf{s}_t, \mathbf{a}_t) + \gamma G_{t+1}\) 代入 \(V^{\pi}\) 的定义:

\[\begin{aligned} V^{\pi}(\mathbf{s}) &= \mathbb{E}_{\pi}\left[R(\mathbf{s}_t, \mathbf{a}_t) + \gamma \sum_{k=0}^{\infty} \gamma^k R(\mathbf{s}_{t+1+k}, \mathbf{a}_{t+1+k}) \;\middle\vert \; \mathbf{s}_t = \mathbf{s}\right] \\[4pt] &= \mathbb{E}_{\mathbf{a} \sim \pi(\cdot \mid \mathbf{s})}\left[R(\mathbf{s}, \mathbf{a}) + \gamma \, \mathbb{E}_{\mathbf{s}' \sim P(\cdot \mid \mathbf{s}, \mathbf{a})}[V^{\pi}(\mathbf{s}')]\right] \end{aligned}\]

Q函数的Bellman期望方程:

\[Q^{\pi}(\mathbf{s}, \mathbf{a}) = R(\mathbf{s}, \mathbf{a}) + \gamma \, \mathbb{E}_{\mathbf{s}' \sim P(\cdot \mid \mathbf{s}, \mathbf{a})}\left[\mathbb{E}_{\mathbf{a}' \sim \pi(\cdot \mid \mathbf{s}')}[Q^{\pi}(\mathbf{s}', \mathbf{a}')]\right]\]

优势函数: \(A^{\pi}(\mathbf{s}, \mathbf{a}) = Q^{\pi}(\mathbf{s}, \mathbf{a}) - V^{\pi}(\mathbf{s})\)。直接的性质: \(\mathbb{E}_{\mathbf{a} \sim \pi}[A^{\pi}(\mathbf{s}, \mathbf{a})] = 0\) (动作的期望优势恒为零)。\(A^{\pi}(\mathbf{s}, \mathbf{a}) > 0\) 表示该动作好于策略平均,应增加其概率;\(A^{\pi} < 0\) 反之。优势函数构成了所有Actor-Critic方法方差削减的理论基础。

2.2.2 Bellman最优性方程

定义最优值函数: \(V^*(\mathbf{s}) = \max_{\pi} V^{\pi}(\mathbf{s})\), \(Q^*(\mathbf{s}, \mathbf{a}) = \max_{\pi} Q^{\pi}(\mathbf{s}, \mathbf{a})\)。

\[\boxed{V^*(\mathbf{s}) = \max_{\mathbf{a} \in \mathcal{A}} \left[R(\mathbf{s}, \mathbf{a}) + \gamma \, \mathbb{E}_{\mathbf{s}' \sim P(\cdot \mid \mathbf{s}, \mathbf{a})}[V^*(\mathbf{s}')]\right]}\] \[\boxed{Q^*(\mathbf{s}, \mathbf{a}) = R(\mathbf{s}, \mathbf{a}) + \gamma \, \mathbb{E}_{\mathbf{s}' \sim P}\left[\max_{\mathbf{a}' \in \mathcal{A}} Q^*(\mathbf{s}', \mathbf{a}')\right]}\]

一旦获得 \(Q^*\),最优策略为: \(\pi^*(\mathbf{s}) = \arg\max_{\mathbf{a}} Q^*(\mathbf{s}, \mathbf{a})\)

策略改进定理(Policy Improvement Theorem): 设 \(\pi, \pi'\) 为确定性策略。若对所有 \(\mathbf{s}\) 有 \(Q^{\pi}(\mathbf{s}, \pi'(\mathbf{s})) \geq V^{\pi}(\mathbf{s})\),则 \(\pi'\) 至少与 \(\pi\) 一样好: \(V^{\pi'}(\mathbf{s}) \geq V^{\pi}(\mathbf{s}), \forall \mathbf{s}\)。若至少一个状态上式严格成立,则 \(\pi'\) 严格优于 \(\pi\)。

证明: 反复展开Bellman方程:

\[\begin{aligned} V^{\pi}(\mathbf{s}) &\leq Q^{\pi}(\mathbf{s}, \pi'(\mathbf{s})) \\ &= R(\mathbf{s}, \pi'(\mathbf{s})) + \gamma \mathbb{E}_{\mathbf{s}' \sim P}[V^{\pi}(\mathbf{s}')] \\ &\leq R(\mathbf{s}, \pi'(\mathbf{s})) + \gamma \mathbb{E}_{\mathbf{s}' \sim P}[Q^{\pi}(\mathbf{s}', \pi'(\mathbf{s}'))] \\ &= R(\mathbf{s}, \pi'(\mathbf{s})) + \gamma \mathbb{E}_{\mathbf{s}' \sim P}[R(\mathbf{s}', \pi'(\mathbf{s}')) + \gamma \mathbb{E}_{\mathbf{s}''}[V^{\pi}(\mathbf{s}'')]] \\ &\leq \ldots \quad (\text{无限展开}) \quad \leq V^{\pi'}(\mathbf{s}) \end{aligned}\] \[\blacksquare\]

2.2.3 Bellman最优算子的收缩性 — Banach不动点定理证明

定义Bellman最优算子 \(\mathcal{T}^*: \mathbb{R}^{\vert \mathcal{S}\vert } \to \mathbb{R}^{\vert \mathcal{S}\vert }\):

\[(\mathcal{T}^* V)(\mathbf{s}) = \max_{\mathbf{a} \in \mathcal{A}} \left[R(\mathbf{s}, \mathbf{a}) + \gamma \sum_{\mathbf{s}' \in \mathcal{S}} P(\mathbf{s}' \mid \mathbf{s}, \mathbf{a}) V(\mathbf{s}')\right]\]

定理(Bellman算子的 \(\gamma\)-收缩性): \(\|\mathcal{T}^* V_1 - \mathcal{T}^* V_2\|_{\infty} \leq \gamma \|V_1 - V_2\|_{\infty}\)

证明:

\[\begin{aligned} \|(\mathcal{T}^* V_1) - (\mathcal{T}^* V_2)\|_{\infty} &= \max_{\mathbf{s}} \left\vert \max_{\mathbf{a}} [R(\mathbf{s}, \mathbf{a}) + \gamma \sum_{\mathbf{s}'} P(\mathbf{s}'\vert \mathbf{s}, \mathbf{a}) V_1(\mathbf{s}')] - \max_{\mathbf{a}} [R(\mathbf{s}, \mathbf{a}) + \gamma \sum_{\mathbf{s}'} P(\mathbf{s}'\vert \mathbf{s}, \mathbf{a}) V_2(\mathbf{s}')] \right\vert \end{aligned}\]

利用 \(\vert \max_a f(a) - \max_a g(a)\vert \leq \max_a \vert f(a) - g(a)\vert\) (max算子的非扩张性):

\[\begin{aligned} \|(\mathcal{T}^* V_1) - (\mathcal{T}^* V_2)\|_{\infty} &\leq \max_{\mathbf{s}, \mathbf{a}} \left\vert \gamma \sum_{\mathbf{s}'} P(\mathbf{s}'\vert \mathbf{s}, \mathbf{a}) (V_1(\mathbf{s}') - V_2(\mathbf{s}')) \right\vert \\ &\leq \gamma \max_{\mathbf{s}, \mathbf{a}} \sum_{\mathbf{s}'} P(\mathbf{s}'\vert \mathbf{s}, \mathbf{a}) \cdot \max_{\mathbf{s}''} \vert V_1(\mathbf{s}'') - V_2(\mathbf{s}'')\vert \\ &= \gamma \max_{\mathbf{s}, \mathbf{a}} \sum_{\mathbf{s}'} P(\mathbf{s}'\vert \mathbf{s}, \mathbf{a}) \cdot \|V_1 - V_2\|_{\infty} \\ &= \gamma \|V_1 - V_2\|_{\infty} \end{aligned}\]

最后一步成立是因为 \(\sum_{\mathbf{s}'} P(\mathbf{s}'\vert \mathbf{s}, \mathbf{a}) = 1\)。\(\blacksquare\)

由Banach不动点定理: 完备度量空间上的收缩映射存在唯一不动点。因此 \(\mathcal{T}^*\) 有唯一不动点,且恰好是 \(V^*\): \(\mathcal{T}^* V^* = V^*\)。值迭代 \(V_{k+1} \leftarrow \mathcal{T}^* V_k\) 从任意初始 \(V_0\) 出发以线性速率收敛:

\[\|V_k - V^*\|_{\infty} \leq \gamma^k \|V_0 - V^*\|_{\infty}\]

机器人学含义: 在连续状态空间中,函数近似(神经网络)替代了精确值函数表格。深度RL丢失了精确收敛保证,但换取了在高维连续空间中的可行解能力——这是”利用计算的苦涩教训”在RL中的具体体现。

2.3 策略梯度定理的完整证明

策略梯度方法直接对期望回报做梯度上升。这是处理连续动作空间的自然选择——\(\arg\max_{\mathbf{a}} Q\) 无法在 \(\mathbb{R}^{d_a}\) 上枚举。

定理(Policy Gradient Theorem) [Sutton et al., 1999]:

\[\boxed{\nabla_{\boldsymbol{\theta}} J(\boldsymbol{\theta}) = \mathbb{E}_{\pi_{\boldsymbol{\theta}}}\left[\sum_{t=0}^{\infty} \nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) \cdot \Psi_t\right]}\]

其中 \(\Psi_t\) 可为以下任一形式(均给出无偏梯度估计; 以优势函数 \(\Psi_t = A^{\pi}(\mathbf{s}_t, \mathbf{a}_t)\) 方差最小):

完整证明(5步):

步骤1 — 轨迹概率分解。轨迹 \(\tau = (\mathbf{s}_0, \mathbf{a}_0, \ldots, \mathbf{s}_T)\) 的概率密度:

\[p_{\boldsymbol{\theta}}(\tau) = \rho_0(\mathbf{s}_0) \prod_{t=0}^{T-1} \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) \cdot P(\mathbf{s}_{t+1} \mid \mathbf{s}_t, \mathbf{a}_t)\]

关键洞察: 环境转移 \(P\) 和初始分布 \(\rho_0\) 与策略参数 \(\boldsymbol{\theta}\) 无关。

步骤2 — 对数导数技巧。利用 \(\nabla_{\boldsymbol{\theta}} p_{\boldsymbol{\theta}}(\tau) = p_{\boldsymbol{\theta}}(\tau) \nabla_{\boldsymbol{\theta}} \log p_{\boldsymbol{\theta}}(\tau)\):

\[\begin{aligned} \nabla_{\boldsymbol{\theta}} J(\boldsymbol{\theta}) &= \nabla_{\boldsymbol{\theta}} \mathbb{E}_{\tau \sim p_{\boldsymbol{\theta}}}[R(\tau)] = \nabla_{\boldsymbol{\theta}} \int R(\tau) p_{\boldsymbol{\theta}}(\tau) d\tau \\ &= \int R(\tau) \nabla_{\boldsymbol{\theta}} p_{\boldsymbol{\theta}}(\tau) d\tau \quad (\text{积分与梯度交换}) \\ &= \int R(\tau) p_{\boldsymbol{\theta}}(\tau) \nabla_{\boldsymbol{\theta}} \log p_{\boldsymbol{\theta}}(\tau) d\tau \\ &= \mathbb{E}_{\tau \sim p_{\boldsymbol{\theta}}}\left[R(\tau) \nabla_{\boldsymbol{\theta}} \log p_{\boldsymbol{\theta}}(\tau)\right] \end{aligned}\]

步骤3 — 环境动力学与策略解耦(策略梯度定理的精髓):

\[\begin{aligned} \log p_{\boldsymbol{\theta}}(\tau) &= \log \rho_0(\mathbf{s}_0) + \sum_{t=0}^{T-1} \left[\log \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) + \log P(\mathbf{s}_{t+1} \mid \mathbf{s}_t, \mathbf{a}_t)\right] \\ \nabla_{\boldsymbol{\theta}} \log p_{\boldsymbol{\theta}}(\tau) &= \sum_{t=0}^{T-1} \nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) + 0 + 0 \end{aligned}\]

\(\rho_0\) 和 \(P\) 不含 \(\boldsymbol{\theta}\),梯度为零——策略梯度定理不需要环境动力学模型。这就是model-free RL的数学基础。

步骤4 — 因果性与baseline减除。时刻 \(t\) 的动作不影响之前的奖励:

\[\nabla_{\boldsymbol{\theta}} J(\boldsymbol{\theta}) = \mathbb{E}_{\tau \sim p_{\boldsymbol{\theta}}}\left[\sum_{t=0}^{T-1} \nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) \cdot G_t\right]\]

Baseline \(b(\mathbf{s}_t)\) 不引入偏差:

\[\mathbb{E}_{\mathbf{a}_t \sim \pi_{\boldsymbol{\theta}}}\left[\nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) \cdot b(\mathbf{s}_t)\right] = b(\mathbf{s}_t) \nabla_{\boldsymbol{\theta}} \underbrace{\mathbb{E}_{\mathbf{a}_t}[1]}_{=1} = 0\]

步骤5 — 最终形式。用 \(Q^{\pi}\) 替代 \(G_t\) 的期望,用 \(V^{\pi}\) 作为最优baseline:

\[\boxed{\nabla_{\boldsymbol{\theta}} J(\boldsymbol{\theta}) = \mathbb{E}_{\pi_{\boldsymbol{\theta}}}\left[\sum_{t=0}^{\infty} \nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t) \cdot A^{\pi}(\mathbf{s}_t, \mathbf{a}_t)\right]}\] \[\blacksquare\]

从REINFORCE到Actor-Critic的演进逻辑:

2.4 广义优势估计(GAE)的完整推导

GAE(Schulman et al., 2016)是当代策略梯度方法中最重要的方差削减技术。核心思想: 在偏差和方差之间用参数 \(\lambda\) 做连续的、可微调的折衷。

定义(TD误差): \(\delta_t^V = R_t + \gamma V(\mathbf{s}_{t+1}) - V(\mathbf{s}_t)\)

k-步优势估计: \(\hat{A}_t^{(k)} = \sum_{l=0}^{k-1} \gamma^l \delta_{t+l}^V\)

性质: \(k=1\) → 单步TD(低方差、高偏差);\(k \to \infty\) → 蒙特卡洛(无偏、高方差)。

GAE的关键洞察: 不选固定 \(k\),而对所有可能 \(k\) 按指数衰减权重 \(\lambda^{k-1}\) 加权组合:

\[\boxed{\hat{A}_t^{\text{GAE}(\gamma, \lambda)} = (1 - \lambda)\sum_{k=1}^{\infty} \lambda^{k-1} \hat{A}_t^{(k)} = \sum_{l=0}^{\infty} (\gamma \lambda)^l \delta_{t+l}^V}\]

推导(交换求和次序):

\[\begin{aligned} \hat{A}_t^{\text{GAE}} &= (1 - \lambda) \sum_{k=1}^{\infty} \lambda^{k-1} \sum_{l=0}^{k-1} \gamma^l \delta_{t+l}^V \\ &= (1 - \lambda) \sum_{l=0}^{\infty} \gamma^l \delta_{t+l}^V \underbrace{\sum_{k=l+1}^{\infty} \lambda^{k-1}}_{\text{几何级数: } \frac{\lambda^l}{1-\lambda}} \quad (\text{交换求和次序}) \\ &= \sum_{l=0}^{\infty} (\gamma \lambda)^l \delta_{t+l}^V \end{aligned}\]

参数 \(\lambda\) 的物理含义:

\(\lambda\) 等效行为 方差 偏差 适用场景
\(\lambda = 0\) 1-步TD 最低 最高 环境高度随机
\(\lambda = 0.95\) 约20步有效窗口 低 低 机器人学推荐
\(\lambda = 1\) MC(无折扣) 最高 无偏 环境完全确定性

机器人学典型值 \(\lambda \in [0.92, 0.97]\)。有效时间窗口约 \(\frac{1}{1-\gamma\lambda} \approx 10\text{-}30\) 步(假设 \(\gamma=0.99\)),恰好覆盖步态周期的相位转换时间尺度。

GAE的递推计算: 从后向前,每步仅需一次乘法和加法:

\[\hat{A}_t^{\text{GAE}} = \delta_t^V + \gamma \lambda (1 - d_t) \hat{A}_{t+1}^{\text{GAE}}\]

其中 \(d_t\) 是终止标志。

GAE与TD(\(\lambda\))的统一: \(G_t^{\lambda} = V(\mathbf{s}_t) + \hat{A}_t^{\text{GAE}}\)。\(\lambda=0\) 给出TD(0)目标,\(\lambda=1\) 给出MC回报。GAE将所有介于其间的可能性无缝统一。

2.5 PPO: 信任区域策略优化的实用化

PPO(Schulman et al., 2017)是机器人学中应用最广泛的on-policy RL算法。其前身TRPO通过KL散度约束限制策略更新幅度——但需要共轭梯度。PPO用一个巧妙的裁剪(clipping)机制实现几乎相同的效果。

重要性采样比率: \(r_t(\boldsymbol{\theta}) = \frac{\pi_{\boldsymbol{\theta}}(\mathbf{a}_t \mid \mathbf{s}_t)}{\pi_{\boldsymbol{\theta}_{\text{old}}}(\mathbf{a}_t \mid \mathbf{s}_t)}\)

PPO的裁剪代理目标:

\[\boxed{L^{\text{CLIP}}(\boldsymbol{\theta}) = \mathbb{E}_t\left[\min\left(r_t(\boldsymbol{\theta}) \hat{A}_t,\; \text{clip}(r_t(\boldsymbol{\theta}), 1 - \epsilon, 1 + \epsilon) \hat{A}_t\right)\right]}\]

clip机制的工作原理:

Case 1: \(\hat{A}_t > 0\)(该动作好于预期)。\(L = \min(r_t, 1+\epsilon) \hat{A}_t\)。当 \(r_t > 1+\epsilon\) 时梯度为零——防止过于激进地增加已不错的动作概率。

Case 2: \(\hat{A}_t < 0\)(该动作差于预期)。\(L\) 等价于 \(\max(r_t, 1-\epsilon) \hat{A}_t\)。当 \(r_t < 1-\epsilon\) 时梯度为零——防止过于激进地惩罚已不太可能被选择的动作。

PPO的完整损失函数:

\[L^{\text{PPO}}(\boldsymbol{\theta}, \boldsymbol{\phi}) = \mathbb{E}_t\left[L^{\text{CLIP}}(\boldsymbol{\theta}) - c_1 L^{\text{VF}}(\boldsymbol{\phi}) + c_2 S[\pi_{\boldsymbol{\theta}}](\mathbf{s}_t)\right]\]

其中 \(L^{\text{VF}} = (V_{\boldsymbol{\phi}}(\mathbf{s}_t) - V_t^{\text{targ}})^2\) 是价值函数损失,\(S\) 是策略熵奖励。典型超参数: \(\epsilon=0.2\), \(c_1=0.5\), \(c_2=0.01\)。

连续动作空间的策略参数化: 动作空间 \(\mathbf{a} \in \mathbb{R}^{d_a}\)。标准做法是对角高斯分布:

\[\pi_{\boldsymbol{\theta}}(\mathbf{a} \mid \mathbf{s}) = \mathcal{N}\left(\boldsymbol{\mu}_{\boldsymbol{\theta}}(\mathbf{s}),\; \text{diag}(\boldsymbol{\sigma}_{\boldsymbol{\theta}}^2(\mathbf{s}))\right)\]

Actor网络输出 \(\boldsymbol{\mu}_{\boldsymbol{\theta}} \in \mathbb{R}^{d_a}\) 和 \(\log \boldsymbol{\sigma}_{\boldsymbol{\theta}} \in \mathbb{R}^{d_a}\) (对数形式保证正定性)。动作采样通过重参数化: \(\mathbf{a} = \boldsymbol{\mu}_{\boldsymbol{\theta}}(\mathbf{s}) + \boldsymbol{\sigma}_{\boldsymbol{\theta}}(\mathbf{s}) \odot \boldsymbol{\epsilon}\), \(\boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I}_{d_a})\)。

对数概率: \(\log \pi_{\boldsymbol{\theta}}(\mathbf{a} \mid \mathbf{s}) = -\frac{d_a}{2} \log(2\pi) - \frac{1}{2} \sum_{i=1}^{d_a} [\frac{(a_i - \mu_i)^2}{\sigma_i^2} + 2\log \sigma_i]\)

2.6 SAC: 最大熵强化学习 — 机器人RL的标准范式

SAC(Haarnoja et al., 2018)是为连续动作空间设计的off-policy算法,已成为机器人RL的事实标准。核心创新: 将熵正则化植入RL目标函数。

2.6.1 最大熵目标与Soft Bellman方程

最大熵RL目标:

\[\boxed{J_{\text{SAC}}(\pi) = \sum_{t=0}^{\infty} \mathbb{E}_{(\mathbf{s}_t, \mathbf{a}_t) \sim \rho_{\pi}}\left[R(\mathbf{s}_t, \mathbf{a}_t) + \alpha \, \mathcal{H}(\pi(\cdot \mid \mathbf{s}_t))\right]}\]

其中 \(\mathcal{H}(\pi(\cdot \mid \mathbf{s})) = -\mathbb{E}_{\mathbf{a} \sim \pi}[\log \pi(\mathbf{a} \mid \mathbf{s})]\) 是策略熵。\(\alpha > 0\) 控制探索与利用平衡: \(\alpha \to 0\) 退化回标准RL;\(\alpha \to \infty\) 退化为均匀随机策略。

最大熵框架的三大优势:

  1. 自然探索: 熵项鼓励策略保持随机性,防止过早收敛到次优确定性策略。在多模态奖励地形(如多条步态都能稳定行走)中尤为重要。
  2. 鲁棒性: 最大熵策略更”圆滑”,对sim-to-real迁移中的模型误差更宽容。
  3. 样本效率: Off-policy replay buffer使样本效率远超on-policy算法(10x-100x差距),对机器人学意义深远。

Soft值函数: 从最大熵目标定义Soft Q和Soft V:

\[Q_{\text{soft}}^{\pi}(\mathbf{s}, \mathbf{a}) = R(\mathbf{s}, \mathbf{a}) + \gamma \mathbb{E}_{\mathbf{s}' \sim P}\left[V_{\text{soft}}^{\pi}(\mathbf{s}')\right]\] \[V_{\text{soft}}^{\pi}(\mathbf{s}) = \mathbb{E}_{\mathbf{a} \sim \pi}\left[Q_{\text{soft}}^{\pi}(\mathbf{s}, \mathbf{a}) - \alpha \log \pi(\mathbf{a} \mid \mathbf{s})\right]\]

合并得到Soft Bellman方程:

\[\boxed{Q_{\text{soft}}^{\pi}(\mathbf{s}, \mathbf{a}) = R(\mathbf{s}, \mathbf{a}) + \gamma \mathbb{E}_{\mathbf{s}' \sim P,\, \mathbf{a}' \sim \pi}\left[Q_{\text{soft}}^{\pi}(\mathbf{s}', \mathbf{a}') - \alpha \log \pi(\mathbf{a}' \mid \mathbf{s}')\right]}\]

与标准Bellman方程的唯一差异: 每步奖励扣除了 \(\alpha \log \pi\)——高熵动作被”征税”,低熵动作获”补贴”。

2.6.2 SAC重参数化技巧 — 机器人学视角

策略更新需计算 \(\nabla_{\boldsymbol{\theta}} \mathbb{E}_{\mathbf{a} \sim \pi_{\boldsymbol{\theta}}}[Q(\mathbf{s}, \mathbf{a}) - \alpha \log \pi_{\boldsymbol{\theta}}(\mathbf{a} \mid \mathbf{s})]\)。直接用对数导数技巧(§2.3)会产生高方差——因为动作 \(\mathbf{a}\) 的采样随机性被注入梯度。

重参数化技巧将采样与网络参数解耦:

\[\boxed{\mathbf{a} = f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s}) = \boldsymbol{\mu}_{\boldsymbol{\theta}}(\mathbf{s}) + \boldsymbol{\sigma}_{\boldsymbol{\theta}}(\mathbf{s}) \odot \boldsymbol{\epsilon}, \quad \boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I})}\]

现在 \(\boldsymbol{\theta}\) 仅出现在确定性函数 \(f_{\boldsymbol{\theta}}\) 中。策略目标函数:

\[J_{\pi}(\boldsymbol{\theta}) = \mathbb{E}_{\mathbf{s} \sim \mathcal{D},\, \boldsymbol{\epsilon} \sim \mathcal{N}}\left[\alpha \log \pi_{\boldsymbol{\theta}}(f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s}) \mid \mathbf{s}) - Q_{\boldsymbol{\psi}}(\mathbf{s}, f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s}))\right]\]

通过链式法则求梯度:

\[\boxed{\nabla_{\boldsymbol{\theta}} J_{\pi} = \mathbb{E}_{\mathbf{s}, \boldsymbol{\epsilon}}\left[\nabla_{\mathbf{a}} (\alpha \log \pi_{\boldsymbol{\theta}} - Q_{\boldsymbol{\psi}}) \big\vert _{\mathbf{a} = f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s})} \cdot \nabla_{\boldsymbol{\theta}} f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s}) + \alpha \nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}\right]}\]

第一项通过 \(\nabla_{\mathbf{a}} Q\) 反向传播(利用Q网络的信息丰富的梯度),第二项是熵对 \(\boldsymbol{\theta}\) 的直接梯度。

重参数化为何方差更小? 标准策略梯度的方差来自 \(\log \pi_{\boldsymbol{\theta}}\) 梯度和 \(Q\) 值两个随机变量之积。重参数化将 \(\nabla_{\mathbf{a}} Q\) 带入计算——\(\nabla_{\mathbf{a}} Q\) 在接近贪心动作时趋于零,提供自然方差衰减。对高维动作空间(如Shadow Hand的24维),方差削减效果是质变式的。

tanh压缩: 机器人动作通常有界(\(a_i \in [-1, 1]\),关节限位)。SAC用tanh压缩:

\[\mathbf{a} = \tanh(\boldsymbol{\mu}_{\boldsymbol{\theta}}(\mathbf{s}) + \boldsymbol{\sigma}_{\boldsymbol{\theta}}(\mathbf{s}) \odot \boldsymbol{\epsilon})\]

对数概率通过变量变换修正:

\[\log \pi(\mathbf{a} \mid \mathbf{s}) = \log \mathcal{N}(\mathbf{u} \mid \boldsymbol{\mu}, \boldsymbol{\sigma}^2) - \sum_{i=1}^{d_a} \log(1 - \tanh^2(u_i))\]

其中 \(\mathbf{u} \sim \mathcal{N}(\boldsymbol{\mu}, \boldsymbol{\sigma}^2)\) 是tanh之前的pre-activation。第二项是 \(\tanh\) 的雅可比行列式对数。

2.6.3 SAC算法完整流程

双Q网络(Clipped Double-Q): 两组独立Q网络 \(Q_{\boldsymbol{\psi}_1}, Q_{\boldsymbol{\psi}_2}\) 及其目标网络。取最小值抑制overestimation bias(Fujimoto et al., 2018): \(\min_{j=1,2} Q_{\bar{\boldsymbol{\psi}}_j}(\mathbf{s}', \mathbf{a}')\)

Critic更新: 最小化Soft Bellman残差:

\[J_Q(\boldsymbol{\psi}_j) = \mathbb{E}_{(\mathbf{s}, \mathbf{a}, r, \mathbf{s}', d) \sim \mathcal{D}}\left[(Q_{\boldsymbol{\psi}_j}(\mathbf{s}, \mathbf{a}) - y)^2\right]\]

目标值: \(y = r + \gamma (1 - d)(\min_{j=1,2} Q_{\bar{\boldsymbol{\psi}}_j}(\mathbf{s}', \mathbf{a}') - \alpha \log \pi_{\boldsymbol{\theta}}(\mathbf{a}' \mid \mathbf{s}'))\), \(\mathbf{a}' \sim \pi_{\boldsymbol{\theta}}(\cdot \mid \mathbf{s}')\)

Actor更新(重参数化): \(J_{\pi}(\boldsymbol{\theta}) = \mathbb{E}_{\mathbf{s} \sim \mathcal{D}, \boldsymbol{\epsilon}}\left[\alpha \log \pi_{\boldsymbol{\theta}}(f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s}) \mid \mathbf{s}) - \min_{j} Q_{\boldsymbol{\psi}_j}(\mathbf{s}, f_{\boldsymbol{\theta}}(\boldsymbol{\epsilon}; \mathbf{s}))\right]\)

自动温度调节: \(J(\alpha) = \mathbb{E}_{\mathbf{a} \sim \pi_{\boldsymbol{\theta}}}[-\alpha \log \pi_{\boldsymbol{\theta}}(\mathbf{a} \mid \mathbf{s}) - \alpha \bar{\mathcal{H}}]\), 目标熵 \(\bar{\mathcal{H}} = -\dim(\mathcal{A})\)

目标网络软更新: \(\bar{\boldsymbol{\psi}}_j \leftarrow \tau \boldsymbol{\psi}_j + (1 - \tau)\bar{\boldsymbol{\psi}}_j\), \(\tau \ll 1\) (典型值 \(0.005\))

2.6.4 SAC vs PPO: 机器人学中的选择指南

维度 SAC PPO
数据来源 Off-policy(replay buffer) On-policy(当前策略)
样本效率 高(可重用历史数据) 低(每次更新后丢弃)
训练稳定性 中等(对超参数敏感) 高(clip机制提供天然稳定性)
并行化 独立环境并行 同步环境并行
熵处理 目标函数内置(最大熵) 附加熵奖励项
适用场景 仿真中长期训练; 样本效率关键 大规模并行仿真(Isaac Gym)
典型训练步数 \(10^5 - 10^6\) \(10^6 - 10^8\)

2.7 Sim-to-Real迁移: 从仿真到真实世界

机器人RL的根本矛盾: 训练需海量交互(\(10^6 - 10^9\)步),而真实硬件每步都有时间和磨损成本。Sim-to-Real将训练放在仿真器中进行。

Sim-to-Real鸿沟的形式化: \(\mathcal{L}_{\text{SR}}(\pi) = J_{\text{real}}(\pi) - J_{\text{sim}}(\pi)\)。根源: \(P_{\text{sim}} \neq P_{\text{real}}\) 且 \(\Omega_{\text{sim}} \neq \Omega_{\text{real}}\)

2.7.1 域随机化(Domain Randomization, DR)

训练期间随机化仿真参数 \(\xi \sim p(\xi)\),迫使策略对参数变化鲁棒:

\[J_{\text{DR}}(\pi) = \mathbb{E}_{\xi \sim p(\xi)}\left[\mathbb{E}_{\tau \sim \pi, \mathcal{M}_\xi}\left[\sum_{t} R_t\right]\right]\]

Episode-level vs Step-level: Episode-level(每episode采样一次)优于Step-level(每步重采样),因为: (a)真实世界参数保持固定;(b)Step-level产生非物理的参数波动;(c)Episode-level迫使策略从历史中隐式辨识参数——训练出内嵌于策略中的”系统辨识器”。

OpenAI灵巧手的DR参数空间:

参数 随机化范围 物理含义
手指摩擦系数 \(\mathcal{U}[0.5, 1.5]\) 不同表面状况
物体质量 名义值 \(\times [0.7, 1.3]\) 未知物体
关节阻尼 名义值 \(\times [0.5, 1.5]\) 温度变化/磨损
物体尺寸 \(\pm 5\%\) 制造公差
外力扰动 随机脉冲 意外碰撞
执行器延迟 \([0, 20]\) ms 通信延迟
观测噪声 \(\mathcal{N}(0, \sigma_{\text{obs}}^2)\) 传感器噪声

2.7.2 系统辨识(System Identification)

DR的局限: 真实参数可能不在随机化范围内。SysID用少量真实数据校准仿真器:

\[\hat{\xi} = \arg\min_{\xi} \sum_{(\mathbf{s}_t^{\text{real}}, \mathbf{a}_t^{\text{real}}, \mathbf{s}_{t+1}^{\text{real}})} \|\mathbf{s}_{t+1}^{\text{real}} - f_{\text{sim}}(\mathbf{s}_t^{\text{real}}, \mathbf{a}_t^{\text{real}}; \xi)\|^2\]

SysID缩小所需DR范围,两者协同使用效果最佳。

2.7.3 域适应(Domain Adaptation)

学习映射 \(\Phi: \mathcal{S}_{\text{sim}} \to \mathcal{S}_{\text{real}}\),使仿真策略可应用于真实观测。对视觉观测(图像)的域适应最为有效——将仿真渲染图像”风格迁移”到真实相机的色彩/纹理分布。


三、关键案例分析

3.1 Haarnoja et al.(RSS 2019): 通过深度RL学习四足行走

问题设定: 四足机器人Minitaur(8自由度,每条腿2个直接驱动电机)在平面上稳定行走,仅使用本体感觉(关节编码器 + IMU, 无外部视觉)。动作空间为8维关节位置PD控制目标。

方法论核心 — SAC + 层次化PD控制:

奖励函数设计是核心工程贡献:

\[R_t = \underbrace{w_v \cdot \min(v_x, v_x^{\text{des}})}_{\text{前进速度}} + \underbrace{w_a \cdot \mathbb{1}_{\text{alive}}}_{\text{存活奖励}} - \underbrace{w_e \cdot \sum_i \vert \tau_i \dot{q}_i\vert }_{\text{能量消耗}} - \underbrace{w_q \cdot \|\mathbf{q} - \mathbf{q}_{\text{nom}}\|_2^2}_{\text{姿态正则化}}\]

每个子项的物理含义:

层次化控制架构: 策略输出关节位置目标 \(\mathbf{q}_{\text{des}}\)(100Hz),底层PD控制器1kHz跟踪:

\[\boldsymbol{\tau} = K_p(\mathbf{q}_{\text{des}} - \mathbf{q}) - K_d \dot{\mathbf{q}}\]

这种分层的优势: (a)策略从直接力控制降级为目标位置选择;(b)PD控制器提供平滑执行器行为,稳定训练;(c)与真实电机驱动器的位置控制接口直接兼容。

SAC的行走定制: (1) 状态堆叠最近3帧以推断速度;(2) 策略均值裁剪到关节限位;(3) 双Q + 自动温度调节。

训练与结果: MuJoCo仿真, 8并行环境, 约200万步(~2小时)收敛, 速度跟踪误差约0.1m/s。SAC比DDPG收敛快约2x且步态更自然。简单域随机化(地面摩擦)后zero-shot迁移成功。

3.2 OpenAI et al.(IJRR 2020): 通过RL学习灵巧手中操作

问题设定: Shadow Dexterous Hand(24自由度五指仿人灵巧手)在手掌内旋转物体到达目标姿态。训练完全在MuJoCo仿真中进行,zero-shot迁移到真实硬件。

方法论核心 — PPO + LSTM + 非对称Actor-Critic + 域随机化:

非对称Actor-Critic是该工作的核心架构洞见:

非对称架构的有效性原理:

  1. Critic享有特权信息 → 极为精确的优势估计 → 低方差梯度信号
  2. Actor被迫从部分观测中提取隐含状态 → 隐式学习状态估计器
  3. 零冗余部署: 推理时仅需Actor网络
  4. 本质上是通过RL进行表示学习——无需标注状态真值

LSTM的角色: 将过去约50步的观测压缩为隐状态 \(\mathbf{h}_t\),使策略能够: (1)通过时序差分估计物体速度;(2)从接触模式推断被遮挡的物体位姿;(3)捕获滚动接触动力学;(4)建模肌腱驱动的滞后效应。

训练配置与结果: 6144并行CPU核心, ~50小时。PPO: lr=\(3\times10^{-4}\), batch=98304, \(\gamma=0.998\), \(\lambda=0.95\), \(\epsilon=0.2\)。手掌内旋转zero-shot迁移成功率~90%。失败主要来自仿真未建模的物理效应(静摩擦、柔性接触、肌腱滞后)。

工程教训: 非对称Actor-Critic已成为sim-to-real迁移的标配(RMA, ANYmal等均采用);Episode-level随机化优于Step-level;大规模并行化使on-policy PPO与off-policy SAC可在样本效率层面竞争。


四、算法与代码实现

本节给出机器人RL中三个核心组件的完整PyTorch实现。所有代码带逐行中文注释,标注公式出处和工程考量。

4.1 PPO for Continuous Control(连续控制的PPO)

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.distributions import Normal
import numpy as np


class GaussianActor(nn.Module):
    """连续动作空间的对角高斯策略网络(Actor)

    输出: μ_θ(s) ∈ R^{d_a} 和 log σ_θ ∈ R^{d_a}
    对应 §2.5: π_θ(a|s) = N(μ_θ(s), diag(σ_θ²(s)))

    架构: 2层MLP (hidden=256) 是机器人RL的经验标配。
    本体感觉状态(关节角度/IMU)用2层已足够。
    """
    def __init__(self, obs_dim, act_dim, hidden_dim=256):
        super().__init__()
        # 共享特征提取层
        self.net = nn.Sequential(
            nn.Linear(obs_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
        )
        self.mean_head = nn.Linear(hidden_dim, act_dim)
        # 对数标准差: 可学习参数 (状态无关)
        # init log_std=0 → std=1.0 → 初始探索范围约 [-1, 1]
        self.log_std = nn.Parameter(torch.zeros(act_dim))

    def forward(self, obs):
        """前向传播: 输入状态, 输出高斯分布参数"""
        h = self.net(obs)
        mean = self.mean_head(h)
        # clamp 防止 exp(log_std) 数值爆炸
        # exp(-20) ≈ 2e-9, exp(2) ≈ 7.4
        std = torch.exp(self.log_std.clamp(-20, 2))
        return mean, std

    def sample(self, obs):
        """重参数化采样 + 对数概率计算

        对应 §2.5: a = μ + σ ⊙ ε, ε ~ N(0, I)
        """
        mean, std = self.forward(obs)
        dist = Normal(mean, std)
        action = dist.rsample()  # 重参数化 — 梯度流过采样
        # sum(dim=-1): 独立高斯假设, 多维log_prob = 各维之和
        log_prob = dist.log_prob(action).sum(dim=-1)
        return action, log_prob

    def evaluate(self, obs, action):
        """评估给定动作的对数概率 (用于PPO的 ratio = π_new/π_old)"""
        mean, std = self.forward(obs)
        dist = Normal(mean, std)
        log_prob = dist.log_prob(action).sum(dim=-1)
        entropy = dist.entropy().sum(dim=-1)
        return log_prob, entropy


class ValueCritic(nn.Module):
    """V(s) 状态值函数网络(Critic)

    输出: 标量 V_φ(s) ∈ R
    对应 Bellman 方程: V^π(s) = E_a[R(s,a) + γ V^π(s')]
    """
    def __init__(self, obs_dim, hidden_dim=256):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(obs_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, 1),
        )

    def forward(self, obs):
        return self.net(obs).squeeze(-1)  # [B,1] → [B]


def compute_gae(rewards, values, dones, gamma=0.99, lam=0.95):
    """广义优势估计(GAE)的向量化实现

    对应 §2.4: A_t^GAE = Σ_{l=0}^{∞} (γλ)^l δ_{t+l}^V

    递推形式: A_t = δ_t + γλ(1-d_t)A_{t+1}
    其中 δ_t = r_t + γ V(s_{t+1})(1-d_t) - V(s_t)

    Args:
        rewards: [T]          奖励序列
        values:  [T+1]        价值估计, values[-1] 是 bootstrap value
        dones:   [T]          终止标志 (1.0=terminal, 0.0=not)
        gamma:   折扣因子
        lam:     GAE-λ 参数 (机器人学典型值: 0.95)

    Returns:
        advantages: [T]       优势估计 A_t^GAE
        returns:    [T]       TD(λ) 回报目标 G_t^λ = A_t + V(s_t)
    """
    T = len(rewards)
    advantages = torch.zeros(T)
    gae = 0.0

    # 反向遍历 (从 T-1 到 0)
    for t in reversed(range(T)):
        # TD误差: δ_t = r_t + γ V(s_{t+1}) - V(s_t)
        delta = (rewards[t]
                 + gamma * values[t + 1] * (1.0 - dones[t])
                 - values[t])
        # GAE递推: gae_t = δ_t + γλ(1-d_t) gae_{t+1}
        gae = delta + gamma * lam * (1.0 - dones[t]) * gae
        advantages[t] = gae

    # TD(λ) 回报目标: G_t^λ = A_t^GAE + V(s_t)
    returns = advantages + values[:-1]
    return advantages, returns


def ppo_update(actor, critic, actor_optim, critic_optim,
               obs_batch, act_batch, adv_batch, ret_batch,
               old_log_prob_batch, clip_eps=0.2, value_coef=0.5,
               entropy_coef=0.01, n_epochs=10, batch_size=64):
    """PPO 多轮更新 — mini-batch SGD + PPO clipping

    对应 §2.5:
    L^PPO = L^CLIP(θ) - c1 * L^VF(φ) + c2 * S[π_θ]
    其中 L^CLIP(θ) = min(r_t(θ) Â_t, clip(r_t(θ), 1-ε, 1+ε) Â_t)
    """
    # === 优势归一化 — 降低方差的关键工程技巧 ===
    adv_batch = (adv_batch - adv_batch.mean()) / (adv_batch.std() + 1e-8)

    dataset = torch.utils.data.TensorDataset(
        obs_batch, act_batch, adv_batch, ret_batch, old_log_prob_batch
    )
    loader = torch.utils.data.DataLoader(dataset, batch_size=batch_size,
                                          shuffle=True)

    for _ in range(n_epochs):
        for obs, act, adv, ret, old_logp in loader:

            # === Critic 更新: L^VF(φ) = MSE(V_φ(s), G_t^λ) ===
            value_pred = critic(obs)
            value_loss = F.mse_loss(value_pred, ret)

            critic_optim.zero_grad()
            value_loss.backward()
            critic_optim.step()

            # === Actor 更新: PPO clipped surrogate objective ===
            log_prob, entropy = actor.evaluate(obs, act)
            ratio = torch.exp(log_prob - old_logp)  # r_t(θ) = π_new/π_old

            # PPO clipped objective
            surr1 = ratio * adv
            surr2 = torch.clamp(ratio, 1.0 - clip_eps, 1.0 + clip_eps) * adv
            actor_loss = -torch.min(surr1, surr2).mean()

            # 完整PPO损失: L^CLIP - c2 * entropy
            loss = actor_loss - entropy_coef * entropy

            actor_optim.zero_grad()
            loss.backward()
            actor_optim.step()

4.2 SAC for Locomotion(面向机器人运动的SAC)

import copy
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.distributions import Normal
import numpy as np


class SoftQNetwork(nn.Module):
    """Soft Q-function Q_ψ(s, a)

    对应 §2.6.2 Soft Bellman 方程

    输入: [obs, act] 拼接 (d_s + d_a 维)
    输出: 标量 Q 值
    """
    def __init__(self, obs_dim, act_dim, hidden_dim=256):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(obs_dim + act_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, 1),
        )

    def forward(self, obs, act):
        return self.net(torch.cat([obs, act], dim=-1)).squeeze(-1)


class TanhGaussianActor(nn.Module):
    """带 tanh 压缩的高斯策略网络(SAC Actor)

    对应 §2.6.2:
    a = tanh(μ_θ(s) + σ_θ(s) ⊙ ε), ε ~ N(0, I)

    tanh 压缩确保 a_i ∈ (-1, 1), 契合关节限位。
    """
    LOG_STD_MIN = -20   # exp(-20) ≈ 2e-9
    LOG_STD_MAX = 2     # exp(2) ≈ 7.4

    def __init__(self, obs_dim, act_dim, hidden_dim=256):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(obs_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
        )
        self.mean_head = nn.Linear(hidden_dim, act_dim)
        self.log_std_head = nn.Linear(hidden_dim, act_dim)

    def forward(self, obs):
        h = self.net(obs)
        mean = self.mean_head(h)
        log_std = self.log_std_head(h)
        log_std = torch.clamp(log_std, self.LOG_STD_MIN, self.LOG_STD_MAX)
        std = torch.exp(log_std)
        return mean, std, log_std

    def sample(self, obs):
        """重参数化采样 + tanh 压缩 + 对数概率修正

        返回: (action, log_prob)
        """
        mean, std, log_std = self.forward(obs)
        dist = Normal(mean, std)
        u = dist.rsample()          # u ~ N(μ, σ²), 无界
        action = torch.tanh(u)      # a = tanh(u), a ∈ (-1, 1)

        # 对数概率的变量变换修正 (§2.6.2):
        # log π(a|s) = log p(u) - Σ_i log(1 - tanh²(u_i))
        log_prob_u = dist.log_prob(u).sum(dim=-1)
        # 数值稳定实现: 2*(log(2) - u - softplus(-2u))
        log_prob = log_prob_u - (
            2.0 * (np.log(2.0) - u - F.softplus(-2.0 * u))
        ).sum(dim=-1)

        return action, log_prob


class SACAgent:
    """SAC (Soft Actor-Critic) — 连续控制的标准 off-policy RL 算法

    架构 (对应 §2.6.3 完整流程):
      - Actor π_θ:     TanhGaussianActor (重参数化高斯策略)
      - Critic Q_ψ1, Q_ψ2: SoftQNetwork (双 Q, Clipped Double-Q)
      - Target Q_ψ̄1, Q_ψ̄2: EMA 目标网络
      - 自动温度调节 α: log_α 作为可学习参数

    Args:
        obs_dim:         观测维度 d_s
        act_dim:         动作维度 d_a
        lr:              学习率 (典型值 3e-4)
        gamma:           折扣因子 γ
        tau:             目标网络软更新系数 (典型值 0.005)
        alpha:           初始温度 (若自动调节则为初始值)
        target_entropy:  目标熵 H̄ (默认 -act_dim)
    """
    def __init__(self, obs_dim, act_dim, lr=3e-4, gamma=0.99,
                 tau=0.005, alpha=0.2, target_entropy=None):
        self.actor = TanhGaussianActor(obs_dim, act_dim)
        self.q1 = SoftQNetwork(obs_dim, act_dim)
        self.q2 = SoftQNetwork(obs_dim, act_dim)

        # 目标网络: deep copy 初始参数, 冻结 requires_grad
        self.q1_target = copy.deepcopy(self.q1)
        self.q2_target = copy.deepcopy(self.q2)
        for p in self.q1_target.parameters():
            p.requires_grad = False
        for p in self.q2_target.parameters():
            p.requires_grad = False

        self.actor_optim = torch.optim.Adam(self.actor.parameters(), lr=lr)
        self.q1_optim = torch.optim.Adam(self.q1.parameters(), lr=lr)
        self.q2_optim = torch.optim.Adam(self.q2.parameters(), lr=lr)

        self.gamma = gamma
        self.tau = tau

        # 自动温度调节 (Haarnoja et al., 2019)
        if target_entropy is None:
            target_entropy = -act_dim
        self.target_entropy = target_entropy
        self.log_alpha = nn.Parameter(torch.tensor(np.log(alpha)))
        self.alpha_optim = torch.optim.Adam([self.log_alpha], lr=lr)

    @property
    def alpha(self):
        """exp(log_α) 保证 α > 0"""
        return self.log_alpha.exp().item()

    def update(self, replay_buffer, batch_size=256):
        """SAC 单步更新 (off-policy: 从 replay buffer 采样)

        对应 §2.6.3 算法流程:
        1. Critic 更新 (Soft Bellman residual)
        2. Actor 更新 (重参数化梯度)
        3. 温度 α 自动调节
        4. 目标网络 EMA 软更新
        """
        obs, act, reward, next_obs, done = replay_buffer.sample(batch_size)

        # ============================================================
        # Step 1: Critic 更新 — Soft Bellman Residual
        # J_Q(ψ_j) = E[(Q_ψ_j(s,a) - y)²]
        # y = r + γ(1-d)(min_j Q_ψ̄_j(s',a') - α log π_θ(a'|s'))
        # ============================================================
        with torch.no_grad():
            next_act, next_log_prob = self.actor.sample(next_obs)
            # Clipped Double-Q: 取 min 抑制 overestimation
            q1_next = self.q1_target(next_obs, next_act)
            q2_next = self.q2_target(next_obs, next_act)
            q_next = torch.min(q1_next, q2_next) - self.alpha * next_log_prob
            # (1-done): episode 终止时不 bootstrap
            q_target = reward + self.gamma * (1.0 - done) * q_next

        q1_loss = F.mse_loss(self.q1(obs, act), q_target)
        q2_loss = F.mse_loss(self.q2(obs, act), q_target)

        self.q1_optim.zero_grad(); q1_loss.backward(); self.q1_optim.step()
        self.q2_optim.zero_grad(); q2_loss.backward(); self.q2_optim.step()

        # ============================================================
        # Step 2: Actor 更新 — 重参数化梯度 (§2.6.2)
        # J_π(θ) = E[α log π_θ(f_θ(ε;s)|s) - min_j Q_ψ_j(s, f_θ(ε;s))]
        # ============================================================
        new_act, new_log_prob = self.actor.sample(obs)
        q1_new = self.q1(obs, new_act)
        q2_new = self.q2(obs, new_act)
        q_new = torch.min(q1_new, q2_new)
        actor_loss = (self.alpha * new_log_prob - q_new).mean()

        self.actor_optim.zero_grad(); actor_loss.backward()
        self.actor_optim.step()

        # ============================================================
        # Step 3: 自动温度调节 (Haarnoja et al., 2019)
        # J(α) = E[-α log π(a|s) - α H̄]
        # ============================================================
        alpha_loss = -(self.log_alpha.exp() *
                       (new_log_prob + self.target_entropy).detach()).mean()
        self.alpha_optim.zero_grad(); alpha_loss.backward()
        self.alpha_optim.step()

        # ============================================================
        # Step 4: 目标网络 EMA 软更新: θ̄ ← τ·θ + (1-τ)·θ̄
        # ============================================================
        with torch.no_grad():
            for tp, p in zip(self.q1_target.parameters(),
                             self.q1.parameters()):
                tp.data.copy_(self.tau * p.data + (1 - self.tau) * tp.data)
            for tp, p in zip(self.q2_target.parameters(),
                             self.q2.parameters()):
                tp.data.copy_(self.tau * p.data + (1 - self.tau) * tp.data)

4.3 Domain Randomization Wrapper(域随机化包装器)

from typing import Dict, Tuple, Any
import numpy as np


class DomainRandomizationEnv:
    """域随机化环境包装器 — 每次 reset 随机采样物理参数

    实现 DR 训练范式 (§2.7.1):
      J_DR(π) = E_{ξ~p(ξ)}[E_{τ~π, M_ξ}[Σ R_t]]

    关键技术: Episode-level 随机化
      - 每个 episode 采样一次参数 ξ, 全程固定
      - 迫使策略从观测历史中隐式辨识环境参数

    为何不采用 Step-level:
      1. 真实世界参数不每步变化
      2. Step-level 产生非物理参数波动 → 误导性训练信号
      3. Episode-level 诱导隐式系统辨识能力
    """
    def __init__(self, env, randomization_config: Dict[str, Any]):
        """
        Args:
            env: 基础仿真环境 (Gym/Gymnasium 兼容)
            randomization_config: 随机化参数空间字典, 格式:
                {
                    'friction':    [0.5, 1.5],     # [low, high] 均匀分布
                    'mass_scale':  [0.7, 1.3],      # 质量缩放
                    'damping':     [0.5, 1.5],      # 阻尼缩放
                    'action_delay': [0, 20],         # 延迟 (ms)
                    'obs_noise':   0.001,            # 固定值(不随机化)
                }
        """
        self.env = env
        self.config = randomization_config
        self.current_params: Dict[str, float] = {}

    def _sample_params(self) -> Dict[str, float]:
        """从配置空间中独立采样一组物理参数"""
        params = {}
        for param_name, param_range in self.config.items():
            if isinstance(param_range, (list, tuple)):
                low, high = param_range
                params[param_name] = np.random.uniform(low, high)
            elif isinstance(param_range, (int, float)):
                params[param_name] = param_range  # 固定值
        return params

    def reset(self) -> np.ndarray:
        """重置环境 + 采样新参数 (Episode-level DR)"""
        self.current_params = self._sample_params()
        for param_name, value in self.current_params.items():
            self._apply_param(param_name, value)
        return self.env.reset()

    def step(self, action: np.ndarray) -> Tuple[np.ndarray, float, bool, Dict]:
        """执行动作"""
        return self.env.step(action)

    def _apply_param(self, param_name: str, value: float):
        """将采样参数应用到仿真环境 (MuJoCo 风格伪实现)"""
        if param_name == 'friction':
            self.env.set_geom_friction(value)
        elif param_name == 'mass_scale':
            self.env.set_body_mass_scale(value)
        elif param_name == 'damping':
            self.env.set_joint_damping(value)
        elif param_name == 'action_delay':
            self.env.set_action_delay(value)
        elif param_name == 'obs_noise':
            self.env.set_observation_noise(value)

    def get_current_params(self) -> Dict[str, float]:
        """返回当前 episode 的物理参数 (用于日志和分析)"""
        return self.current_params.copy()

五、核心Takeaway与延伸阅读

5.1 核心洞察

洞察 1: Bellman方程是RL的第一性原理,所有无模型RL算法都是其不同的实现方式。Bellman最优算子 \(\mathcal{T}^*\) 的 \(\gamma\)-收缩性赋予值迭代收敛保证(Banach不动点定理);策略梯度定理本质上是在连续动作空间中通过采样近似求解 \(\max_{\mathbf{a}} Q\);SAC的Soft Bellman方程将熵嵌入值函数定义,使探索-利用平衡成为优化目标的一部分而非外挂技巧。

洞察 2: 方差-偏差权衡贯穿RL全程 — GAE的 \(\lambda\) 参数是机器人RL中最重要的”压缩旋钮”。\(\lambda=0\) 退化为单步TD(高偏差、低方差);\(\lambda=1\) 退化为MC(无偏、高方差)。机器人学典型值 \(\lambda \approx 0.95\) 提供的有效时间窗口(\(\frac{1}{1-\gamma\lambda} \approx 10\text{-}30\)步)恰好覆盖步态周期和操作原语的自然时间尺度——这是物理世界的时间常数与算法设计的对齐。

洞察 3: 最大熵框架(SAC)是机器人RL的标准范式 — 不是因为它理论优雅,而是因为它解决了sim-to-real中的实际问题。熵正则化的三大效应——自然探索、策略鲁棒性、off-policy样本效率——每一项都直接回应了机器人RL的核心痛感。SAC的重参数化技巧利用 \(\nabla_{\mathbf{a}} Q\) 的信息丰富梯度信号,大幅降低策略梯度方差——对高自由度(Shadow Hand的24维)是质变式的改进。

洞察 4: 非对称Actor-Critic + LSTM + 域随机化是sim-to-real迁移的成熟配方。OpenAI灵巧手工作的四件套具有一般性: (1)训练时Critic享有特权仿真状态产生低方差优势估计;(2)Actor仅接收部署时可获取的观测,被迫隐式学习状态估计;(3)LSTM将时序上下文压缩为隐状态,近似恢复马尔可夫性;(4)Episode-level域随机化注入分布鲁棒性约束。这一范式已扩散到RMA(四足行走)、ANYmal、无人机导航等一系列系统。

洞察 5: 奖励函数设计是机器人RL中最重要也最”非数学”的超参数。与Atari(天然得分)和围棋(胜负明确)不同,行走/操作的奖励必须由工程师精心设计。好的奖励函数编码任务的几何/物理约束——”\(v_x\) 接近 \(v_{\text{des}}\)“而非”到达终点”;”姿态接近直立”而非”不摔倒”。逐项惩罚(能量、抖动、极限位置)防止reward hacking。奖励设计是一门介于物理、几何和心理学之间的技艺。

5.2 开放问题与研究方向

  1. 奖励规范(Reward Specification): 能否从自然语言指令或专家演示中自动推断奖励函数?Inverse RL和Preference-based RL(Christiano et al., 2017)是两条主线。

  2. 安全探索(Safe Exploration): 如何保证RL探索阶段不发生灾难性行为?约束MDP(CMDP)、控制屏障函数(CBF)、以及基于MPC的安全滤波器都是活跃方向。

  3. 世界模型 + RL: Dreamer系列(Hafner et al., 2019-2023)在学到的动力学模型中”想象”训练。这能解决样本效率问题吗?还是世界模型的累积误差使其在高精度操作中不可靠?

  4. 多任务与元RL: 能否训练一个策略同时完成行走、奔跑、跳跃?多任务RL面临灾难性遗忘、任务推断和奖励尺度平衡等困难。

  5. 大规模并行仿真: Isaac Gym将并行环境推到数万级别——是否会使得on-policy PPO的样本效率劣势变得无关紧要?

5.3 推荐延伸阅读

文献 关键贡献 与本章的关联
Sutton & Barto (2018), Ch.3-6, 13 RL完整理论体系 值函数、TD学习、策略梯度的标准参考
Schulman et al. (2016), “GAE” 广义优势估计 GAE完整推导、\(\lambda\) 消融实验
Schulman et al. (2017), “PPO” 裁剪代理目标函数 PPO vs TRPO对比、大规模分布式实验
Haarnoja et al. (2018), “SAC” 最大熵off-policy AC SAC理论基础、与DDPG/TD3的对比
Haarnoja et al. (2019), “SAC v2” 自动温度调节 使SAC成为”无调参”算法
Andrychowicz et al. (2020), IJRR OpenAI灵巧手完整版 非对称AC、DR全面分析
Tobin et al. (2017), “Domain Randomization” DR开创性工作 DR原理、首个策略迁移验证
Peng et al. (2018), “Dynamics Randomization” DR系统化实验 4项任务的DR消融研究
Hafner et al. (2023), “DreamerV3” 世界模型 + RL 隐动力学中训练策略
Kumar et al. (2021), “RMA” 快速运动适应 非对称AC在四足行走的应用(第14章)

六、练习与思考

基础练习

习题1(MDP建模与Bellman手动计算): 考虑3x3 GridWorld。状态 \(s \in \{0, 1, \ldots, 8\}\)。动作 \(\mathcal{A} = \{\text{上}, \text{下}, \text{左}, \text{右}\}\),确定性转移但碰壁则留在原地。状态8是目标(到达奖励+10并终止),状态4是陷阱(进入奖励-10并终止),其余每步 \(R=-1\)。取 \(\gamma=0.9\)。

(a) 写出该MDP的完整六元组。假设 \(\rho_0\) 均匀分布在所有非终止状态。

(b) 用值迭代手动计算 \(V^*(s)\) 对所有9个状态(至少3轮迭代)。

(c) 验证 \(V^*\) 是 \(\mathcal{T}^*\) 的不动点: 从你得到的 \(V^*\) 出发,手算 \(\mathcal{T}^* V^*\) 验证相等。

(d) 分析: 为什么深度RL无法在连续高维空间中做值迭代?你的答案应涉及维数灾难和函数近似的必要性。

习题2(策略梯度定理的工程验证): 用PyTorch实现REINFORCE算法在CartPole-v1上的训练。要求:

(a) 不查阅教学代码,根据 §2.3 的策略梯度定理独立推导实现。

(b) 实现两个版本: (i)无baseline(\(\Psi_t = G_t\));(ii)带baseline \(V_{\boldsymbol{\phi}}(\mathbf{s})\)。

(c) 每个版本运行10个随机种子,绘制: (i)episode回报学习曲线;(ii)梯度范数 \(\|\nabla_{\boldsymbol{\theta}} J\|_2\) 的变化。分析baseline对梯度方差的削减效果。

(d) 证明: 若 \(V_{\boldsymbol{\phi}} = V^{\pi}\)(完美价值函数),则带baseline的梯度估计是无偏且方差最小的(提示: §2.3步骤4)。

习题3(GAE参数扫描): 在连续控制环境(如Pendulum-v1或HalfCheetah-v2)中用PPO训练,固定所有其他超参数,仅改变 \(\lambda \in \{0, 0.5, 0.8, 0.9, 0.95, 0.99, 1.0\}\)。

(a) 绘制平均回报 vs 环境步数的曲线。

(b) 测量达到80%最终性能所需的训练步数 vs \(\lambda\)。

(c) 讨论: \(\lambda=0\)(纯TD)和 \(\lambda=1\)(纯MC)在训练初期和后期的表现差异。与GAE的”方差-偏差”理论是否一致?

(d) 在什么情况下 \(\lambda=1\) 可能优于 \(\lambda=0.95\)?(提示: 考虑环境随机性非常小的场景)

进阶练习

习题4(SAC的实现与重参数化分析): 基于 §4.2 的SACAgent框架,在HalfCheetah-v2上从零实现完整SAC训练。要求:

(a) 自己实现Replay Buffer。

(b) 训练10万步后,对同一状态重复采样1000次动作(不同 \(\boldsymbol{\epsilon}\))。绘制动作分布直方图,验证策略保持了有意义的熵(分布不是delta函数)。

(c) 比较: (i)重参数化技巧的actor更新;(ii)对数导数技巧的actor更新。量化两者的actor_loss方差。

(d) 验证Clipped Double-Q是否缓解Q值过估计: 每隔1000步记录 \(Q_{\boldsymbol{\psi}_1}, Q_{\boldsymbol{\psi}_2}\) 和实际MC回报,绘制三者趋势图。

习题5(SAC vs PPO系统对比): 在MuJoCo机器人任务(推荐Ant-v2或Humanoid-v2)上系统对比SAC和PPO:

(a) 样本效率: 横轴交互步数,纵轴平均回报。标注两算法达到相同性能阈值所需步数比。

(b) 壁钟时间: 记录实际计算时间,讨论off-policy的replay buffer开销和on-policy的rollout同步开销如何影响wall-time效率。

(c) 超参数敏感性: 学习率 \(\{10^{-4}, 3\times10^{-4}, 10^{-3}\}\) 和网络宽度 \(\{64, 128, 256, 512\}\) 的网格搜索,绘制性能热力图。

(d) 基于实验结果,为以下场景推荐算法: (i)单GPU, 10并行环境;(ii)8-GPU, 4096并行环境;(iii)真实机器人在线学习。

习题6(域随机化消融实验): 在四足行走仿真(推荐MuJoCo的Ant或Minitaur)中用PPO训练,进行DR消融研究:

(a) Baseline: 无DR(固定参数)。

(b) 单参数消融: 逐一添加随机化(地面摩擦、负载质量、关节阻尼、执行器延迟、观测噪声),测量zero-shot鲁棒性影响。

(c) 鲁棒性评估: 对每个策略在100个”外推”参数集(参数在训练范围的1.2倍之外)上评估,记录平均存活步数。

(d) 哪个参数对sim-to-real迁移最关键?是否所有参数都产生正向鲁棒性收益?

(e) 将结果与 §2.7.1 的DR形式化 \(J_{\text{DR}}\) 联系。\(p(\xi)\) 的支撑集选择如何影响分布内和分布外泛化?讨论”随机化范围越大越好”是否成立。

开放研究问题

习题7(奖励函数设计的几何方法): 四足机器人需学习”安静行走”——最小化足地接触冲击噪声。

(a) 提出至少三种不同的奖励设计方案。写出每个方案的数学表达式。

(b) 对每个方案,分析可能的reward hacking行为。例如: 机器人选择不移动,或采用低频蹦跳步态。

(c) 提出两种缓解reward hacking的策略,分析各自优劣: (i)多目标加权奖励;(ii)约束RL(硬约束而非软惩罚)。

(d) 讨论: 在极端情况下,奖励工程是否等价于”用先验知识设计控制器”?如果是,RL在机器人学中的独特价值在哪里?

习题8(域随机化的理论基础与局限): 域随机化隐含假设真实环境参数 \(\xi^*\) 在随机化分布 \(p(\xi)\) 的支撑集内。

(a) 用概率论严格陈述这一假设。若 \(\xi^* \notin \text{supp}(p)\),给出最坏情况下 \(J_{\text{real}}(\pi) - J_{\text{sim}}(\pi)\) 的下界。

(b) 结构性失配(structural mismatch): DR只能随机化仿真器已有模型的参数,但无法弥补仿真器根本不建模的物理效应(柔性接触、静摩擦、肌腱滞后)。试证: 存在一类真实物理现象,DR无法通过任何 \(p(\xi)\) 来补偿。

(c) 系统辨识(SysID, §2.7.2)和域随机化(DR, §2.7.1)如何互补?设计将两者结合的训练方案。

(d) 若有一个”完美”物理模拟器,RL是否还需策略学习?还是可直接做开环最优控制?讨论Sim-to-Real的根本哲学。


上一章: 第10章 视频世界模型

下一章: 第12章 行为克隆

提示: 第12章将介绍行为克隆(Behavioral Cloning)——从专家演示中直接学习策略。与本章的RL不同,行为克隆不需要奖励函数,但面临分布偏移的根本挑战。两章共同构成了机器人技能获取的两大范式:试错学习(RL)与演示学习(IL)。


← 第10章 视频世界模型
↑ 目录
第12章 行为克隆 →