强化学习 - 基于策略搜索和策略优化: 高斯策略

最近在做毕设需要用强化学习来做控制,对强化学习的知识点做一下总结。

高斯策略

高斯策略属于强化学习中的基于策略优化的分支(Policy Optimization),尤其是策略梯度方法(Policy Gradient Methods) 的一部分。这一分支专注于通过优化策略的参数来直接提升策略的性能,而不需要显式地学习一个价值函数。


高斯策略在强化学习中的位置

强化学习可以按照以下几个主要分支分类:

  1. 基于价值函数的方法(Value-Based Methods)

    • 如Q-Learning、深度Q网络(DQN)。
    • 这些方法学习状态-动作值函数 ( Q(s, a) ),然后通过选择最大值的动作来构建策略。
  2. 基于策略的方法(Policy-Based Methods)

    • 直接对策略进行建模并优化。
    • 高斯策略属于这一类方法,特别是策略梯度方法(Policy Gradient Methods),因为它通过优化概率分布(高斯分布)来学习策略。
  3. 基于策略与价值的混合方法(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)) πθ(as)=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πθ(as)Qπ(s,a)]
其中:

  • log ⁡ π θ ( a ∣ s ) \log \pi_{\theta}(a|s) logπθ(as)是高斯分布的对数似然。
  • Q π ( s , a ) Q^{\pi}(s, a) Qπ(s,a) 是状态-动作值函数,用于评估策略的表现。

高斯策略在连续动作空间中的广泛应用,得益于高斯分布的可微性和灵活性,适合通过梯度优化调整策略。


高斯策略适用的场景

  1. 适用场景:
    • 机器人控制:如臂式机器人轨迹规划。
    • 无人机导航:优化无人机通过动态障碍的策略(如论文中提到的任务)。
    • 自动驾驶:优化车辆在连续状态和动作空间中的驾驶策略。

高斯策略的实际应用: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 = 0while 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 actiondist = torch.distributions.Normal(mean, std) # 知道均值和方差,就可以直到action的高斯分布了。# (C) 采样动作,并计算 log_probaction = 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 & rewardlog_probs.append(log_prob)rewards.append(reward)total_reward += rewardstate = next_stateif terminated or truncated:break# ========== 回合结束:计算回报并更新策略 ==========returns = []G = 0for r in reversed(rewards): # 存放每个时间步的折扣累计奖励G = r + gamma * Greturns.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 * Roptimizer.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)

  1. 表示连续动作策略
    在连续动作空间(如倒立摆),我们经常用高斯分布 (\mathcal{N}(\mu, \sigma^2)) 来表示“策略”,其中:

    • μ \mu μ(mean):动作的均值
    • σ \sigma σ(std):动作的标准差
  2. 进行动作采样
    有了这个 Normal(mean, std) 对象,就可以用

    action = dist.sample()
    

    来采样一个连续值的动作 action,从而在不同状态下能产生随机探索的效果。

  3. 计算对数概率(log_prob)
    在策略梯度强化学习里,需要用对数概率 log ⁡ π ( a ∣ s ) \log \pi(a|s) logπ(as) 来进行梯度更新。
    这个 dist 对象提供了 dist.log_prob(action),可以直接得到对数似然,方便我们实现 REINFORCE、PPO 等算法的损失函数。



3. 原理:高斯分布中的参数

一个一维高斯(正态)分布通常由两个参数决定:
X ∼ N ( μ , σ 2 ) X \sim \mathcal{N}(\mu, \sigma^2) XN(μ,σ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).

在代码中,meanstd 就是分别对应 (\mu) 和 (\sigma);因此 torch.distributions.Normal(mean, std) 可以完整表达这个分布。


4. 强化学习中的用法

在许多连续控制的强化学习算法里(如REINFORCETRPOPPO),我们往往直接建模一个高斯策略

  1. 网络输出:均值 μ ( s ) \mu(s) μ(s) + 对数标准差 log ⁡ σ \log \sigma logσ
  2. 构造分布
    dist = torch.distributions.Normal(mean, std)
    
  3. 采样动作
    action = dist.sample()
    
  4. 计算对数概率
    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 θtlogπθ(atst)Gt

这样就能在训练时学习到使期望回报最大的分布参数(meanstd),兼顾到探索(由 std 控制)和开销之间的平衡。


小结

  • dist = torch.distributions.Normal(mean, std) 是在 PyTorch 中创建一个正态(高斯)分布对象。
  • 通过这个对象可以采样动作计算对数概率,这是连续动作空间的经典做法。
  • 在强化学习中,这种高斯策略能实现探索,并且可通过梯度反向传播来学习 (\mu, \sigma) 等参数,从而自动优化控制策略。

为什么高斯策略最后能够使得policy最优?

连续动作空间的强化学习中,使用高斯策略(Gaussian Policy)是一种非常常见且有效的做法。核心原因并不在于高斯分布“本质上就能保证全局最优”,而是由于高斯策略作为可微分且可训练的分布形式,能够通过策略梯度方法不断逼近最优策略。下面从几个关键角度解释为什么高斯策略在实践中常能得到很好的(局部)最优策略。


1. 高斯策略的可微性及易于优化

  1. 连续空间需要可微分的概率分布

    • 在连续动作空间(如无人机控制、机械臂操作)中,需要一种能对动作进行可微分采样可微分对数概率计算的方法。
    • 高斯分布 N ( μ , σ 2 ) \mathcal{N}(\mu, \sigma^2) N(μ,σ2)拥有简单的概率密度函数和已知的对数似然形式,使得我们可以用梯度下降来优化 μ \mu μ σ \sigma σ
  2. PyTorch支持自动求导

    • 通过 torch.distributions.Normal,可以方便地计算 log ⁡ π ( a ∣ s ) \log\pi(a|s) logπ(as) 并反向传播到网络参数。
    • 这满足了策略梯度的核心需求: ∇ θ log ⁡ π θ ( a ∣ s ) \nabla_{\theta} \log \pi_{\theta}(a|s) θlogπθ(as)
  3. 均值+协方差(或标准差)可学习

    • 只要用一个神经网络输出均值 μ ( s ) \mu(s) μ(s)标准差 σ ( s ) \sigma(s) σ(s)(或者对数标准差),就可以表示很多不同形状(在动作空间)的高斯分布。
    • 在训练过程中,通过梯度更新,这两个部分会朝使预期奖励更高的方向移动,从而逼近最优解。

2. 策略梯度方法能找到(局部)最优解

在策略梯度(Policy Gradient)或者 Actor-Critic 方法(如 PPO、TRPO)中:

  1. 目标函数

    • 最大化期望累积奖励 J ( θ ) = E τ ∼ π θ [ ∑ r t ] J(\theta) = \mathbb{E}_{\tau\sim\pi_\theta}[\sum r_t] J(θ)=Eτπθ[rt]
    • 在连续动作场景下,为了对动作进行探索和梯度计算,需要将策略表示成某种分布 π θ ( a ∣ s ) \pi_\theta(a|s) πθ(as)。高斯分布是常见选择。
  2. 梯度更新

    • 策略参数 (\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πθ(atst)Rt]
      (或其他 Actor-Critic 变体)
      不断迭代,尝试提升期望回报 (J(\theta))。
  3. 高斯分布的好处

    • log ⁡ π θ ( a ∣ s ) \log \pi_\theta(a|s) logπθ(as) 有解析形式:
      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μ)2logσ21log(2π)
      易于对 μ \mu μ σ \sigma σ 求梯度。

只要给定足够丰富的函数逼近(例如神经网络的隐层足够大),该策略能在梯度信息的指引下,不断“爬”向局部最优甚至全局最优区域。在很多问题上,高斯策略通常能达到不错的解。


3. 高斯策略的探索性与单峰假设

  1. 探索性

    • 高斯分布是连续的且带有标准差(KaTeX parse error: Can't use function '\)' in math mode at position 7: \sigma\̲)̲)这一可调参量,可以自动学到合…\sigma$ 会变大;若需要精确决策, σ \sigma σ 会缩小。
  2. 单峰分布可能足够

    • 高斯分布是单峰分布,意味着策略假设动作分布呈现一个峰值。
    • 在很多控制问题中,这已经足以找到满意的(局部)最优,因系统动力学往往在最优附近相对平滑。
  3. 可能的局限

    • 如果最优解呈多峰分布或非常复杂的形状(可能出现多种动作选择都能高回报),单一高斯很难同时捕捉;但通常通过神经网络(隐层非线性)和反复迭代,也能逼近到一个“较优”峰值。

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)) πθ(as)=N(aμθ(s),Σθ(s))
  • REINFORCE:一种基本的策略梯度方法,核心思想是采样状态-动作轨迹并利用 log ⁡ π θ ( a ∣ s ) \log \pi_\theta(a\mid s) logπθ(as)的梯度来更新策略。

以下将从高斯策略的定义开始,到折扣回报梯度更新公式一步步展开。


一、高斯策略

1.1 策略表示

在代码中,策略用一个神经网络来输出动作的均值( μ \mu μ),并维护一个可学习的
对数标准差($\log\sigma $)。

  1. 形如 π θ ( 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) πθ(as)=N(aμθ(s),diag(σθ2))
  2. 在代码中,$\mu_\theta(s)) 由 self.fc(state) 计算得出,其形状是 [batch_size, action_dim]
  3. $\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). πθ(as)=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πθ(as),其解析形式是一维时:

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πθ(as)=21(σθ(s)aμθ(s))2logσθ(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+1st,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=0T1γ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=0T1logπθ(atst)(k=tT1γktrk)].

  • 这意味着:要更新参数 θ \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=tT1γktrk做乘积,然后对整个期望取梯度。

3.2 REINFORCE 算法流程

在 REINFORCE 算法中,具体做法是:

  1. 采样:与环境交互一个回合(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),,(sT1,aT1,rT1)}
  2. 计算回报:对每个时间步 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=tT1γktrk.
  3. 累积损失
    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=0T1logπθ(atst)(Gtbt),
    其中 b t b_t bt 可以是基线(此示例中未使用或可视为 0)。此处加负号是因为要最大化 J ( θ ) J(\theta) J(θ),等价于最小化损失。
  4. 梯度更新
    θ ← θ − α ∇ θ 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πθ(atst)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=tT1γktrk
这是对未来奖励的一个加权和((\gamma\in(0,1]))。

在代码中,做法是:

G = 0
for r in reversed(rewards):G = r + gamma * Greturns.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)):

  1. 动作分布
    π θ ( 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). πθ(as)=N(a μθ(s),σθ(s)2).
  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πθ(as)=21(σθ(s)aμθ(s))2logσθ(s)21log(2π).
  3. 梯度传播
    • μ θ ( s ) \mu_\theta(s) μθ(s) 由网络输出 σ θ \sigma_\theta σθ 也可以由网络或参数 log_std 生成。
    • 当计算 ∇ θ log ⁡ π θ ( a ∣ s ) \nabla_\theta\log \pi_\theta(a\mid s) θlogπθ(as) 时,误差信号会经过均值网络和标准差网络的权重,更新两部分参数。

在代码中,则是利用 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)。


六、为什么高斯策略可以学到最优?

  1. 梯度方法保证不断改进

    • 在理论上,只要策略是可微分的,且学习率、样本充分,就能在梯度指引下逐步增大期望回报
    • 高斯分布为我们提供了一个简单、连续、且具有可计算对数似然的形式。
  2. 高斯策略具有探索能力

    • σ θ \sigma_\theta σθ 决定探索幅度;若初始大,可在动作空间随机试探。
    • 学到后期, σ θ \sigma_\theta σθ 可能收敛到较小的值,使动作接近最优均值 μ θ ( s ) \mu_\theta(s) μθ(s),减少随机抖动。
  3. 局部最优

    • 严格来说,这种方法往往收敛于局部最优;在很多连续控制任务中,局部最优已经相当好。

七、与代码的对应关系

从数学公式到代码实现,可以总结出对应:

  1. GaussianPolicy

    • self.fc(state) μ θ ( s ) \mu_\theta(s) μθ(s)
    • torch.exp(self.log_std) σ θ \sigma_\theta σθ
  2. dist = torch.distributions.Normal(mean, std)

    • 建立高斯分布 N ( a ∣ μ , σ ) \mathcal{N}(a|\mu,\sigma) N(aμ,σ)
  3. 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) atN(μθ(st),σθ(st)2)
  4. log_prob = dist.log_prob(action)

    • 等价于 log ⁡ π θ ( a t ∣ s t ) \log \pi_\theta(a_t|s_t) logπθ(atst)
  5. 收集 (log_prob, reward),计算折扣回报 returns

    • 对应策略梯度公式中的 ∑ t log ⁡ π θ ( a t ∣ s t ) G t \sum_t \log \pi_\theta(a_t|s_t) G_t tlogπθ(atst)Gt
  6. loss -= log_prob * Gloss.backward()

    • 负号是因为要最大化 log ⁡ π θ ⋅ G \log \pi_\theta \cdot G logπθG
    • PyTorch 会自动根据 μ θ ( s ) \mu_\theta(s) μθ(s) σ θ \sigma_\theta σθ 的计算图进行梯度传递。
  7. optimizer.step()

    • 完成一次梯度更新,即 θ ← θ + α ∇ θ J ( θ ) \theta \leftarrow \theta + \alpha \nabla_\theta J(\theta) θθ+αθJ(θ)

八、总结

  1. 高斯策略的数学本质

    • 用一个可微函数(神经网络)映射状态到 μ ( s ) \mu(s) μ(s);再用可学习的 log ⁡ σ \log\sigma logσ 得到 σ \sigma σ。这样组成一个在连续动作上的概率分布
    • 可微分 + 有解析形式 → 可以很方便地计算 log ⁡ π θ ( a ∣ s ) \log \pi_\theta(a|s) logπθ(as) 并做梯度更新。
  2. REINFORCE

    • 基于采样梯度上升的原理,将 log ⁡ π θ ( a ∣ s ) \log \pi_\theta(a|s) logπθ(as)与相应的回报 G t G_t Gt 乘起来,更新策略参数,使期望收益不断提升。
  3. 折扣回报与标准化

    • 通过折扣系数 γ \gamma γ 让未来奖励“递减影响”,更好地处理无限或长时序问题。
    • 通过标准化回报减少数值不稳定性。
  4. 局部最优

    • 该方法常可收敛到一个足够好的解,特别是在 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πθ(as)Gt]
  • 高斯分布的可微属性: log ⁡ π θ \log\pi_\theta logπθ μ \mu μ σ \sigma σ可微,易编程实现。
  • 可视化:在 Pendulum 中,随着训练进行, μ θ \mu_\theta μθ 不断变得“更加准确”, σ θ \sigma_\theta σθ 可能逐渐变小,从而在扭矩上更精确地控制摆的倒立平衡。

在实践中,高斯策略 + REINFORCE是强化学习的一个最小可行例子。更复杂的场景或更先进的方法(PPO, DDPG, SAC 等)本质上都遵循类似的思路,只是改进了更新方式与稳定性,但核心仍离不开策略可微+对数概率+梯度驱动的理论基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于微信小程序高校课堂教学管理系统 课堂管理系统微信小程序(源码+文档)

目录 一.研究目的 二.需求分析 三.数据库设计 四.系统页面展示 五.免费源码获取 一.研究目的 困扰管理层的许多问题当中,高校课堂教学管理也是不敢忽视的一块。但是管理好高校课堂教学又面临很多麻烦需要解决,如何在工作琐碎,记录繁多的情况下将高校课堂教学的当前情况反…

论文阅读笔记:VMamba: Visual State Space Model

论文阅读笔记:VMamba: Visual State Space Model 1 背景2 创新点3 方法4 模块4.1 2D选择性扫描模块(SS2D)4.2 加速VMamba 5 效果5.1 和SOTA方法对比5.2 SS2D和自注意力5.3 有效感受野5.4 扫描模式 论文:https://arxiv.org/pdf/240…

【文星索引】搜索引擎项目测试报告

目录 一、项目背景二、 项目功能2.1 数据收集与索引2.2 API搜索功能2.3 用户体验与界面设计2.4 性能优化与维护 三、测试报告3.1 功能测试3.2 界面测试3.3 性能测试3.4 兼容性测试3.5 自动化测试 四、测试总结4.1 功能测试方面4.2 性能测试方面4.3 用户界面测试方面 一、项目背…

DBO-高斯回归预测matlab

蜣螂优化算法(Dung Beetle Optimizer, DBO)是一种新型的群智能优化算法,在2022年底提出,主要是受蜣螂的的滚球、跳舞、觅食、偷窃和繁殖行为的启发。 本次研究使用的是 Excel 格式的股票预测数据。数据集按照 8:1:1 的比例&#x…

MySQL篇之对MySQL进行参数优化,提高MySQL性能

1. MySQL参数优化说明 MySQL 参数调优是提高数据库性能的重要手段之一。通过调整 MySQL 的配置参数,可以优化查询速度、提升并发处理能力、减少资源消耗等。 MySQL 的性能优化涉及到多个方面,包括内存管理、磁盘 I/O、查询优化、连接管理、复制配置等。…

8621 二分查找

SCAU数据结构OJ第五章 文章目录 8621 二分查找 8621 二分查找 Description 编写Search_Bin函数,实现在一个递增有序数组ST中采用折半查找法确定元素位置的算法. 输入格式 第一行: 元素个数n 第二行:依次输入n个元素的值(有序) 第…

差分等长的原理

差分等长是指在设计差分信号传输线路时,保证两条差分线的长度尽量一致,长度之差在一个合理的范围内。这是为了确保两个差分信号时刻保持相反极性,减少共模分量,从而提高信号传输的质量。 在差分信号传输中,两条差分线…

Autogen_core: Reflection

目录 代码代码逻辑解释:数据类定义:CoderAgent 类:ReviewerAgent 类:主程序: 完成的功能: 代码 from dataclasses import dataclassdataclass class CodeWritingTask:task: strdataclass class CodeWritin…

我们需要有哪些知识体系,知识体系里面要有什么哪些内容?

01、管理知识体系的学习知识体系 主要内容: 1、知识管理框架的外部借鉴、和自身知识体系的搭建; 2、学习能力、思维逻辑能力等的塑造; 3、知识管理工具的使用; 4、学习资料的导入和查找资料的渠道; 5、深层关键的…

java后端之事务管理

Transactional注解:作用于业务层的方法、类、接口上,将当前方法交给spring进行事务管理,执行前开启事务,成功执行则提交事务,执行异常回滚事务 spring事务管理日志: 默认情况下,只有出现Runti…

Sora学习

openai 12天的发布会 remix:对视频处理 可以改变视频的元素和内容,打开一扇门的例子(打开门是太空,打开门是丛林) recut:重新生成或者重新剪辑,给一个视频前后做扩展 storyboard:可以对每一帧进行剪辑和生成新的 …

Python 字典:快速掌握高效的数据存储方式

文章目录 一、什么是字典?字典的定义二、字典的基本操作1. 访问字典的值2. 修改字典中的值3. 添加新的键值对4. 删除键值对5. 获取字典长度三、字典的遍历1. 遍历键2. 遍历值3. 遍历键值对四、字典的常用方法1. `keys()`:获取所有键2. `values()`:获取所有值3. `items()`:获…

【嵌入式】总结——Linux驱动开发(三)

鸽了半年,几乎全忘了,幸亏前面还有两篇总结。出于快速体验嵌入式linux的目的,本篇与前两篇一样,重点在于使用、快速体验,uboot、linux、根文件系统不作深入理解,能用就行。 重新梳理一下脉络,本…

RabbitMQ 多种安装模式

文章目录 前言一、Windows 安装 RabbitMq1、版本关系2、Erlang2.1、下载安装 Erlang 23.12.2、配置 Erlang 环境变量 3、RabbitMQ3.1、下载安装 RabbitMQ 3.8.93.2、环境变量3.3、启动RabbitMQ 管理插件3.3、RabbitMQ3.4、注意事项 二、安装docker1、更新系统包:2、…

使用python-docx包进行多文件word文字、字符批量替换

1、首先下载pycharm。 2、改为中文。 3、安装python-docx包。 搜索包名字,安装。 4、新建py文件,写程序。 from docx import Documentdef replace1(array1):# 替换词典(标签值按实际情况修改)dic {替换词1: array1[0], 替换…

Android中Service在新进程中的启动流程

目录 1、Service与AMS交互框架介绍 1.1、认识AMS代表IActivityManager 1.2、认识客户端代表IApplicationThread 2、Service启动流程概览 我们知道Android有四大组件,Activity、Service、ContentProvider、Broadcast,每个组件在系统运行中或者我们编写…

【信息系统项目管理师-选择真题】2011下半年综合知识答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9~10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第21题】…

read+write实现:链表放到文件+文件数据放到链表 的功能

思路 一、 定义链表: 1 节点结构(数据int型) 2 链表操作(创建节点、插入节点、释放链表、打印链表)。 二、链表保存到文件 1打开文件 2遍历链表、写文件: 遍历链表,write()将节点数据写入文件。…

【景区导游——LCA】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int N 1e5 10; const int M 2 * N; int p[N][18], d[N], a[N]; ll dis[N][18]; //注意这里要开long long int h[N], e[M], ne[M], idx, w[M]; int n, k; void add(int a, int b, …

Vue 3 30天精进之旅:Day 06 - 表单输入绑定

引言 在前几天的学习中&#xff0c;我们探讨了事件处理的基本概念及其在Vue中的应用。今天&#xff0c;我们将进一步了解Vue的表单输入绑定。这是构建用户交互式应用的核心部分&#xff0c;使得我们能够方便地处理用户输入并实时更新数据。本文将介绍如何在Vue中实现单向和双向…