强化学习:什么是PPO算法
PPO(Proximal Policy Optimization,近端策略优化) 算法是深度强化学习里非常重要的一类 策略梯度(Policy Gradient) 方法,被广泛应用于游戏智能体、机器人控制等场景。
1. 背景与问题
在强化学习(RL)中,我们有一个智能体(agent)与环境交互:
- 状态 $s_t$
- 动作 $a_t$
- 奖励 $r_t$
- 策略 $\pi_\theta(a|s)$:给定状态选择动作的概率分布,参数化为 $\theta$
目标是最大化期望回报:
$$ J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \Big[ \sum_{t=0}^T \gamma^t r_t \Big] $$
传统的 策略梯度方法(如 REINFORCE)会直接用蒙特卡洛方法估计梯度更新策略,但存在:
- 方差很大(更新不稳定)
- 更新过大可能导致策略崩溃
于是提出 TRPO(Trust Region Policy Optimization),它通过约束新旧策略的 KL 散度,避免更新过大。但是 TRPO 实现复杂,需要解约束优化问题。
PPO 就是对 TRPO 的简化,保留稳定性,又方便实现。
2. PPO 的核心思想
核心目标:在更新策略时,不要让新策略和旧策略差别过大。
定义 概率比值:
$$ r_t(\theta) = \frac{\pi_\theta(a_t | s_t)}{\pi_{\theta_{\text{old}}}(a_t | s_t)} $$
- 如果 $r_t(\theta) > 1$,表示新策略更倾向于采取这个动作。
- 如果 $r_t(\theta) < 1$,表示新策略更不倾向于这个动作。
我们希望提升 优势函数(Advantage Function):
$$ A_t = Q(s_t, a_t) - V(s_t) $$
表示在状态 $s_t$ 下,采取动作 $a_t$ 比平均水平好多少。
3. PPO 的目标函数
PPO 提出了 Clipped Surrogate Objective(裁剪代理目标):
$$ L^{CLIP}(\theta) = \mathbb{E}_t \Big[ \min \big( r_t(\theta) A_t, \ \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) A_t \big) \Big] $$
解释:
- 第一项:和普通策略梯度类似,鼓励动作优势大时增加概率。
- 第二项:限制更新幅度,如果 $r_t(\theta)$ 偏离 $[1-\epsilon, 1+\epsilon]$ 太远,就把它裁剪回去,避免更新过大。
- 最终取 min,即“宁可保守更新,也不要过大更新”。
这样就实现了类似 TRPO 的“信任域”效果,但更简单。
4. PPO 的训练步骤
采样数据:用旧策略 $\pi_{\theta_{\text{old}}}$ 跑一批轨迹,收集 $(s_t, a_t, r_t)$。
估计优势函数: 常用 GAE(Generalized Advantage Estimation),平衡偏差和方差:
$$ A_t = \sum_{l=0}^\infty (\gamma \lambda)^l \delta_{t+l}, \quad \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) $$
优化目标:最大化 $L^{CLIP}(\theta)$,同时加上 值函数误差和熵正则项:
$$ L(\theta) = L^{CLIP}(\theta) - c_1 (V_\theta(s_t) - R_t)^2 + c_2 H(\pi_\theta(\cdot|s_t)) $$
- 第二项保证价值估计准确
- 第三项增加探索性(熵项)
多次迭代更新:在同一批数据上反复优化几步,然后更新旧策略参数 $\theta_{\text{old}} \leftarrow \theta$。
5. PPO 的优点
✅ 实现简单(相比 TRPO 不需要二阶优化) ✅ 稳定收敛(限制策略更新幅度) ✅ 泛化性强(适用于离散动作和连续动作空间) ✅ 在 Atari 游戏、MuJoCo 控制任务上表现优秀(OpenAI 主推算法之一)
6. PPO 在代码里的实现框架(简化版)
for iteration in range(N):
# 1. 用旧策略收集一批数据
states, actions, rewards, dones, log_probs = collect_trajectories(policy_old)
# 2. 计算优势函数 A_t
advantages = compute_gae(rewards, values, dones)
# 3. 更新策略
for _ in range(K_epochs):
r_t = exp(new_log_prob - old_log_prob) # 概率比
surr1 = r_t * advantages
surr2 = torch.clamp(r_t, 1-ε, 1+ε) * advantages
loss = -torch.min(surr1, surr2).mean() + value_loss + entropy_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 4. 更新旧策略
policy_old.load_state_dict(policy.state_dict())7. 总结
PPO 的关键点是:
- 目标函数引入裁剪,避免策略更新过大
- 保守更新,提升稳定性
- 结合值函数和熵正则,平衡学习和探索
因此 PPO 成为了当前最常用、最实用的强化学习算法之一。