强化学习 - 基于策略搜索和策略优化: 高斯策略
最近在做毕设需要用强化学习来做控制,对强化学习的知识点做一下总结。
高斯策略
高斯策略属于强化学习中的基于策略优化的分支(Policy Optimization),尤其是策略梯度方法(Policy Gradient Methods) 的一部分。这一分支专注于通过优化策略的参数来直接提升策略的性能,而不需要显式地学习一个价值函数。
高斯策略在强化学习中的位置
强化学习可以按照以下几个主要分支分类:
-
基于价值函数的方法(Value-Based Methods)
- 如Q-Learning、深度Q网络(DQN)。
- 这些方法学习状态-动作值函数 ( Q(s, a) ),然后通过选择最大值的动作来构建策略。
-
基于策略的方法(Policy-Based Methods)
- 直接对策略进行建模并优化。
- 高斯策略属于这一类方法,特别是策略梯度方法(Policy Gradient Methods),因为它通过优化概率分布(高斯分布)来学习策略。
-
基于策略与价值的混合方法(Actor-Critic Methods)
- 同时学习策略(Actor)和价值函数(Critic),如A3C、DDPG等。
- 虽然高斯策略本身是策略梯度的一部分,但它也经常在这些方法中作为Actor的策略模型使用。
高斯策略与策略梯度的关系
高斯策略是一种经典的连续动作空间中的策略表示形式,其主要特点是将策略建模为一个概率分布(通常是高斯分布):
π
θ
(
a
∣
s
)
=
N
(
μ
θ
(
s
)
,
Σ
θ
(
s
)
)
\pi_{\theta}(a|s) = \mathcal{N}(\mu_{\theta}(s), \Sigma_{\theta}(s))
πθ(a∣s)=N(μθ(s),Σθ(s))
- 均值 μ θ ( s ) \mu_{\theta}(s) μθ(s) 和 协方差 Σ θ ( s ) \Sigma_{\theta}(s) Σθ(s) 是需要学习的策略参数。
- 通过最大化期望累计奖励 J ( θ ) = E π θ [ R ] J(\theta) = \mathbb{E}_{\pi_{\theta}}[R] J(θ)=Eπθ[R]来优化策略。
策略梯度方法的核心公式:
通过策略梯度定理,我们可以计算梯度并优化策略参数:
∇
θ
J
(
θ
)
=
E
π
θ
[
∇
θ
log
π
θ
(
a
∣
s
)
Q
π
(
s
,
a
)
]
\nabla_{\theta} J(\theta) = \mathbb{E}_{\pi_{\theta}} \left[ \nabla_{\theta} \log \pi_{\theta}(a|s) Q^{\pi}(s, a) \right]
∇θJ(θ)=Eπθ[∇θlogπθ(a∣s)Qπ(s,a)]
其中:
- log π θ ( a ∣ s ) \log \pi_{\theta}(a|s) logπθ(a∣s)是高斯分布的对数似然。
- Q π ( s , a ) Q^{\pi}(s, a) Qπ(s,a) 是状态-动作值函数,用于评估策略的表现。
高斯策略在连续动作空间中的广泛应用,得益于高斯分布的可微性和灵活性,适合通过梯度优化调整策略。
高斯策略适用的场景
- 适用场景:
- 机器人控制:如臂式机器人轨迹规划。
- 无人机导航:优化无人机通过动态障碍的策略(如论文中提到的任务)。
- 自动驾驶:优化车辆在连续状态和动作空间中的驾驶策略。
高斯策略的实际应用:Policy Gradient vs Actor-Critic
-
纯策略梯度方法(如REINFORCE):
高斯策略直接使用策略梯度定理更新参数,但容易出现高方差问题。 -
Actor-Critic方法:
高斯策略作为Actor,由Critic(价值函数)提供更稳定的梯度信号,常见于:- 深度确定性策略梯度(DDPG)
- 近端策略优化(PPO)
- 信任区域策略优化(TRPO)
总结
高斯策略属于强化学习的基于策略优化的分支,具体归类为策略梯度方法。它特别适合解决连续动作空间中的任务,并在机器人控制、无人机飞行等领域得到广泛应用。结合其他强化学习算法(如Actor-Critic),高斯策略还能实现更稳定和高效的策略优化。
看一个GPT给的代码,理解高斯策略优化
import time
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import gym
# =========== 1. 创建 Pendulum 环境 ===========
env = gym.make("Pendulum-v1", render_mode="human")
# =========== 2. 定义高斯策略网络 ===========
class GaussianPolicy(nn.Module):
def __init__(self, state_dim, action_dim):
super(GaussianPolicy, self).__init__()
self.fc = nn.Sequential(
nn.Linear(state_dim, 64),
nn.ReLU(),
nn.Linear(64, action_dim)
)
self.log_std = nn.Parameter(torch.zeros(action_dim))
def forward(self, state):
"""
state: [batch_size, state_dim] (例如 [1, 3])
返回:
mean: [batch_size, action_dim]
std: [action_dim] (可广播为 [batch_size, action_dim])
"""
mean = self.fc(state)
std = torch.exp(self.log_std)
return mean, std #前向传播输出的是均值和方差(动作的)
# =========== 3. 初始化策略、优化器 ===========
state_dim = env.observation_space.shape[0] # 3 for Pendulum
action_dim = env.action_space.shape[0] # 1 扭矩
policy = GaussianPolicy(state_dim, action_dim) # model
optimizer = optim.Adam(policy.parameters(), lr=0.01) # 用adam优化器,优化model的参数
# =========== 4. 策略梯度训练 (REINFORCE) ===========
def train(policy, env, episodes=300, gamma=0.99, render=False):
for episode in range(episodes):
state, _ = env.reset()
log_probs = []
rewards = []
total_reward = 0
while True:
# (A) 将状态转换为 [1, state_dim] 的张量
state_t = torch.tensor(state, dtype=torch.float32).unsqueeze(0)
# (B) 前向传播:获取动作分布
mean, std = policy(state_t) # input: current state ; output: mean and std of action
dist = torch.distributions.Normal(mean, std) # 知道均值和方差,就可以直到action的高斯分布了。
# (C) 采样动作,并计算 log_prob
action = dist.sample() # shape: (1, 1) 对动作空间采样
log_prob = dist.log_prob(action).sum(dim=-1) # 计算action的对数概率,为了策略梯度
# (D) 裁剪动作并与环境交互
action_env = action.detach().numpy()[0]
action_env = np.clip(action_env,
env.action_space.low[0],
env.action_space.high[0])
# 执行动作
next_state, reward, terminated, truncated, info = env.step(action_env)
# (E) 保存 log_prob & reward
log_probs.append(log_prob)
rewards.append(reward)
total_reward += reward
state = next_state
if terminated or truncated:
break
# ========== 回合结束:计算回报并更新策略 ==========
returns = []
G = 0
for r in reversed(rewards): # 存放每个时间步的折扣累计奖励
G = r + gamma * G
returns.insert(0, G)
returns = torch.tensor(returns, dtype=torch.float32)
# 标准化回报
returns = (returns - returns.mean()) / (returns.std() + 1e-9)
# REINFORCE 损失
loss = 0
# 对每个时间步的 (log_prob, return) 求和,前面加负号是因为要最大化期望回报,相当于最小化负的期望回报。
for log_p, R in zip(log_probs, returns):
loss -= log_p * R
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 打印训练进度
if (episode + 1) % 50 == 0:
print(f"Episode {episode+1}/{episodes}, Total Reward: {total_reward:.2f}")
env.close()
# =========== 5. 运行训练并渲染 ===========
if __name__ == "__main__":
train(policy, env, episodes=300, render=True)
代码解析
在这行代码里:
dist = torch.distributions.Normal(mean, std)
我们使用了 PyTorch 提供的 概率分布模块(torch.distributions
)来构建一个高斯(正态)分布对象。以下是这句代码背后的原理与作用:
1. 为什么要构建 torch.distributions.Normal(mean, std)
-
表示连续动作策略
在连续动作空间(如倒立摆),我们经常用高斯分布 (\mathcal{N}(\mu, \sigma^2)) 来表示“策略”,其中:- μ \mu μ(mean):动作的均值
- σ \sigma σ(std):动作的标准差
-
进行动作采样
有了这个Normal(mean, std)
对象,就可以用action = dist.sample()
来采样一个连续值的动作
action
,从而在不同状态下能产生随机探索的效果。 -
计算对数概率(log_prob)
在策略梯度强化学习里,需要用对数概率 log π ( a ∣ s ) \log \pi(a|s) logπ(a∣s) 来进行梯度更新。
这个dist
对象提供了dist.log_prob(action)
,可以直接得到对数似然,方便我们实现 REINFORCE、PPO 等算法的损失函数。
3. 原理:高斯分布中的参数
一个一维高斯(正态)分布通常由两个参数决定:
X
∼
N
(
μ
,
σ
2
)
X \sim \mathcal{N}(\mu, \sigma^2)
X∼N(μ,σ2)
- μ \mu μ(mean):分布的均值。
- σ \sigma σ(std):分布的标准差。
**分布的概率密度函数(PDF)**为:
p
(
x
)
=
1
2
π
σ
exp
(
−
(
x
−
μ
)
2
2
σ
2
)
.
p(x) = \frac{1}{\sqrt{2 \pi} \, \sigma} \exp\left( -\frac{(x - \mu)^2}{2 \sigma^2} \right).
p(x)=2πσ1exp(−2σ2(x−μ)2).
在代码中,mean
和 std
就是分别对应 (\mu) 和 (\sigma);因此 torch.distributions.Normal(mean, std)
可以完整表达这个分布。
4. 强化学习中的用法
在许多连续控制的强化学习算法里(如REINFORCE、TRPO、PPO),我们往往直接建模一个高斯策略:
- 网络输出:均值 μ ( s ) \mu(s) μ(s) + 对数标准差 log σ \log \sigma logσ。
- 构造分布:
dist = torch.distributions.Normal(mean, std)
- 采样动作:
action = dist.sample()
- 计算对数概率:
并用于策略梯度:log_prob = dist.log_prob(action)
∇ θ ∑ t log π θ ( a t ∣ s t ) ⋅ G t \nabla_{\theta} \sum_t \log \pi_{\theta}(a_t | s_t) \cdot G_t ∇θt∑logπθ(at∣st)⋅Gt
这样就能在训练时学习到使期望回报最大的分布参数(mean
和 std
),兼顾到探索(由 std
控制)和开销之间的平衡。
小结
dist = torch.distributions.Normal(mean, std)
是在 PyTorch 中创建一个正态(高斯)分布对象。- 通过这个对象可以采样动作和计算对数概率,这是连续动作空间的经典做法。
- 在强化学习中,这种高斯策略能实现探索,并且可通过梯度反向传播来学习 (\mu, \sigma) 等参数,从而自动优化控制策略。
为什么高斯策略最后能够使得policy最优?
在连续动作空间的强化学习中,使用高斯策略(Gaussian Policy)是一种非常常见且有效的做法。核心原因并不在于高斯分布“本质上就能保证全局最优”,而是由于高斯策略作为可微分且可训练的分布形式,能够通过策略梯度方法不断逼近最优策略。下面从几个关键角度解释为什么高斯策略在实践中常能得到很好的(局部)最优策略。
1. 高斯策略的可微性及易于优化
-
连续空间需要可微分的概率分布
- 在连续动作空间(如无人机控制、机械臂操作)中,需要一种能对动作进行可微分采样和可微分对数概率计算的方法。
- 高斯分布 N ( μ , σ 2 ) \mathcal{N}(\mu, \sigma^2) N(μ,σ2)拥有简单的概率密度函数和已知的对数似然形式,使得我们可以用梯度下降来优化 μ \mu μ和 σ \sigma σ。
-
PyTorch支持自动求导
- 通过
torch.distributions.Normal
,可以方便地计算 log π ( a ∣ s ) \log\pi(a|s) logπ(a∣s) 并反向传播到网络参数。 - 这满足了策略梯度的核心需求: ∇ θ log π θ ( a ∣ s ) \nabla_{\theta} \log \pi_{\theta}(a|s) ∇θlogπθ(a∣s)。
- 通过
-
均值+协方差(或标准差)可学习
- 只要用一个神经网络输出均值 μ ( s ) \mu(s) μ(s)与标准差 σ ( s ) \sigma(s) σ(s)(或者对数标准差),就可以表示很多不同形状(在动作空间)的高斯分布。
- 在训练过程中,通过梯度更新,这两个部分会朝使预期奖励更高的方向移动,从而逼近最优解。
2. 策略梯度方法能找到(局部)最优解
在策略梯度(Policy Gradient)或者 Actor-Critic 方法(如 PPO、TRPO)中:
-
目标函数
- 最大化期望累积奖励 J ( θ ) = E τ ∼ π θ [ ∑ r t ] J(\theta) = \mathbb{E}_{\tau\sim\pi_\theta}[\sum r_t] J(θ)=Eτ∼πθ[∑rt]。
- 在连续动作场景下,为了对动作进行探索和梯度计算,需要将策略表示成某种分布 π θ ( a ∣ s ) \pi_\theta(a|s) πθ(a∣s)。高斯分布是常见选择。
-
梯度更新
- 策略参数 (\theta) 通过公式
θ ← θ + α ∇ θ E [ ∑ log π θ ( a t ∣ s t ) R t ] \theta \leftarrow \theta + \alpha \nabla_{\theta} \mathbb{E}[\sum \log \pi_\theta(a_t|s_t) R_t] θ←θ+α∇θE[∑logπθ(at∣st)Rt]
(或其他 Actor-Critic 变体)
不断迭代,尝试提升期望回报 (J(\theta))。
- 策略参数 (\theta) 通过公式
-
高斯分布的好处
-
log
π
θ
(
a
∣
s
)
\log \pi_\theta(a|s)
logπθ(a∣s) 有解析形式:
log N ( a ∣ μ , σ 2 ) = − 1 2 ( a − μ σ ) 2 − log σ − 1 2 log ( 2 π ) \log \mathcal{N}(a|\mu,\sigma^2) = -\frac12 \left(\frac{a-\mu}{\sigma}\right)^2 - \log \sigma - \frac12\log(2\pi) logN(a∣μ,σ2)=−21(σa−μ)2−logσ−21log(2π)
易于对 μ \mu μ 和 σ \sigma σ 求梯度。
-
log
π
θ
(
a
∣
s
)
\log \pi_\theta(a|s)
logπθ(a∣s) 有解析形式:
只要给定足够丰富的函数逼近(例如神经网络的隐层足够大),该策略能在梯度信息的指引下,不断“爬”向局部最优甚至全局最优区域。在很多问题上,高斯策略通常能达到不错的解。
3. 高斯策略的探索性与单峰假设
-
探索性
- 高斯分布是连续的且带有标准差(KaTeX parse error: Can't use function '\)' in math mode at position 7: \sigma\̲)̲)这一可调参量,可以自动学到合…\sigma$ 会变大;若需要精确决策, σ \sigma σ 会缩小。
-
单峰分布可能足够
- 高斯分布是单峰分布,意味着策略假设动作分布呈现一个峰值。
- 在很多控制问题中,这已经足以找到满意的(局部)最优,因系统动力学往往在最优附近相对平滑。
-
可能的局限
- 如果最优解呈多峰分布或非常复杂的形状(可能出现多种动作选择都能高回报),单一高斯很难同时捕捉;但通常通过神经网络(隐层非线性)和反复迭代,也能逼近到一个“较优”峰值。
4. 神经网络强大的函数逼近能力
- 均值网络: μ θ ( s ) \mu_\theta(s) μθ(s) 本身是一个多层感知机(MLP),可以在状态空间上逼近相当复杂的映射;
- 标准差网络: σ θ ( s ) \sigma_\theta(s) σθ(s) 也可以是状态相关,从而在不同区域探索力度不同。
这种多层神经网络 + 高斯分布的组合,实际上能够表达“随状态而变化的单峰分布”,对很多控制任务已经足够。在理想条件(无限样本、合适的优化超参)下,策略梯度就能收敛到一个局部最优策略;在很多实际任务中,这个局部最优也已经很好了。
5. 小结
- 高斯策略最优的本质:
它并不是因为“高斯分布本身必然找到全局最优”,而是由于梯度优化(如REINFORCE、PPO)的迭代过程,可以持续地提高期望回报,最终收敛到一个**(局部)最优或足够优**的策略。 - 连续动作空间的易用分布:
高斯分布可微且计算对数概率方便,能够在策略梯度过程中被梯度更新,从而实现策略的改进。 - 最终效果:
足够丰富的网络表征 + 合理的超参数选择,让高斯策略在多数连续控制任务中表现良好,而且在实践中广泛应用(如机器人控制、无人机飞行等)。
因此,高斯策略并不必然是唯一最优,但它提供了一个可学习、可微、易实现的方式让策略梯度算法在连续动作空间中工作,从而“使得 policy(在梯度更新下)收敛到最优或近似最优解”。
下面是一份较为系统且深入的数学原理和解析,涵盖了这段 Pendulum 环境中所用的**高斯策略(Gaussian Policy)以及策略梯度(Policy Gradient, REINFORCE)**方法的核心数学背景和推导。为方便说明,以下内容将结合代码中的关键步骤,深入剖析它背后的原理与公式。
总览
在一个连续动作空间的强化学习场景下(例如 Pendulum),我们常使用高斯分布来表示策略 $\pi_\theta(a \mid s))。然后通过策略梯度(Policy Gradient)或其变体(如 Actor-Critic、PPO、TRPO 等)不断更新策略参数,使期望累积奖励最大化。
- 高斯策略: π θ ( a ∣ s ) = N ( a ∣ μ θ ( s ) , Σ θ ( s ) ) \pi_\theta(a \mid s) = \mathcal{N}(a \mid \mu_\theta(s),\, \Sigma_\theta(s)) πθ(a∣s)=N(a∣μθ(s),Σθ(s))。
- REINFORCE:一种基本的策略梯度方法,核心思想是采样状态-动作轨迹并利用 log π θ ( a ∣ s ) \log \pi_\theta(a\mid s) logπθ(a∣s)的梯度来更新策略。
以下将从高斯策略的定义开始,到折扣回报与梯度更新公式一步步展开。
一、高斯策略
1.1 策略表示
在代码中,策略用一个神经网络来输出动作的均值(
μ
\mu
μ),并维护一个可学习的
对数标准差($\log\sigma $)。
- 形如 π θ ( a ∣ s ) = N ( a ∣ μ θ ( s ) , d i a g ( σ θ 2 ) ) \pi_\theta(a\mid s) = \mathcal{N}\bigl(a \mid \mu_\theta(s),\, \mathrm{diag}(\sigma^2_\theta)\bigr) πθ(a∣s)=N(a∣μθ(s),diag(σθ2))
- 在代码中,$\mu_\theta(s)) 由
self.fc(state)
计算得出,其形状是[batch_size, action_dim]
。 - $\sigma_\theta) 由
std = torch.exp(self.log_std)
得到,形状[action_dim]
,若是多维动作也可以扩展成对角协方差矩阵。
一维高斯分布(动作维度=1)时,其概率密度函数(PDF)为
π θ ( a ∣ s ) = 1 2 π σ θ ( s ) exp ( − ( a − μ θ ( s ) ) 2 2 σ θ ( s ) 2 ) . \pi_\theta(a \mid s) \;=\; \frac{1}{\sqrt{2\pi}\,\sigma_\theta(s)} \exp\!\Bigl(-\frac{(a - \mu_\theta(s))^2}{2\,\sigma_\theta(s)^2}\Bigr). πθ(a∣s)=2πσθ(s)1exp(−2σθ(s)2(a−μθ(s))2).
若 $\mu) 和 $\sigma) 依赖于状态 $s) 的神经网络输出,则得到一个条件高斯分布。
1.2 采样与对数概率
-
采样:代码中
action = dist.sample()
就是从 N ( μ , σ 2 ) \mathcal{N}(\mu,\sigma^2) N(μ,σ2) 中进行一次采样,得到动作 $a)。
-
对数概率:
log_prob = dist.log_prob(action)
对应 log π θ ( a ∣ s ) \log \pi_\theta(a\mid s) logπθ(a∣s),其解析形式是一维时:
log π θ ( a ∣ s ) = − 1 2 ( a − μ θ ( s ) σ θ ( s ) ) 2 − log σ θ ( s ) − 1 2 log ( 2 π ) . \log \pi_\theta(a\mid s) \;=\; -\frac12 \Bigl(\frac{a - \mu_\theta(s)}{\sigma_\theta(s)}\Bigr)^2 \;-\; \log \sigma_\theta(s) \;-\; \frac12 \log (2\pi). logπθ(a∣s)=−21(σθ(s)a−μθ(s))2−logσθ(s)−21log(2π).
在高维时会有类似形式,只是用向量运算或对角协方差。
二、强化学习核心:马尔可夫决策过程
在强化学习中,我们通常有一个马尔可夫决策过程 (MDP),由 (\langle \mathcal{S}, \mathcal{A}, P, r, \gamma \rangle) 表示:
-
S
\mathcal{S}
S:状态空间,如 Pendulum 的
[cosθ, sinθ, θ̇]
(3 维)。 -
A
\mathcal{A}
A:动作空间,如扭矩
[–2, 2]
连续区间 (1 维)。 - P ( s t + 1 ∣ s t , a t ) P(s_{t+1} \mid s_t, a_t) P(st+1∣st,at):状态转移概率,这里由环境动力学给出。
- r ( s t , a t ) r(s_t, a_t) r(st,at):奖励函数。
- γ \gamma γ:折扣因子。
通过与环境交互(step 函数)、收集状态(s_t)、动作(a_t)、奖励(r_t) 的序列,可以估计策略性能。
三、REINFORCE(策略梯度)原理
在策略梯度方法中,我们的优化目标是最大化期望折扣回报:
J
(
θ
)
=
E
τ
∼
π
θ
[
∑
t
=
0
T
−
1
γ
t
r
(
s
t
,
a
t
)
]
,
J(\theta) \;=\; \mathbb{E}_{\tau \sim \pi_\theta}\Bigl[\sum_{t=0}^{T-1} \gamma^t\,r(s_t,a_t)\Bigr],
J(θ)=Eτ∼πθ[t=0∑T−1γtr(st,at)],
其中
τ
=
(
s
0
,
a
0
,
s
1
,
a
1
,
…
)
\tau=(s_0,a_0,s_1,a_1,\dots)
τ=(s0,a0,s1,a1,…) 表示一条轨迹,依赖于策略
π
θ
\pi_\theta
πθ。
3.1 策略梯度定理
经典的策略梯度定理告诉我们如何计算对 θ \theta θ 的梯度:
∇ θ J ( θ ) = E τ ∼ π θ [ ∇ θ ∑ t = 0 T − 1 log π θ ( a t ∣ s t ) ( ∑ k = t T − 1 γ k − t r k ) ] . \nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \Bigl[ \nabla_\theta \sum_{t=0}^{T-1} \log \pi_\theta(a_t \mid s_t)\, \Bigl(\sum_{k=t}^{T-1}\gamma^{k-t} r_k\Bigr)\Bigr]. ∇θJ(θ)=Eτ∼πθ[∇θt=0∑T−1logπθ(at∣st)(k=t∑T−1γk−trk)].
- 这意味着:要更新参数 θ \theta θ,需要对对数概率 log π θ \log \pi_\theta logπθ 与折扣累计回报 G t = ∑ k = t T − 1 γ k − t r k G_t = \sum_{k=t}^{T-1}\gamma^{k-t} r_k Gt=∑k=tT−1γk−trk做乘积,然后对整个期望取梯度。
3.2 REINFORCE 算法流程
在 REINFORCE 算法中,具体做法是:
- 采样:与环境交互一个回合(episode),收集状态、动作、即时奖励: { ( s 0 , a 0 , r 0 ) , … , ( s T − 1 , a T − 1 , r T − 1 ) } \{(s_0,a_0,r_0), \dots, (s_{T-1},a_{T-1},r_{T-1})\} {(s0,a0,r0),…,(sT−1,aT−1,rT−1)}。
- 计算回报:对每个时间步
t
t
t 计算折扣累计回报
G t = ∑ k = t T − 1 γ k − t r k . G_t = \sum_{k=t}^{T-1} \gamma^{k-t}r_k. Gt=k=t∑T−1γk−trk. - 累积损失:
L ( θ ) = − ∑ t = 0 T − 1 log π θ ( a t ∣ s t ) ( G t − b t ) , L(\theta) \;=\; -\sum_{t=0}^{T-1} \log \pi_\theta(a_t\mid s_t)\,\bigl(G_t - b_t\bigr), L(θ)=−t=0∑T−1logπθ(at∣st)(Gt−bt),
其中 b t b_t bt 可以是基线(此示例中未使用或可视为 0)。此处加负号是因为要最大化 J ( θ ) J(\theta) J(θ),等价于最小化损失。 - 梯度更新:
θ ← θ − α ∇ θ L ( θ ) . \theta \;\leftarrow\; \theta - \alpha\, \nabla_\theta L(\theta). θ←θ−α∇θL(θ).
在代码中可以看到,这个过程实现为:
loss = 0
for (log_prob, G) in zip(log_probs, returns):
loss -= log_prob * G
对应上面公式中的 − log π θ ( a t ∣ s t ) G t -\log \pi_\theta(a_t|s_t)\,G_t −logπθ(at∣st)Gt 之和。
四、折扣回报与标准化
4.1 折扣回报
对每个时间步
t
t
t,折扣累计回报(Return)定义:
G
t
=
∑
k
=
t
T
−
1
γ
k
−
t
r
k
G_t \;=\; \sum_{k=t}^{T-1} \gamma^{k-t}\,r_k
Gt=k=t∑T−1γk−trk
这是对未来奖励的一个加权和((\gamma\in(0,1]))。
在代码中,做法是:
G = 0
for r in reversed(rewards):
G = r + gamma * G
returns.insert(0, G)
这样就得到 { G 0 , G 1 , … } \{G_0, G_1, \dots\} {G0,G1,…}。
4.2 标准化回报
代码中还把 returns
做了一步统计标准化:
returns = (returns - returns.mean()) / (returns.std() + 1e-9)
- 这样可减少回报的数值范围差异,帮助训练稳定。
- 其本质是把回报视为一个随机变量,对其做 Z-Score 归一化,有助于减少梯度的高方差。
五、带入高斯策略的梯度更新
结合高斯策略 (\pi_\theta(a|s)):
- 动作分布:
π θ ( a ∣ s ) = N ( a ∣ μ θ ( s ) , σ θ ( s ) 2 ) . \pi_\theta(a\mid s) = \mathcal{N}\bigl(a\;\big|\;\mu_\theta(s), \sigma_\theta(s)^2\bigr). πθ(a∣s)=N(a μθ(s),σθ(s)2). - 对数概率:
log π θ ( a ∣ s ) = − 1 2 ( a − μ θ ( s ) σ θ ( s ) ) 2 − log σ θ ( s ) − 1 2 log ( 2 π ) . \log \pi_\theta(a\mid s) \;=\; -\frac{1}{2}\Bigl(\frac{a-\mu_\theta(s)}{\sigma_\theta(s)}\Bigr)^2 \;-\; \log \sigma_\theta(s)\;-\;\frac12 \log (2\pi). logπθ(a∣s)=−21(σθ(s)a−μθ(s))2−logσθ(s)−21log(2π). - 梯度传播
-
μ
θ
(
s
)
\mu_\theta(s)
μθ(s) 由网络输出
σ
θ
\sigma_\theta
σθ 也可以由网络或参数
log_std
生成。 - 当计算 ∇ θ log π θ ( a ∣ s ) \nabla_\theta\log \pi_\theta(a\mid s) ∇θlogπθ(a∣s) 时,误差信号会经过均值网络和标准差网络的权重,更新两部分参数。
-
μ
θ
(
s
)
\mu_\theta(s)
μθ(s) 由网络输出
σ
θ
\sigma_\theta
σθ 也可以由网络或参数
在代码中,则是利用 PyTorch 的自动求导机制来完成这个过程,关键在于:
dist = torch.distributions.Normal(mean, std)
action = dist.sample()
log_prob = dist.log_prob(action).sum(dim=-1)
...
loss -= log_prob * G
loss.backward()
PyTorch 会自动计算对应的梯度并更新 mean, std
(包括网络中的权重 fc(...)
和 log_std
)。
六、为什么高斯策略可以学到最优?
-
梯度方法保证不断改进
- 在理论上,只要策略是可微分的,且学习率、样本充分,就能在梯度指引下逐步增大期望回报。
- 高斯分布为我们提供了一个简单、连续、且具有可计算对数似然的形式。
-
高斯策略具有探索能力
- σ θ \sigma_\theta σθ 决定探索幅度;若初始大,可在动作空间随机试探。
- 学到后期, σ θ \sigma_\theta σθ 可能收敛到较小的值,使动作接近最优均值 μ θ ( s ) \mu_\theta(s) μθ(s),减少随机抖动。
-
局部最优
- 严格来说,这种方法往往收敛于局部最优;在很多连续控制任务中,局部最优已经相当好。
七、与代码的对应关系
从数学公式到代码实现,可以总结出对应:
-
GaussianPolicy
self.fc(state)
→ μ θ ( s ) \mu_\theta(s) μθ(s)torch.exp(self.log_std)
→ σ θ \sigma_\theta σθ
-
dist = torch.distributions.Normal(mean, std)
- 建立高斯分布 N ( a ∣ μ , σ ) \mathcal{N}(a|\mu,\sigma) N(a∣μ,σ)
-
action = dist.sample()
- 等价于抽取 a t ∼ N ( μ θ ( s t ) , σ θ ( s t ) 2 ) a_t \sim \mathcal{N}(\mu_\theta(s_t), \sigma_\theta(s_t)^2) at∼N(μθ(st),σθ(st)2)
-
log_prob = dist.log_prob(action)
- 等价于 log π θ ( a t ∣ s t ) \log \pi_\theta(a_t|s_t) logπθ(at∣st)
-
收集
(log_prob, reward)
,计算折扣回报returns
- 对应策略梯度公式中的 ∑ t log π θ ( a t ∣ s t ) G t \sum_t \log \pi_\theta(a_t|s_t) G_t ∑tlogπθ(at∣st)Gt
-
loss -= log_prob * G
,loss.backward()
- 负号是因为要最大化 log π θ ⋅ G \log \pi_\theta \cdot G logπθ⋅G。
- PyTorch 会自动根据 μ θ ( s ) \mu_\theta(s) μθ(s)、 σ θ \sigma_\theta σθ 的计算图进行梯度传递。
-
optimizer.step()
- 完成一次梯度更新,即 θ ← θ + α ∇ θ J ( θ ) \theta \leftarrow \theta + \alpha \nabla_\theta J(\theta) θ←θ+α∇θJ(θ)。
八、总结
-
高斯策略的数学本质
- 用一个可微函数(神经网络)映射状态到 μ ( s ) \mu(s) μ(s);再用可学习的 log σ \log\sigma logσ 得到 σ \sigma σ。这样组成一个在连续动作上的概率分布。
- 可微分 + 有解析形式 → 可以很方便地计算 log π θ ( a ∣ s ) \log \pi_\theta(a|s) logπθ(a∣s) 并做梯度更新。
-
REINFORCE
- 基于采样与梯度上升的原理,将 log π θ ( a ∣ s ) \log \pi_\theta(a|s) logπθ(a∣s)与相应的回报 G t G_t Gt 乘起来,更新策略参数,使期望收益不断提升。
-
折扣回报与标准化
- 通过折扣系数 γ \gamma γ 让未来奖励“递减影响”,更好地处理无限或长时序问题。
- 通过标准化回报减少数值不稳定性。
-
局部最优
- 该方法常可收敛到一个足够好的解,特别是在 Pendulum 之类的平滑且单峰问题中,常能获得理想表现。
参考要点
- 策略梯度定理: ∇ θ J ( θ ) = E [ ∇ θ log π θ ( a ∣ s ) G t ] \nabla_\theta J(\theta) = \mathbb{E}[\nabla_\theta \log \pi_\theta(a|s) \,G_t] ∇θJ(θ)=E[∇θlogπθ(a∣s)Gt]。
- 高斯分布的可微属性: log π θ \log\pi_\theta logπθ对 μ \mu μ、 σ \sigma σ可微,易编程实现。
- 可视化:在 Pendulum 中,随着训练进行, μ θ \mu_\theta μθ 不断变得“更加准确”, σ θ \sigma_\theta σθ 可能逐渐变小,从而在扭矩上更精确地控制摆的倒立平衡。
在实践中,高斯策略 + REINFORCE是强化学习的一个最小可行例子。更复杂的场景或更先进的方法(PPO, DDPG, SAC 等)本质上都遵循类似的思路,只是改进了更新方式与稳定性,但核心仍离不开策略可微+对数概率+梯度驱动的理论基础。