Contents

强化学习入门:使用近端策略优化(PPO)求解倒立摆问题

摘要

本文旨在从理论层面深入探讨强化学习(Reinforcement Learning, RL)的运作机制。我们以经典的**倒立摆(CartPole-v1)**环境为例,首先将其形式化为马尔可夫决策过程(Markov Decision Process, MDP),然后详细阐述策略梯度(Policy Gradient)方法的基础,并最终推导出现今最稳定和常用的算法之一——近端策略优化(Proximal Policy Optimization, PPO)。每一部分理论都将与Python(PyTorch)代码实现紧密结合,展示理论公式在实践中的落地。


1. 形式化框架:马尔可夫决策过程 (MDP)

强化学习的数学基础是马尔可夫决策过程。一个MDP由五元组 $(\mathcal{S}, \mathcal{A}, P, R, \gamma)$ 定义:

  • 状态空间 $\mathcal{S}$ (State Space):环境所有可能状态的集合。在CartPole中,一个状态 $s \in \mathcal{S}$ 是一个四维向量:
[s_小车位置, s_小车速度, s_杆子角度, s_杆尖速度]

对应 env.observation_space

  • 动作空间 $\mathcal{A}$ (Action Space):智能体可以执行的动作集合。在CartPole中,动作是离散的:
[0 (向左推), 1 (向右推)]

对应 env.action_space

  • 转移概率 $P(s’ | s, a)$:在状态 $s$ 执行动作 $a$ 后转移到状态 $s’$ 的概率。无模型强化学习中,这通常未知,通过与环境交互采样得到。

  • 奖励函数 $R(s, a, s’)$:在状态 $s$ 执行动作 $a$ 转移到 $s’$ 后获得的即时奖励。在CartPole中,杆子未倒每步奖励 +1。

  • 折扣因子 $\gamma \in [0,1]$:权衡即时奖励与未来奖励的重要性,对应代码超参数 gamma

1.1 策略与目标

智能体的行为由策略 $\pi$ 定义,即从状态到动作的映射。在深度强化学习中,使用参数 $\theta$ 的神经网络表示策略:

$$ \pi_\theta(a|s) = \text{Pr}(a_t = a \mid s_t = s, \theta) $$

强化学习的目标是找到最优策略 $\pi^*$,最大化从初始状态开始的期望累计折扣奖励:

$$ J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \Big[ G_0 \Big] = \mathbb{E}_{\tau \sim \pi_\theta} \Big[ \sum_{t=0}^{T} \gamma^t R(s_t, a_t, s_{t+1}) \Big] $$

其中 $\tau = (s_0, a_0, r_1, s_1, …)$ 是一条轨迹,$G_0$ 是初始回报。

代码对应:

self.actor_head = nn.Linear(64, action_dim)
action_probs = torch.softmax(self.actor_head(x), dim=-1)  # π_θ(a|s)

2. 策略梯度方法 (Policy Gradient Methods)

策略梯度方法直接对参数 $\theta$ 进行梯度上升优化策略。根据策略梯度定理:

$$ \nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \Big[ \sum_{t=0}^{T} \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot G_t \Big] $$

其中

$$ G_t = \sum_{k=t}^{T} \gamma^{k-t} r_{k+1} $$

是从时间步 $t$ 开始的累计折扣回报。

  • $\nabla_\theta \log \pi_\theta(a_t|s_t)$:得分函数,指示参数 $\theta$ 应如何调整,使动作 $a_t$ 的概率上升。
  • $G_t$:权重,回报越高梯度更新幅度越大。

代码对应:

log_prob = dist.log_prob(action)
loss = -log_prob * G_t
loss.backward()

2.1 基线与优势函数

为减小方差,引入基线 $b(s_t)$,通常取状态值函数 $V^\pi(s_t)$。优势函数定义为:

$$ A^\pi(s_t, a_t) = Q^\pi(s_t, a_t) - V^\pi(s_t) $$

代码对应:

advantages = rewards - state_values.detach()  # A(s_t, a_t)

3. 近端策略优化 (PPO) 算法

普通策略梯度对学习率敏感,容易破坏策略。PPO通过裁剪目标函数实现稳定更新。

定义概率比:

$$ r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)} $$

代码对应:

ratios = torch.exp(logprobs - old_logprobs.detach())  # r_t(θ)

3.1 裁剪目标函数

$$ L^{CLIP}(\theta) = \mathbb{E}_t \Big[ \min\big( r_t(\theta) \hat{A}_t, \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) \hat{A}_t \big) \Big] $$

  • $\hat{A}_t$:优势函数
  • $\epsilon$:裁剪范围(如 0.2)

代码对应:

surr1 = ratios * advantages
surr2 = torch.clamp(ratios, 1-self.eps_clip, 1+self.eps_clip) * advantages
policy_loss = -torch.min(surr1, surr2).mean()

3.2 完整损失函数

PPO最终目标函数结合策略损失、价值函数损失和熵奖励:

$$ L_t(\theta) = L_t^{CLIP}(\theta) + c_1 (V_\theta(s_t) - G_t)^2 - c_2 S[\pi_{\theta}](s_t) $$

  • $V_\theta(s_t)$:Critic预测值
  • $G_t$:实际回报
  • $S[\pi_\theta](s_t)$:策略熵,用于鼓励探索

代码对应:

value_loss = 0.5 * self.MseLoss(state_values, rewards)
entropy_bonus = -0.01 * dist_entropy
loss = policy_loss + value_loss + entropy_bonus

loss.backward()
self.optimizer.step()

4. 结论

本文从马尔可夫决策过程出发,推导了策略梯度方法,最终构建PPO算法。每个理论组件——策略 $\pi_\theta(a|s)$、值函数 $V(s)$、优势函数 $A(s,a)$、PPO裁剪目标——都与PyTorch代码实现一一对应。

这种“从理论到代码”的结合揭示了强化学习本质:通过与环境交互和梯度优化,智能体逐步掌握解决复杂任务的能力。