Spinning Up 深度强化学习

许多研究人员和工程师依赖于像 Garage、OpenAI Baselines 和 RLlib 这样的优秀开源库来加速研究。然而,这些框架虽然功能强大,但其内部复杂的抽象、工程上的权衡和不甚明显的实现细节,使得它们更像是为资深研究者打造的“生产力工具”,而非为初学者准备的“入门指南”。

主流强化学习框架概览:为何它们不适合入门?

在深入 Spinning Up 之前,我们先快速了解一下当前主流的几个 RL 框架,这能帮助我们理解为何需要一个更侧重于教学的资源。

  1. Garage:由卡内基梅隆大学(CMU)和首尔大学(SNU)联合开发,是一个专为强化学习研究设计的框架。它强调模块化可复现性,允许研究者灵活地组合、扩展和测试新算法。Garage 支持 TensorFlow 和 PyTorch 后端,并内置了完善的实验管理机制。它的定位是“研究友好型”,非常适合学术界。

  2. OpenAI Baselines:这是 OpenAI 官方推出的一组高质量、标准化的经典强化学习算法实现。如果你想知道 PPO、TRPO 或 DDPG 等算法的“黄金标准”实现是怎样的,Baselines 就是你的首选参考。它的目标是提供基准,而非构建一个庞大的系统。不过,该项目近年来已较少更新,部分代码架构略显陈旧。

  3. RLlib:作为 Ray 分布式计算框架的核心组件,RLlib 的设计目标是规模化。它天生支持大规模并行训练,能够轻松驾驭数百个环境实例,并将训练任务扩展到多节点集群。RLlib 更偏向“工业级”应用,旨在将 RL 算法无缝部署到生产系统中。

这些框架无疑是推动领域发展的重要基石,但对于想从零开始理解 RL 算法核心思想的人来说,直接阅读它们的源码可能会迷失在复杂的工程细节中。

Spinning Up 的环境准备与依赖

为了解决上述问题,OpenAI 推出了 Spinning Up,一个以教育为核心目的的深度强化学习资源。在开始之前,我们需要准备好基础环境。Spinning Up 的核心依赖包括:

  • Python 3
  • OpenAI Gym
  • OpenMPI

其中,OpenAI Gym 是不可或缺的一环。它是一个用于开发和比较强化学习算法的开源库,提供了海量标准化的模拟环境(如经典的 CartPole、Atari 游戏和 MuJoCo 机器人控制等),并定义了一套统一的交互接口(reset(), step(), render())。这使得我们的算法可以无需修改就应用在不同的测试场景中,极大地促进了研究的标准化和可复现性。

Spinning Up 官方主要支持 Linux 和 macOS 系统。虽然理论上也可以在 Windows 上运行,但过程会曲折一些,需要借助 WSL (Windows Subsystem for Linux)。

Windows 用户的 WSL 安装指南

如果你是 Windows 10/11 用户,可以按照以下步骤配置一个能够运行 Spinning Up 的 Linux 环境:

  1. 启用 WSL:首先,你需要在 Windows 中启用“适用于 Linux 的 Windows 子系统”功能。具体步骤可以参考 微软官方文档

  2. 安装图形界面支持 (X Server):Gym 环境的 render() 函数需要图形界面。WSL 本身不带图形界面,因此需要一个 X Server for Windows 来接收并显示图形。

    • Xming 是一个经典选择,可以从 这里 下载安装。
    • VcXsrv 是一个更现代的替代品,最近还在迭代。
    • 安装后,请确保它正在后台运行。
  3. 配置 WSL 图形环境:启动 WSL 终端(例如,在命令提示符或 PowerShell 中输入 bash),然后执行以下命令来安装必要的库并配置 DISPLAY 环境变量,让 WSL 知道将图形数据发送到哪里。

    # 安装 X11 应用
    sudo apt-get update
    sudo apt-get install x11-apps
    
    # 配置 DISPLAY 环境变量
    # 这个命令告诉 WSL 将图形输出发送到 Windows 主机
    # 注意:如果你的 WSL 使用 NAT 网络模式,IP 地址可能需要动态获取
    export DISPLAY=$(grep -oP '(?<=nameserver ).+' /etc/resolv.conf):0
    
    # 将配置写入 .bashrc,使其永久生效
    echo "export DISPLAY=$(grep -oP '(?<=nameserver ).+' /etc/resolv.conf):0" >> ~/.bashrc
    

    小提示:localhost:0.0 在旧版 WSL 中有效,但新版 WSL 网络模式下通常需要上述动态获取 IP 的方法。

备选方案:Fired Up

如果环境配置过程出现问题,或者你更偏爱 PyTorch,那么有替代项目值得一试:Fired Up。该项目旨在用纯 PyTorch 复现 Spinning Up 的所有功能,免去了 TensorFlow 和其他复杂依赖的安装麻烦。

你可以通过以下几个简单的命令来测试 Fired Up 是否安装成功:

  1. 训练一个 PPO AgentLunarLander-v2 环境中训练一个简单的 PPO 智能体。

    python -m fireup.run ppo --hid "[32,32]" --env LunarLander-v2 --exp_name installtest --gamma 0.999
    
  2. 绘制训练结果 训练完成后,使用以下命令将日志数据可视化,查看学习曲线。

    # 请将路径替换为你的实际输出路径
    python3 -m fireup.run plot /path/to/your/firedup/data/installtest/installtest_s0
    
  3. 观看智能体表现 最后,加载训练好的模型,看看智能体在环境中的实际表现。

    # 请将路径替换为你的实际输出路径
    python3 -m fireup.run test_policy /path/to/your/firedup/data/installtest/installtest_s0
    

强化学习关键概念

../_images/rl_diagram_transparent_bg.png

强化学习世界里的主角是智能体 (agent)环境 (environment)。环境是智能体生活并与之互动的世界。在交互的每一步,智能体都会观察到世界状态 (state) 的一个(可能是部分的)信息,然后决定要采取一个动作 (action)。当智能体行动后,环境会发生改变,但有时环境自身也可能会发生变化。

智能体还会从环境中感知到一个奖励 (reward) 信号,这是一个数字,告诉它当前的世界状态有多好或多坏。智能体的目标是最大化它收到的累计奖励,这个累计奖励被称为回报 (return)。强化学习方法就是智能体可以用来学习行为以实现其目标的各种方式。


状态和观测 (States and Observations)

一个状态 (state) $s$ 是对世界状态的完整描述。关于这个世界,没有任何信息是隐藏在状态之外的。而一个观测 (observation) $o$ 则是对状态的部分描述,它可能会遗漏一些信息。

在深度强化学习中,我们几乎总是用实值的向量、矩阵或高阶张量来表示状态和观测。例如,一个视觉观测可以用其像素值的RGB矩阵来表示;一个机器人的状态可以用它的关节角度和速度来表示。

当智能体能够观测到环境的完整状态时,我们称这个环境是完全可观测的 (fully observed)。当智能体只能看到一个部分观测时,我们称这个环境是部分可观测的 (partially observed)

强化学习的符号表示有时会把代表状态的符号 $s$ 写在那些严格来说应该写观测符号 $o$的地方。

具体来说,这通常发生在我们讨论智能体如何决定动作时:我们经常在符号中表示动作是基于状态的,而实际上,动作是基于观测的,因为智能体并不能接触到完整的状态。

1. 状态 (State, s)
  • 定义:状态是描述世界完整、真实情况的一组信息。
  • 关键特性:它包含了做出最优决策所需的所有信息。状态 s 具有马尔可夫性质,意思是“未来只与现在有关,与过去无关”。只要你知道当前状态 s,你就不需要知道它是如何到达这个状态的,你已经拥有了预测未来的全部信息。
  • 可以把它想象成“上帝视角”:全知全能,了解环境中的一切。
2. 观测 (Observation, o)
  • 定义:观测是智能体(Agent)在某个时间点能够感知到的环境信息。
  • 关键特性:观测可能是状态的一部分,也可能是状态经过某种处理(比如加了噪声)后的结果。它可能不完整、有噪声、有延迟
  • 可以把它想象成“第一人称视角”:智能体通过自身的传感器(比如摄像头、雷达)看到的世界。

“符号混用”的原因

你引用的那句话指出,我们经常在公式里写策略(policy)是 π(a|s),意思是“在状态 s 下选择动作 a 的概率”。

  • 理论上 (Fully Observable Environments):在一些理想环境中,智能体可以直接获取完整的状态,即 观测 o = 状态 s。这种环境被称为完全可观测的马尔可夫决策过程 (MDP)。在这种情况下,写 π(a|s) 是完全准确的。
  • 实践中 (Partially Observable Environments):在绝大多数现实世界的问题中,智能体无法获取完整的状态,即 观测 o ≠ 状态 s。这种环境被称为部分可观测的马尔可夫决策过程 (POMDP)。在这种情况下,智能体的策略实际上是 π(a|o),因为它只能根据它所观测到的 o 来行动。

那为什么大家还普遍写 π(a|s) 呢?

  1. 简化和传统:MDP 是强化学习的理论基石,其符号系统 (S, A, P, R, γ) 和 π(a|s) 已经成为标准。为了保持理论框架的一致性,即使在部分可观测的情况下,人们也常常沿用这套符号。
  2. 隐含的假设:有时候,作者默认读者理解,这里的 s 指的是“智能体用于决策的输入”,也就是 o。或者,他们假设存在一个预处理步骤,能从一系列观测 o 中重建或估计出一个近似的“状态表示”。
  3. 关注点不同:研究的重点可能在于学习算法本身(如 Q-learning、Policy Gradient),而不是感知(Perception)部分。使用 s 可以让大家把注意力集中在核心的决策逻辑上。

举例说明

这部分最能帮你理解。

例子1:国际象棋 (Chess) - 完全可观测 (o = s)
  • 状态 (s):棋盘上每一个棋子的确切位置,以及当前轮到哪一方走棋、是否有王车易位的权利等。这个信息是完整且公开的。
  • 观测 (o):AI 程序能看到的信息和“状态 s”是完全一样的。它能看到整个棋盘。
  • 结论:在这个场景下,o = s。所以,当我们说 AI 的策略是 π(a|s) 时,这是完全正确的。AI 根据完整的棋盘状态来决定下一步棋。
例子2:自动驾驶汽车 - 部分可观测 (o ≠ s)
  • 状态 (s):这是“上帝视角”的真实情况。包括:
    • 你的车和其他所有车辆的精确位置、速度、加速度、朝向。
    • 所有行人的精确位置和意图(比如他是否准备过马路)。
    • 路面的摩擦系数(是否有结冰或积水)。
    • 交通信号灯的内部状态(比如它还有几秒变红)。
  • 观测 (o):这是自动驾驶汽车通过传感器获得的“第一人称视角”信息。包括:
    • 摄像头捕捉到的像素图像。
    • 激光雷达 (LiDAR) 返回的点云数据。
    • 毫米波雷达检测到的障碍物距离和速度(可能有误差)。
    • GPS 定位信息(有误差)。
  • 结论:很明显,o ≠ s。
    • 摄像头图像只是真实世界的一个二维投影,可能会被遮挡(比如一辆卡车挡住了后面的小汽车)。
    • AI 无法直接知道其他司机的驾驶意图,只能通过他们的驾驶行为(观测)来推断。
    • AI 无法知道路面下是否结冰,只能通过轮胎打滑(观测)来感知。

在这种情况下,自动驾驶汽车的策略实际上是 π(a|o),它根据摄像头、雷达等传感器数据来决定是加速、刹车还是转向。但是,在一篇关于自动驾驶强化学习的论文中,为了简化,作者可能仍然会写“汽车的策略是 π(a|s)”,这是一种被广泛接受的“不严谨”的写法。

例子3:德州扑克
  • 状态 (s):你手里的牌 + 对手手里的牌 + 牌堆里剩下的牌。
  • 观测 (o):你手里的牌 + 公共牌 + 对手的下注行为。你看不见对手的牌和牌堆。
  • 结论:o ≠ s。你的决策 π(a|o) 必须基于不完整的信息,你需要根据对手的下注(观测)来猜测他可能持有的牌(状态的一部分)。

总结

特征状态 (State, s)观测 (Observation, o)
视角上帝视角 (God’s-eye view)智能体视角 (Agent’s-eye view)
信息完整、真实、无噪声可能不完整、有噪声、被遮挡
理论模型MDP (马尔可夫决策过程)POMDP (部分可观察马尔可夫决策过程)
决策依据理论上的最优决策依据 π(a|s)实践中的实际决策依据 π(a|o)
例子棋类游戏、模拟器内部数据机器人(摄像头)、自动驾驶、扑克牌

动作空间 (Action Spaces)

不同的环境允许不同种类的动作。在特定环境中所有有效动作的集合通常被称为动作空间 (action space)。像雅达利(Atari)和围棋(Go)这类环境,拥有离散动作空间 (discrete action spaces),其中智能体只有有限数量的动作可选。而其他环境,比如智能体在物理世界中控制一个机器人,则拥有连续动作空间 (continuous action spaces)。在连续空间中,动作是实值向量。


这种区别对深度强化学习的方法有着相当深远的影响。有些算法家族只能直接应用于其中一种情况,而要用于另一种情况则需要进行大量的改造。

策略 (Policies)

策略 (policy) 是智能体用来决定采取什么动作的规则。它可以是确定性的,此时通常用 $\mu$ 来表示:

$$ a_t = \mu(s_t) $$

或者它也可以是随机的,此时通常用 $\pi$ 来表示:

$$ a_t \sim \pi(\cdot|s_t) $$

区别:直接输出一个动作 | 输出一个概率分布

因为策略本质上是智能体的“大脑”,所以用“策略”这个词来替代“智能体”并不少见,例如说“这个策略正在试图最大化奖励”。

在深度强化学习中,我们处理的是参数化策略 (parameterized policies):这些策略的输出是依赖于一组参数(例如神经网络的权重和偏置)的可计算函数,我们可以通过某种优化算法来调整这些参数以改变其行为。

我们通常用 $\theta$或$\phi$来表示策略的参数,然后将其作为策略符号的下标来强调这种联系:

$$ a_t = \mu_\theta(s_t) $$$$ a_t \sim \pi_\theta(\cdot|s_t) $$

确定性策略

例子:确定性策略。 这里有一个代码片段,展示了如何使用 PyTorch 中的 torch.nn 包为一个连续动作空间构建一个简单的确定性策略:

pi_net = nn.Sequential(
    nn.Linear(obs_dim, 64),
    nn.Tanh(),
    nn.Linear(64, 64),
    nn.Tanh(),
    nn.Linear(64, act_dim)
)

这段代码构建了一个多层感知机(MLP)网络,它有两个大小为64的隐藏层和 tanh 激活函数。如果 obs 是一个包含一批观测的 Numpy 数组,pi_net 可以像下面这样用来获取一批动作:

obs_tensor = torch.as_tensor(obs, dtype=torch.float32)
actions = pi_net(obs_tensor)

随机策略

在深度强化学习中,两种最常见的随机策略是分类策略 (categorical policies)对角高斯策略 (diagonal Gaussian policies)

分类策略可用于离散动作空间,而对角高斯策略用于连续动作空间。

对于使用和训练随机策略来说,有两个关键计算至关重要:

  • 从策略中采样动作
  • 计算特定动作的对数似然 (log likelihoods),即 $\log \pi_\theta(a|s)$。

接下来,我们将描述如何为分类策略和对角高斯策略完成这两项工作。

分类策略 (Categorical Policies)

一个分类策略就像一个针对离散动作的分类器。你构建分类策略的神经网络的方式与构建分类器的方式相同:输入是观测,接着是若干层(可能是卷积层或全连接层,取决于输入类型),然后你有一个最终的线性层,它为每个动作输出logits,最后通过一个 softmax 函数将 logits 转换为概率。

采样 (Sampling)。给定每个动作的概率,像 PyTorch 和 Tensorflow 这样的框架都有内置的工具来进行采样。例如,可以查看 PyTorch 中的 Categorical 分布、torch.multinomial,或者 Tensorflow 中的 tf.distributions.Categoricaltf.multinomial 的文档。

AI 不会每次都选择概率最高的动作(那样就是确定性策略了)。对于随机策略,它会根据这个概率分布进行采样

这就像一个有4个扇区的轮盘:

  • “向右”扇区占了71%的面积。
  • “向左”扇区占了18%。
  • …以此类推。

AI “转动”这个轮盘,指针停在哪,就执行哪个动作。虽然“向右”的概率最大,但AI仍然有较小的可能选择向左,甚至向上或向下。这种探索性是强化学习的关键。

对数似然 (Log-Likelihood)。我们将最后一层的概率表示为 $P_\theta(s)$。它是一个向量,其条目数与动作数量相同,因此我们可以将动作视为该向量的索引。那么,一个动作 $a$ 的对数似然可以通过索引该向量得到:

$$ \log \pi_\theta(a|s) = \log [P_\theta(s)]_a $$

对角高斯策略 (Diagonal Gaussian Policies)

一个多元高斯分布(或者如果你喜欢,也可以叫多元正态分布)由一个均值向量 $\mu$ 和一个协方差矩阵 $\Sigma$描述。一个对角高斯分布是协方差矩阵仅在对角线上有非零项的特例。因此,我们可以用一个向量来表示它。

1. 什么是多元高斯分布(Multivariate Gaussian Distribution)?

你可能已经熟悉一维(单变量)正态分布:它由均值 $\mu$ 和方差 $\sigma^2$ 完全确定,其概率密度函数呈钟形。
那么,当你面对多个随机变量(比如一个向量 $\mathbf{x} = [x_1, x_2, \dots, x_d]^\top$)时,如何描述它们联合服从的“正态”分布?

思考:在一维中,方差衡量的是变量围绕均值的“离散程度”。在多维中,我们不仅关心每个变量自身的离散程度,还关心变量之间是否相关。你觉得该如何推广“方差”这个概念?

答案就是:协方差矩阵 $\boldsymbol{\Sigma}$

因此,多元高斯分布由两个参数完全刻画:

  • 均值向量 $\boldsymbol{\mu} \in \mathbb{R}^d$:每个维度的期望值;
  • 协方差矩阵 $\boldsymbol{\Sigma} \in \mathbb{R}^{d \times d}$:对称、半正定矩阵,其中:
    • 对角线元素 $\Sigma_{ii} = \mathrm{Var}(x_i)$ 是第 $i$ 个变量的方差;
    • 非对角线元素 $\Sigma_{ij} = \mathrm{Cov}(x_i, x_j)$ 衡量 $x_i$ 与 $x_j$ 的线性相关性。

其概率密度函数为:

$$ > p(\mathbf{x}) = \frac{1}{(2\pi)^{d/2} |\boldsymbol{\Sigma}|^{1/2}} \exp\left( -\frac{1}{2} (\mathbf{x} - \boldsymbol{\mu})^\top \boldsymbol{\Sigma}^{-1} (\mathbf{x} - \boldsymbol{\mu}) \right) > $$
2. 什么是对角高斯分布(Diagonal Gaussian Distribution)?

现在考虑一种简化情形:假设各个维度之间互不相关(即协方差为零)。这意味着协方差矩阵 $\boldsymbol{\Sigma}$ 的非对角线元素全为 0。

思考:如果两个变量不相关,在高斯分布下,它们是否独立?(提示:对于高斯分布,不相关 $\Leftrightarrow$ 独立)

此时,协方差矩阵变成:

$$ > \boldsymbol{\Sigma} = > \begin{bmatrix} > \sigma_1^2 & 0 & \cdots & 0 \\ > 0 & \sigma_2^2 & \cdots & 0 \\ > \vdots & \vdots & \ddots & \vdots \\ > 0 & 0 & \cdots & \sigma_d^2 > \end{bmatrix} > $$

也就是说,$\boldsymbol{\Sigma}$ 完全由其对角线上的方差值决定。于是我们可以用一个向量 $\boldsymbol{\sigma}^2 = [\sigma_1^2, \sigma_2^2, \dots, \sigma_d^2]^\top$(或标准差向量 $\boldsymbol{\sigma}$)来表示这个分布,而无需存储整个 $d \times d$ 矩阵。

这种分布就叫对角高斯分布(Diagonal Gaussian),它是多元高斯的一个特例,假设各维度独立

一个对角高斯策略总是有一个神经网络,它从观测映射到均值动作 (mean actions),$\mu_\theta(s)$。协方差矩阵通常有两种不同的表示方式。

第一种方式: 存在一个单一的对数标准差向量 $\log \sigma$,它是状态的函数$\log \sigma$是独立的参数。(你需要知道:我们在 VPG、TRPO 和 PPO 的实现中就是这么做的。)

第二种方式: 存在一个神经网络,它从状态映射到对数标准差 $\log \sigma_\theta(s)$。它可能会与均值网络共享一些层。

请注意,在这两种情况下,我们都输出对数标准差而不是标准差本身。这是因为对数标准差的取值范围是 $(-\infty, \infty)$,而标准差必须是非负的。如果你不必强制执行这类约束,训练参数会更容易。通过对对数标准差进行指数运算,我们可以立即获得标准差,所以我们通过这种表示方式没有损失任何东西。

采样 (Sampling)。给定均值动作 $\mu_\theta(s)$ 和标准差 $\sigma_\theta(s)$,以及一个来自球面高斯分布($z \sim \mathcal{N}(0, I)$)的噪声向量 $z$,一个动作样本可以通过以下方式计算:

$$ a = \mu_\theta(s) + \sigma_\theta(s) \odot z $$

其中 $\odot$ 表示两个向量的逐元素乘积。标准的框架有内置的方法来生成噪声向量,例如 torch.normaltf.random_normal。或者,你可以构建分布对象,例如通过 torch.distributions.Normaltf.distributions.Normal,并使用它们来生成样本。(后一种方法的好处是,这些对象也可以为你计算对数似然。)

对数似然 (Log-Likelihood)。一个 $k$ 维动作 $a$,对于一个均值为 $\mu = \mu_\theta(s)$ 且标准差为 $\sigma = \sigma_\theta(s)$ 的对角高斯分布,其对数似然由以下公式给出:

$$ \log \pi_\theta(a|s) = - \frac{1}{2} \left( \sum_{i=1}^{k} \left( \frac{(a_i - \mu_i)^2}{\sigma_i^2} + 2 \log \sigma_i \right) + k \log 2\pi \right) $$

轨迹 (Trajectories)

一个轨迹(trajectory) $\tau$ 是世界中一系列的状态和动作序列,

$$ \tau = (s_0, a_0, s_1, a_1, \dots) $$

世界的最初状态 $s_0$ 是从起始状态分布 (start-state distribution) 中随机抽样的,有时用 $\rho_0$表示:

$$ s_0 \sim \rho_0(\cdot) $$

状态转移(即在时间 $t$ 的状态 $s_t$ 和时间 $t+1$ 的状态 $s_{t+1}$ 之间发生的事情)由环境的自然法则决定,并且只依赖于最近的动作 $a_t$。它们可以是确定性的,

$$ s_{t+1} = f(s_t, a_t) $$

也可以是随机的,

$$ s_{t+1} \sim P(\cdot|s_t, a_t) $$

核心符号:P(·|…) (概率分布) P 不像函数 f 那样只给出一个答案。P 给出的是一张**“可能结果的清单以及它们各自的概率”。我们之前已经讨论过,这里的 · (点) 是一个占位符,意味着 $P(·|s_t, a_t) $代表了在给定 $s_t$ 和$ a_t$ 的情况下,所有可能的下一个状态的完整概率分布**。

动作来自于智能体依据其策略的决策。

奖励和回报 (Reward and Return)

奖励函数 $R$在强化学习中至关重要。它取决于世界的当前状态、刚刚采取的动作以及世界的下一个状态:

$$ r_t = R(s_t, a_t, s_{t+1}) $$

尽管通常这被简化为仅依赖于当前状态 $r_t = R(s_t)$,或状态-动作对 $r_t = R(s_t, a_t)$。

1. 最完整的形式: $r_t = R(s_t, a_t, s_{t+1})$

  • 含义: 这一步的奖励,取决于你从哪个状态 s_t 开始做了什么动作 a_t,最终到达了哪个新状态 s_{t+1}
  • 例子 (机器人导航):
    • s_t = 在A点
    • a_t = 向前走
    • s_{t+1} = 到达B点(目标)
    • 奖励 $r_t = +100$ (因为你从A点出发,通过“向前走”这个动作,成功到达了目标B点)
    • 如果 s_{t+1} 是撞墙,奖励可能就是 -10。
    • 这里的奖励是“事后诸葛亮”,它在你到达新状态之后才能确定。

2. 简化形式一: $r_t = R(s_t, a_t)$

  • 含义: 奖励只取决于你在某个状态 s_t 做了某个动作 a_t。你将要去哪里并不直接影响这次的奖励。
  • 例子 (能源消耗):
    • s_t = 任何状态
    • a_t = 机器人全力加速
    • 奖励 $r_t = -5$ (因为“全力加速”这个动作本身会消耗大量能源,所以给予一个负奖励,与最终到达哪里无关)。
    • 这里的奖励在你做出动作的那一刻就确定了。

3. 简化形式二: $$r_t = R(s_t)$$

  • 含义: 奖励只取决于你当前处于哪个状态 s_t。你做了什么动作或者要去哪里都不重要。
  • 例子 (走迷宫):
    • s_t = 迷宫中的“陷阱”格子
    • 奖励 $r_t = -50$ (只要你待在这个格子上,就会持续受到惩罚)。
    • s_t’ = 迷宫中的“终点”格子
    • 奖励 $r_t' = +1000$ (只要你处于终点状态,就获得巨大奖励)。
    • 这里的奖励是你进入某个状态后,环境立刻给予的。

总结一下“奖励”: 奖励 $r_t$ 是一个标量值,是环境在时间步 t 给予智能体的即时反馈。它评估的是一个非常短期的行为

智能体的目标是最大化在一条轨迹上的某种累计奖励的概念,但这实际上可能意味着几件事。我们会用 $R(\tau)$ 来表示所有这些情况,具体是哪种情况要么从上下文中可以清楚看出,要么就是无关紧要的(因为相同的方程适用于所有情况)。

一种回报是有限期无折扣回报 (finite-horizon undiscounted return),它就是在一个固定时间窗口内的奖励总和:

$$ R(\tau) = \sum_{t=0}^{T} r_t $$

另一种回报是无限期折扣回报 (infinite-horizon discounted return),它是智能体获得的所有奖励的总和,但会根据奖励在未来的遥远程度进行折扣。这种奖励的表达形式包含一个折扣因子 $\gamma \in (0, 1)$:

$$ R(\tau) = \sum_{t=0}^{\infty} \gamma^t r_t $$

不过,我们为什么要用折扣因子呢?我们不就是想要得到所有的奖励吗?是的,我们是这么想的,但折扣因子在直觉上和数学上都很有吸引力且方便。从直觉上看:现在的现金比未来的现金更有价值。从数学上看:一个无限期的奖励总和可能不会收敛到一个有限值,这在方程中很难处理。但有了折扣因子,并且在合理的条件下,这个无限和是会收敛的。

1. 有限期无折扣回报: $R(\tau) = \sum_{t=0}^{T} r_t$

  • 含义: 把从现在开始,未来 T 步内你将收到的所有奖励简单地加起来。
  • 例子: 在一个持续100秒的游戏中,你的总得分就是这100秒内每一秒得分的简单总和。
  • 直觉: “未来每一块钱都和现在的一块钱同样重要”。

2. 无限期折扣回报: $R(\tau) = \sum_{t=0}^{\infty} \gamma^t r_t$

  • 含义: 这更复杂也更常用。它也是把未来的所有奖励加起来,但在相加之前,要给未来的奖励打个折扣
    • 下一秒的奖励,价值是 $γ \times r_{t+1}$
    • 再下一秒的奖励,价值是 $γ^2 \times r_{t+2}$
    • γ (gamma) 是一个0到1之间的小数,比如0.99。
  • 例子:
    • 立刻获得100分,它的价值就是 100
    • 1秒后获得100分,它的价值是 $0.99 \times 100 = 99$。
    • 2秒后获得100分,它的价值是 $0.99^2 \times 100 \approx 98$。
    • 100秒后获得的100分,它的价值只剩下 $0.99^{100} \times 100 \approx 36.6$。
  • 直觉: “现在的现金比未来的现金更有价值”。眼前的奖励比遥远的未来才能获得的奖励更重要、更确定。这种机制促使智能体尽快获得奖励。
  • 奖励 (r_t) 是对刚刚过去的一步(从 s_t 到 s_{t+1})的即时评价。它的计算方式可以很灵活(如上所述的三种形式),但它始终是一个单步的、当下的反馈
  • 回报 (R(τ)) 是对未来所有奖励的一个累计和,它代表了长期的总价值
  • 智能体的优化目标 不是最大化即时奖励 r_t,而是最大化期望的长期回报 E[R(τ)]。它通过观察即时的 r_t 来学习如何做出能导向高回报的决策。它必须学会平衡眼前利益和长远目标

强化学习问题 (The RL Problem)

无论选择哪种回报度量(无论是无限期折扣的,还是有限期无折扣的),也无论选择哪种策略,强化学习的目标都是选择一个策略,使得当智能体按照它行动时,能最大化期望回报 (expected return)

为了谈论期望回报,我们首先需要讨论轨迹的概率分布。

假设环境的转移和策略都是随机的。在这种情况下,一个长度为 $T$的轨迹的概率是:

$$ P(\tau|\pi) = \rho_0(s_0) \prod_{t=0}^{T-1} P(s_{t+1}|s_t, a_t) \pi(a_t|s_t) $$

没有使用后验概率相乘原因:

在马尔可夫决策过程(MDP)的框架下,我们做了一个非常重要的条件独立性假设

  1. 智能体的决策 (a_t) 只依赖于当前状态 (s_t)。它不依赖于过去的状态、动作,也不依赖于环境将要做出的反应。策略 π(a_t|s_t) 已经完全捕捉了决策过程。
  2. 环境的响应 (s_{t+1}) 只依赖于当前状态 (s_t) 和刚刚发生的动作 (a_t)。它不依赖于智能体的“内心想法”(即策略 π 本身),也不依赖于更早的历史。环境只是根据物理法则对发生的动作做出反应。

期望回报(对于任何一种度量),用 $J(\pi)$ 表示,则是:

$$ J(\pi) = \int_{\tau} P(\tau|\pi)R(\tau) = \mathbb{E}_{\tau \sim \pi}[R(\tau)] $$

强化学习的核心优化问题可以表示为:

$$ \pi^* = \arg\max_{\pi} J(\pi) $$

其中 $\pi^*$ 是最优策略 (optimal policy)


价值函数 (Value Functions)

了解一个状态或状态-动作对的价值 (value) 通常很有用。我们所说的价值,是指如果你从那个状态或状态-动作对开始,然后永远遵循某个特定策略行动,你所能获得的期望回报。价值函数 (Value functions) 以某种形式,在几乎所有的强化学习算法中都会被用到。

这里有四个值得注意的主要函数。

  1. 同策略价值函数 (On-Policy Value Function), $V^\pi(s)$,它给出了如果你从状态 $s$ 开始,并始终按照策略 $\pi$ 行动所能获得的期望回报:

    $$ V^\pi(s) = \mathbb{E}_{\tau \sim \pi}[R(\tau) | s_0 = s] $$

    它评估的是一个状态的整体“好坏”程度,是基于策略 π 的一种平均预期

  2. 同策略动作价值函数 (On-Policy Action-Value Function), $Q^\pi(s, a)$,它给出了如果你从状态 $s$开始,采取一个任意的动作 $a$(这个动作可能并非来自策略),然后永远按照策略 $\pi$ 行动所能获得的期望回报:

    $$ Q^\pi(s, a) = \mathbb{E}_{\tau \sim \pi}[R(\tau) | s_0 = s, a_0 = a] $$

    它评估的是在一个特定状态下,采取一个特定动作的好坏程度。

  3. 最优价值函数 (Optimal Value Function), $V^*(s)$,它给出了如果你从状态 $s$ 开始,并始终在环境中遵循最优策略行动所能获得的期望回报:

    $$ V^*(s) = \max_{\pi} \mathbb{E}_{\tau \sim \pi}[R(\tau) | s_0 = s] $$
  4. 最优动作价值函数 (Optimal Action-Value Function), $Q^*(s, a)$,它给出了如果你从状态 $s$开始,采取一个任意的动作 $a$,然后永远在环境中遵循最优策略行动所能获得的期望回报:

    $$ Q^*(s, a) = \max_{\pi} \mathbb{E}_{\tau \sim \pi}[R(\tau) | s_0 = s, a_0 = a] $$

最优Q函数与最优动作 (The Optimal Q-Function and the Optimal Action)

最优动作价值函数 $Q^*(s, a)$ 和最优策略选择的动作之间有一个重要的联系。根据定义,$Q^*(s, a)$ 给出了从状态 $s$ 开始,采取(任意)动作 $a$,然后永远遵循最优策略行动的期望回报。

在状态 $s$ 中的最优策略会选择任何能够最大化从 $s$ 开始的期望回报的动作。因此,如果我们有 $Q^*$,我们就可以直接通过以下方式获得最优动作 $a^*(s)$:

$$ a^*(s) = \arg\max_a Q^*(s, a) $$

注意:可能存在多个动作都能最大化 $Q^*(s, a),在这种情况下,所有这些动作都是最优的,最优策略可能会随机选择其中任何一个。但总会有一个最优策略是确定性地选择一个动作的。

贝尔曼方程 (Bellman Equations)

所有四个价值函数都遵循一种特殊的自洽方程,称为贝尔曼方程 (Bellman equations)。贝尔曼方程背后的基本思想是:

你起点位置的价值,等于你从那里立即获得的奖励,加上你接下来到达任何地方的价值。

1. “你从那里立即获得的奖励” (Immediate Reward)
  • 含义: 这是你迈出下一步就能立刻得到的好处。
  • 比喻:
    • 在从 A 走到 B 的路上(这代表动作 a_1),你捡到了一个银币,价值 +3。这个 +3 就是立即奖励 r(A, a_1)
    • 在从 A 走到 C 的路上(动作 a_2),你踩到了一个捕兽夹,受伤了,价值 -5。这个 -5 就是立即奖励 r(A, a_2)
2. “加上你接下来到达任何地方的价值” (Value of the Next State)
  • 含义: 这是你到达下一个格子后,从那个新起点出发所能获得的未来所有宝藏的总和。
  • 比喻:
    • 假设你通过某种方式(比如问先知)已经知道了 $V(B)$(从B点出发能得到的总宝藏)是 +50。
    • 你也知道了 $V(C)$(从C点出发能得到的总宝藏)是 +80。

对于同策略价值函数的贝尔曼方程是:

$$ V^\pi(s) = \mathbb{E}_{a \sim \pi, s' \sim P}[r(s, a) + \gamma V^\pi(s')] $$$$ Q^\pi(s, a) = \mathbb{E}_{s' \sim P}[r(s, a) + \gamma \mathbb{E}_{a' \sim \pi}[Q^\pi(s', a')]] $$

其中 $s' \sim P$ 是 $s' \sim P(\cdot|s, a)$ 的简写,表示下一个状态 $s'$是从环境的转移规则中抽样的;$a \sim \pi$是 $a \sim \pi(\cdot|s)$ 的简写;而 $a' \sim \pi$` 是 $a' \sim \pi(\cdot|s')$ 的简写。

对于最优价值函数的贝尔曼方程是:

$$ V^*(s) = \max_{a} \mathbb{E}_{s' \sim P}[r(s, a) + \gamma V^*(s')] $$$$ Q^*(s, a) = \mathbb{E}_{s' \sim P}[r(s, a) + \gamma \max_{a'} Q^*(s', a')] $$

同策略价值函数的贝尔曼方程与最优价值函数的贝尔曼方程之间的关键区别,在于是否存在对动作的 $\max$ 操作。它的存在反映了这样一个事实:无论何时智能体有机会选择其动作,为了最优地行动,它必须选择那个能导向最高价值的动作。

“贝尔曼备份”(Bellman backup)这个术语在强化学习文献中经常出现。对于一个状态或状态-动作对的贝尔曼备份,指的是贝尔曼方程的右侧部分:即奖励加上下一个状态的价值 (reward-plus-next-value)

它是一次局部更新:根据当前对“未来”的估计,修正对“现在”的估计

优势函数 (Advantage Functions)

有时在强化学习中,我们不需要描述一个动作在绝对意义上有多好,而只需要知道它比平均水平好多少。也就是说,我们想知道那个动作的相对优势 (relative advantage)。我们用优势函数 (advantage function) 来精确地定义这个概念。

对应于策略 $\pi$ 的优势函数 $A^\pi(s, a)$ 描述了在状态$s$ 中采取特定动作 $a$,比随机按照 $\pi(\cdot|s)$ 选择一个动作要好多少,前提是你之后永远按照策略 $\pi$ 行动。在数学上,优势函数定义为:

$$ A^\pi(s, a) = Q^\pi(s, a) - V^\pi(s) $$

形式化定义

到目前为止,我们一直以一种非正式的方式讨论智能体的环境,但如果你去深入研究文献,你很可能会遇到这个场景的标准数学形式化定义:马尔可夫决策过程 (Markov Decision Processes, MDPs)。一个MDP是一个五元组 $(S, A, R, P, \rho_0)$,其中:

  • $S$ 是所有有效状态的集合,
  • $A$是所有有效动作的集合,
  • $R: S \times A \times S \to \mathbb{R}$ 是奖励函数,其中 $r_t = R(s_t, a_t, s_{t+1})$,
  • $P: S \times A \to \mathcal{P}(S)$ 是转移概率函数,其中 $P(s'|s, a)$ 是指如果你在状态 $s$采取动作 $a$,转移到状态 $s'$ 的概率,
  • 而 $\rho_0$ 是起始状态分布。

马尔可夫决策过程这个名字指的是系统遵循马尔可夫性质 (Markov property):转移只依赖于最近的状态和动作,而与之前的历史无关。