前言
本节中,我们使用策略梯度(Policy Gradient)算法解决经典的 CartPole 问题。虽然在这个简单问题中,Q-Learning 等值函数方法可能更为高效,但我们可以使用这个简单问题来更专注地学习策略梯度算法的核心原理,并在之后的学习中利用此算法解决更加复杂的环境。
策略梯度算法原理
策略梯度算法通过记录回合中的所有时间步,并基于回合结束时与这些时间步相关联的奖励来更新权重训练智能体。使智能体遍历整个回合然后基于获得的奖励更新策略的技术称为蒙特卡洛策略梯度(Monte Carlo Policy Gradient)。
在策略梯度算法中,模型权重在每个回合结束时沿梯度方向移动。关于梯度的计算,我们将在后续章节中详细解释。此外,在每一时间步中,基于当前状态和权重计算的概率得到策略,并从中采样一个动作。与随机搜索和爬山算法(通常采取确定性动作以获得更高的得分)相反,它不再确定性地采取动作。因此,策略从确定性转变为随机性。
例如,如果向左的动作和向右的动作的概率为 [0.8, 0.2],则表示有 80% 的概率选择向左的动作,但这并不意味着一定会选择向左的动作。这种随机性有助于智能体探索环境,避免陷入局部最优。
数学推导简述
策略梯度的核心在于最大化期望回报。对于给定的策略参数 θ,我们希望最大化 J(θ) = E[∑r_t]。根据链式法则,我们需要计算损失函数对参数的梯度。
在实现中,我们通常使用 Softmax 函数将线性输出转换为概率分布。Softmax 函数的导数计算较为特殊,对于选定的动作 i,其相对于输入 z_j 的导数为:
∂p_i / ∂z_j = p_i * (1 - p_j), 当 i = j ∂p_i / ∂z_j = -p_i * p_j, 当 i ≠ j
为了简化计算,我们通常关注与选定动作相关的对数导数(Log Derivative Trick),即 d_log = d_softmax[action] / probs[action]。结合链式法则 dy/dx = dy/du * du/dx,我们可以计算出权重的梯度 grad。
使用 PyTorch 实现 CartPole 策略梯度
在本节中,我们将学习使用 PyTorch 实现策略梯度算法。首先导入所需的库,创建 CartPole 环境实例,并计算状态空间和动作空间的尺寸。
import gym
import torch
import matplotlib.pyplot as plt
# 创建环境
env = gym.make('CartPole-v0')
# 获取状态和动作空间维度
n_state = env.observation_space.shape[0]
n_action = env.action_space.n
print(f"State Dimension: {n_state}")
print(f"Action Space: {n_action}")
定义回合模拟函数
定义 run_episode 函数,在此函数中,根据给定输入权重的情况下模拟一回合 CartPole 游戏,并返回奖励和计算出的梯度。在每个时间步中执行以下操作:
- 根据当前状态和输入权重计算两个动作的概率
probs。 - 根据结果概率采样一个动作
action。 - 以概率作为输入计算
softmax函数的导数d_softmax。由于只需要计算与选定动作相关的导数,公式简化为上述推导。 - 将所得的导数
d_softmax除以概率 ,以得到与策略相关的对数导数 。


