跳到正文
Lanxinmob

CS285 课程笔记:策略梯度、Actor-Critic 与 DQN

从策略梯度、自然梯度与重要性采样,到 Actor-Critic、GAE、DQN 和 SAC,梳理 model-free 强化学习的主线。

前言

今天正式开始 CS285: Deep Reinforcement Learning 深度强化学习的第一部分 model-free 算法,包括 policy gradients、actor-critic、Q-learining。

Policy Gradients

image-20260723173750056

最大似然中梯度只是把所有动作的对数概率简单相加,而策略梯度则会根据轨迹的奖励值增加或减少对数概率,可以理解为对最大似然梯度的一种加权版本。

probelm

策略梯度的方差很大,对于任意有限的样本,最终得到的策略梯度值都很可能不同。这意味着在实践中,为了使梯度策略成为强化学习的有效工具,我们需要以某种方式降低这种极高的方差。

reduce variance

一个利用 causality 关系的 trick是reward不再是所有时间的总和而是时刻 t 状态从时间 t 到T的总和,因为时间步t的动作不能影响过去的奖励,这意味着在无限样本量下当下状态各种可能的策略梯度必然会抵消,时间步t以前的策略梯度的期望为0,不会影响当前时间步的概率。舍去所有过去的奖励,对于有限量的样本其实并不会抵消,实际上会改变估计量,但仍然是无偏的。通过从求和中移除一些量,得到了一个方差更低的估计量。

baseline

从策略梯度的奖励中减去一个常数b,对于无限样本量下不会改变梯度的期望,但是会改变方差。一种baseline是取平均值,增加高于平均值的轨迹的概率,降低差于平均值的轨迹的概率,减去这个基线仍保持无偏,平均值不是最好的baseline在实际中也不常用,但方便帮助我们去理解其他变体。

auto differentiation

在深度学习中,我们习惯先定义一个损失函数(如 MSE 或交叉熵)然后求导,但策略梯度的目标是最大化期望回报 J(θ)J(\theta)。为了强行 PyTorch 或 TensorFlow 现成的自动微分和反向传播机制,我们需要构造一个标量函数,即伪损失。因为这个 Loss 的数值本身没有任何物理意义,只是为了作为一种数学工具,引导自动微分引擎去计算策略梯度。在 PyTorch 中,实现上述逻辑有两种写法。如果离散动作以类别索引表示,可以直接使用交叉熵。如果保存为 one-hot,则可以从 log_softmax 中选出对应动作的对数概率。

import torch
import torch.nn.functional as F

# 1. 策略网络输出动作的 Logits(形状:(N*T) x Da)
logits = policy(states)

# 2. 计算负对数似然
negative_likelihoods = F.cross_entropy(logits, actions, reduction='none')

# 3. 乘以 Q 值进行加权。q_values 必须通过 .detach() 阻断梯度,防止自动微分对其求导
weighted_negative_likelihoods = negative_likelihoods * q_values.detach()

# 4. 计算均值,得到最终的“伪损失”
loss = torch.mean(weighted_negative_likelihoods)

# 5. 反向传播,计算策略梯度
optimizer.zero_grad()
loss.backward()
optimizer.step()

另一种使用 torch.distributions,以离散动作的 Categorical 为例,连续动作可使用 Normal 等分布:

import torch
import torch.distributions as distributions

# 1. 网络输出 Logits 并组装成分类分布
logits = policy(states)
action_dist = distributions.Categorical(logits=logits)

# 2. 直接计算对数概率。
# log_prob(actions) 计算的是 log π(a|s)
log_prob = action_dist.log_prob(actions)

# 3. 构造伪损失(加上负号转化为梯度下降,并乘以 Q 值)
loss = -(log_prob * q_values.detach()).mean()

# 4. 自动微分求导
optimizer.zero_grad()
loss.backward()
optimizer.step()

in practice

策略梯度估算噪声大有着极高的方差,所以习惯用比监督学习更大的批次如5000、10000等,同时在调整学习率上也有更大的难度,像 Adam 这种自适应步长算法也只能算勉强。后续将谈到专门针对策略梯度的学习率调整方法(如自然策略梯度)总的来说需要比通常在监督学习中更多的超参数调优。

Natural PG

普通的策略梯度更新相当于在解下面这个受限优化问题,只限制了新旧参数在参数空间里的欧氏距离(L2 范数)不能超过 ϵ\epsilon 。

max⁡θ′(θ′−θ)T∇θJ(θ)s.t.∥θ′−θ∥2≤ϵ\max_{\theta'} (\theta' - \theta)^T \nabla_\theta J(\theta) \quad \text{s.t.} \quad \|\theta' - \theta\|^2 \le \epsilon

可能存在有些参数稍微变一点,输出概率就会巨变;而有些参数变很多,概率却几乎不变的情况。因为参数空间的几何结构,无法反映机器人行为的真实变化。

为了衡量两个行为空间概率分布之间的距离,我们引入了与参数无关的度量——KL 散度(KL-Divergence)

max⁡θ′(θ′−θ)T∇θJ(θ)s.t.DKL(πθ′∥πθ)≤ϵ\max_{\theta'} (\theta' - \theta)^T \nabla_\theta J(\theta) \quad \text{s.t.} \quad D_{\text{KL}}(\pi_{\theta'} \parallel \pi_\theta) \le \epsilon
  • 无论你的神经网络怎么设计、参数怎么变,它逼迫新旧策略输出的实际动作概率分布的差距永远被锁死在 ϵ\epsilon 之内,避免了因为某一步迈得太大而导致策略崩溃。

Fisher Information Matrix

虽然上面的 KL 散度约束在物理上很完美,但在数学上,KL 散度是一个高度非线性的复杂函数,直接求解这个受限优化问题极其困难。为了在计算机里高效求解,数学家们对 DKL(πθ′∥πθ)D_{\text{KL}}(\pi_{\theta'} \parallel \pi_\theta) 在 θ\theta 处进行了二阶泰勒展开,零阶项,一阶项在 θ\theta 处均为 00,而二阶项在数学上刚好等于著名的费舍尔信息矩阵。因此,当更新步长很小时,KL 散度可以近似写为一个关于参数偏差的二次型:DKL(πθ′∥πθ)≈12(θ′−θ)TF(θ′−θ)D_{\text{KL}}(\pi_{\theta'} \parallel \pi_\theta) \approx \frac{1}{2} (\theta' - \theta)^T \mathbf{F} (\theta' - \theta)。这里的 F\mathbf{F},定义为对数策略梯度的外积期望值:F=Eπθ[∇θlog⁡πθ(a∣s)∇θlog⁡πθ(a∣s)T]\mathbf{F} = \mathbb{E}_{\pi_\theta} \left[ \nabla_\theta \log \pi_\theta(\mathbf{a}|\mathbf{s}) \nabla_\theta \log \pi_\theta(\mathbf{a}|\mathbf{s})^T \right]

  • F\mathbf{F} 是黎曼流形上随位置变化的度量矩阵。它就像是一个空间拉伸器,能够根据当前策略的敏感度,自动对参数空间的不同维度进行缩放,使参数空间完美扭曲对齐到真实的概率分布空间。

利用拉格朗日乘子法求解这个以 F\mathbf{F} 为二次型约束的优化问题,我们可以推导出自然策略梯度的更新公式:

θ←θ+αF−1∇θJ(θ)\theta \leftarrow \theta + \alpha \mathbf{F}^{-1} \nabla_\theta J(\theta)

在策略梯度前面乘了一个 F−1\mathbf{F}^{-1}:

  • 如果某个参数方向对概率分布的改变极度敏感(F\mathbf{F} 很大),F−1\mathbf{F}^{-1} 就会把这个方向的梯度强行缩小,防止更新过头。
  • 如果某个方向对概率改变极度迟钝(F\mathbf{F} 很小),F−1\mathbf{F}^{-1} 就会把这个方向的梯度强行放大,让它多迈一步。

这确保了无论参数空间如何扭曲,机器人在实际行为空间里,每一步都迈着大小合适的步子更新策略。更现代的方法信赖域策略优化 TRPO,使用共轭梯度同时计算 α\alpha 和 自然梯度以及线搜索保证安全边界,不过依然很难工程落地。后面提出了PPO、GRPO避开了二阶计算,直接使用一阶优化器 Adam 才落地到大模型大规模强化学习。

Importance Sampling

策略梯度是一个 on-policy 算法,但我们可以引出一个 off-policy 的变体。重要性采样是一个 Off-policy 中的经典设计,假设我们想计算 r(x)r(x) 在新的概率分布 p(x)p(x) 下的期望值 Ex∼p[r(x)]\mathbb{E}_{x \sim p}[r(x)],但我们无法直接从 p(x)p(x) 中采样数据。相反,我们手头有另一个容易采样的分布 q(x)q(x)(在策略梯度中,就是旧的行为策略 πˉ\bar{\pi} 收集的数据)。对积分公式变形重组:

Ex∼p[r(x)]=∫p(x)r(x)dx=∫q(x)q(x)p(x)r(x)dx=∫q(x)[p(x)q(x)]⏟重要性权重 w(x)r(x)dx\mathbb{E}_{x \sim p}[r(x)] = \int p(x)r(x)dx = \int \frac{q(x)}{q(x)} p(x)r(x)dx = \int q(x) \underbrace{\left[ \frac{p(x)}{q(x)} \right]}_{\text{重要性权重 } w(x)} r(x)dx

因为积分号外面现在是 q(x)dxq(x)dx,所以整个积分等价于在 q(x)q(x) 分布下的期望值:=Ex∼q[p(x)q(x)r(x)]= \mathbb{E}_{x \sim q} \left[ \frac{p(x)}{q(x)} r(x) \right]

  • 这里的比值 w(x)=p(x)q(x)w(x) = \frac{p(x)}{q(x)} 就是重要性权重,用来修正因为采样分布改变而产生的偏差。

展开轨迹概率公式 pθ(τ)pˉ(τ)=∏t=1Tπθ(at∣st)∏t=1Tπˉ(at∣st)\frac{p_\theta(\tau)}{\bar{p}(\tau)} = \frac{\prod_{t=1}^T \pi_\theta(\mathbf{a}_t | \mathbf{s}_t)}{\prod_{t=1}^T \bar{\pi}(\mathbf{a}_t | \mathbf{s}_t)},初始状态分布 p(s1)p(\mathbf{s}_1) 和未知的物理环境转移概率 p(st+1∣st,at)p(\mathbf{s}_{t+1} | \mathbf{s}_t, \mathbf{a}_t) 在分子和分母中被抵消,这使得我们在不需要知道物理环境规律(Model-free)的前提下,仅靠旧动作和新动作的概率比值,就能评估新策略。

First-Order Approximation

但是重要性采样的权重在整条轨迹上进行计算:

∇θ′J(θ′)=Eτ∼pθ(τ)[(∏t′=1Tπθ′(at′∣st′)πθ(at′∣st′))(∑t=1T∇θ′log⁡πθ′(at∣st))(∑t=1Tr(st,at))]\nabla_{\theta'} J(\theta') = \mathbb{E}_{\tau \sim p_\theta(\tau)} \left[ \left( \prod_{t'=1}^T \frac{\pi_{\theta'}(\mathbf{a}_{t'}|\mathbf{s}_{t'})}{\pi_\theta(\mathbf{a}_{t'}|\mathbf{s}_{t'})} \right) \left( \sum_{t=1}^T \nabla_{\theta'} \log \pi_{\theta'}(\mathbf{a}_t|\mathbf{s}_t) \right) \left( \sum_{t=1}^T r(\mathbf{s}_t, \mathbf{a}_t) \right) \right]
  • 由于 TT(时间步长)可能非常大,大量接近于 11 的动作概率比值进行连乘(∏t′=1T\prod_{t'=1}^T),可能快速趋零或变得极大,从而造成严重方差和数值不稳定。

为了解决指数连乘,我们将整体轨迹期望拆解为每个独立时间步 tt 的边际状态-动作分布的期望之和:

J(θ)=∑t=1TEst,at∼pθ[r(st,at)]J(\theta) = \sum_{t=1}^T \mathbb{E}_{\mathbf{s}_t, \mathbf{a}_t \sim p_\theta} [r(\mathbf{s}_t, \mathbf{a}_t)]

对这一项进行单步重要性采样,得到了两个比例的乘积:

pθ′(st,at)pθ(st,at)=pθ′(st)pθ(st)⏟状态边际比例⋅πθ′(at∣st)πθ(at∣st)⏟单步动作比例\frac{p_{\theta'}(\mathbf{s}_t, \mathbf{a}_t)}{p_\theta(\mathbf{s}_t, \mathbf{a}_t)} = \underbrace{\frac{p_{\theta'}(\mathbf{s}_t)}{p_\theta(\mathbf{s}_t)}}_{\text{状态边际比例}} \cdot \underbrace{\frac{\pi_{\theta'}(\mathbf{a}_t | \mathbf{s}_t)}{\pi_\theta(\mathbf{a}_t | \mathbf{s}_t)}}_{\text{单步动作比例}}

接着做出一阶近似,忽略状态边际概率之比,将其当作 11 来看待。只要我们限制更新步伐,让新旧策略 θ′≈θ\theta' \approx \theta 极为接近,那么它们在环境里的状态分布也必然极其接近:pθ′(st)≈pθ(st)p_{\theta'}(\mathbf{s}_t) \approx p_\theta(\mathbf{s}_t)。同时有论文在数学上严格证明了如果约束新旧策略的偏差(例如限制 KL 散度 DKL(πθ∥πθ′)≤δD_{\text{KL}}(\pi_\theta \parallel \pi_{\theta'}) \le \delta),那么会给出一个极小量级的有界误差。

由于忽略状态边际概率的前置条件是新旧策略不能相差太大,现代强化学习算法开始围绕如何把策略限制在安全区(Trust Region)内进行架构设计:

  • PPO:在训练更新时,PPO 引入了 Clipping(截断) 机制,将新旧动作更新比例 rt(θ)r_t(\theta) 限制在 [1−ϵ,1+ϵ][1-\epsilon, 1+\epsilon] 之间(通常 ϵ=0.2\epsilon = 0.2),在每个独立时间步对策略进行微小而稳定的逐步优化。
  • GRPO:继承了 PPO 逐步优化和一阶近似的思想,同时去掉 critic 网络,对于同一个问题(Prompt),GRPO 采样一组(如 G=64G=64 个)不同的回答,计算这组输出的奖励均值 mean\text{mean} 和标准差 std\text{std}。第 ii 个回答的优势直接通过组内相对得分算出:Ai=ri−mean(r)std(r)A_i = \frac{r_i - \text{mean}(r)}{\text{std}(r)}

Actor-Critic

image-20260724164947598

improve PG

V(st)V(s_t) 是一个很好的 baseline 选择,Q - V 是一个非常直观的量,反映了动作 ata_t 相对于状态 sts_t 下的平均动作水平的优劣程度的估计,这个量就是 advantage function,表示动作 a 比策略 p 在状态 s 下预期获得平均奖励的优势程度,对优势函数的估算越精准,策略梯度的方差就越低。

但在实际计算中,我们无法知道精确的 Q(s,a)Q(s,a) 和 V(s)V(s) 值,其中拟合状态价值函数 V(s)V(s) 又被称为 Policy Evaluation,因为只与状态有关看上去更加简单,当然同样可以 fit Q or advantage function 后面会再提到。

通常使用蒙特卡洛采样得到数据来approximate value function,虽然蒙特卡洛能提供真实的、无偏的未来回报标签,但由于其累积方差过大,在工程上我们通常更进一步采用自举的方式。通过用当前网络对下一步的价值估计 V(st+1)V(s_{t+1}) 代替未来长序列的真实奖励,虽然引入了短暂的偏差,但极大降低了拟合方差,并实现了单步在线更新。根据贝尔曼方程,我们有 Qπ(st,at)=E[r(st,at)+γVπ(st+1)]Q^\pi(s_t, a_t) = \mathbb{E}[r(s_t, a_t) + \gamma V^\pi(s_{t+1})],折扣因子 γ\gamma 的作用是减小策略梯度的方差,因为如果奖励无限大必然对应无限大的方差,代价同样是引入偏差。我们将这个等式代入优势函数中就直接促成了现代 Actor-Critic(AC)算法的核心逻辑

Aπ(st,at)=Qπ(st,at)−Vπ(st)≈r(st,at)+γVπ(st+1)−Vπ(st)⏟TD Error(时序差分误差)A^\pi(s_t, a_t) = Q^\pi(s_t, a_t) - V^\pi(s_t) \approx \underbrace{r(s_t, a_t) + \gamma V^\pi(s_{t+1}) - V^\pi(s_t)}_{\text{TD Error(时序差分误差)}}

image-20260724181406618

actor-critic 算法优点是更低的方差,缺点是不再无偏,因为critic是基于有限样本训练的函数逼近器。用下图的蒙特卡洛优势估计器就可以既无偏又有较低方差,但存在的问题是无法像actor-critic一样逐步优化了。

image-20260724193615053

如果使用基于状态和动作的baseline方差还能更低,但也会更加复杂,因为基于动作的baseline就不能保证无偏了,需要另外加上校正项。它相当于一种 control variate(控制变量)用高方差随机量 - 相关的近似量 + 近似量的精确期望。计算策略梯度时,QϕQ_\phi 不对 θ\theta 求梯度,实现中一般也会对 critic 输出使用 detach 或stop_gradient。如果 QϕQ_\phi 与 actor 共享参数,并且不阻断梯度,那么

∇θEπ[Qϕ]=Eπ[∇θlog⁡π Qϕ]+Eπ[∇θQϕ],\nabla_\theta\mathbb E_\pi[Q_\phi] = \mathbb E_\pi[ \nabla_\theta\log\pi\,Q_\phi ] + \mathbb E_\pi[ \nabla_\theta Q_\phi ],

会额外出现Eπ[∇θQϕ]\mathbb E_\pi[\nabla_\theta Q_\phi],抵消关系就不再成立,不能恢复成原始的无偏策略梯度。 image-20260724194347946

GAE

将actor-critic和蒙特卡洛优势估计结合,我们就能得到 n 步优势估计器。随着 nn 的增大,使用了更多真实的奖励,偏差逐渐降低;但由于累积了更多随机的动作和状态,方差也会随之增大。

A^nπ(st,at)=∑l=0n−1γlrt+l+γnV^(st+n)−V^(st)\hat{A}_n^\pi(s_t, a_t) = \sum_{l=0}^{n-1} \gamma^l r_{t+l} + \gamma^n \hat{V}(s_{t+n}) - \hat{V}(s_t)

在实际训练中,选择某一个固定的 nn 非常困难,选 n=1n=1,偏差太大;选 n=∞n=\infty(即蒙特卡洛,等一整条轨迹结束),方差大到神经网络难以收敛。于是进一步推广到任意步组合优势估计器,提出了**广义优势估计(Generalized Advantage Estimation)**把所有不同步数的估计器 A^nπ\hat{A}_n^\pi 组合起来,做一个加权平均

A^GAEπ(st,at)=∑n=1∞wnA^nπ(st,at)\hat{A}_{\text{GAE}}^\pi(s_t, a_t) = \sum_{n=1}^\infty w_n \hat{A}_n^\pi(s_t, a_t)

nn 步优势估计器等于前 nn 步单步 TD 误差的指数折扣和 A^nπ(st,at)=∑l=0n−1γlδt+l\hat{A}_n^\pi(s_t, a_t) = \sum_{l=0}^{n-1} \gamma^l \delta_{t+l}

推导(以 n=2n=2 为例):

\delta_t + \gamma \delta_{t+1} &= \left( r_t + \gamma \hat{V}(s_{t+1}) - \hat{V}(s_t) \right) + \gamma \left( r_{t+1} + \gamma \hat{V}(s_{t+2}) - \hat{V}(s_{t+1}) \right) \\ &= r_t + \gamma r_{t+1} + \gamma^2 \hat{V}(s_{t+2}) - \hat{V}(s_t) \\ &= \hat{A}_2^\pi(s_t, a_t) \end{aligned}$$

为了让它成为一个合理的加权平均,权重必须满足:

  1. 归一化条件:∑n=1∞wn=1\sum_{n=1}^\infty w_n = 1;
  2. 越早截断方差越小,因此更希望给较小的 nn 分配更高的权重

为此,引入指数衰减权重:wn∝λn−1w_n \propto \lambda^{n-1}(其中 λ∈[0,1]\lambda \in [0, 1]),由等比数列求和:

∑n=1∞wn=∑n=1∞Cλn−1=C11−λ=1  ⟹  C=1−λ\sum_{n=1}^\infty w_n = \sum_{n=1}^\infty C \lambda^{n-1} = C \frac{1}{1-\lambda} = 1 \implies C = 1-\lambda

因此,合理的归一化权重分配为:wn=(1−λ)λn−1w_n = (1-\lambda)\lambda^{n-1} 。现在将权重 wn=(1−λ)λn−1w_n = (1-\lambda)\lambda^{n-1} 以及 nn 步优势的展开式 A^nπ(st,at)=∑l=0n−1γlδt+l\hat{A}_n^\pi(s_t, a_t) = \sum_{l=0}^{n-1} \gamma^l \delta_{t+l} 代入加权平均公式:

A^GAEπ(st,at)=∑n=1∞(1−λ)λn−1(∑l=0n−1γlδt+l)\hat{A}_{\text{GAE}}^\pi(s_t, a_t) = \sum_{n=1}^\infty (1-\lambda)\lambda^{n-1} \left( \sum_{l=0}^{n-1} \gamma^l \delta_{t+l} \right)

这里使用一个交换双重求和的顺序的代数技巧将不依赖于 nn 的项提取出来:

A^GAEπ(st,at)=∑l=0∞γlδt+l(1−λ)(∑n=l+1∞λn−1)\hat{A}_{\text{GAE}}^\pi(s_t, a_t) = \sum_{l=0}^\infty \gamma^l \delta_{t+l} (1-\lambda) \left( \sum_{n=l+1}^\infty \lambda^{n-1} \right)

计算内层关于 nn 的无穷等比级数(令 k=n−(l+1)k = n - (l+1)):

∑n=l+1∞λn−1=λl∑k=0∞λk=λl11−λ\sum_{n=l+1}^\infty \lambda^{n-1} = \lambda^l \sum_{k=0}^\infty \lambda^k = \lambda^l \frac{1}{1-\lambda}

将计算结果代回:

A^GAEπ(st,at)=∑l=0∞γlδt+l(1−λ)(λl11−λ)=∑l=0∞(γλ)lδt+l\hat{A}_{\text{GAE}}^\pi(s_t, a_t) = \sum_{l=0}^\infty \gamma^l \delta_{t+l} (1-\lambda) \left( \lambda^l \frac{1}{1-\lambda} \right) = \sum_{l=0}^\infty (\gamma\lambda)^l \delta_{t+l}

如果令时间步 t′=t+lt' = t+l,我们便得到了最终的 GAE 公式:

A^GAEπ(st,at)=∑t′=t∞(γλ)t′−tδt′\hat{A}_{\text{GAE}}^\pi(s_t, a_t) = \sum_{t'=t}^\infty (\gamma\lambda)^{t'-t} \delta_{t'}

引入 λ\lambda 后,(γλ)(\gamma\lambda) 就像一个新的折扣因子,当 λ=0\lambda = 0 时退化为 1 步 TD 估计器,当 λ=1\lambda = 1 时退化为蒙特卡洛优势估计。在实际中,通过调整 λ∈(0,1)\lambda \in (0, 1),就可以非常平滑地在 TD 与 MC 之间进行插值,以达到最优的偏差-方差平衡(PPO 算法通常默认设置 λ=0.95\lambda = 0.95)。


将 GAE 通用公式 ∑t′=t∞(γλ)t′−tδt′\sum_{t'=t}^\infty (\gamma\lambda)^{t'-t} \delta_{t'} 中的 δt′\delta_{t'} 展开为 rt′+γV^t′+1−V^t′r_{t'} + \gamma \hat{V}_{t'+1} - \hat{V}_{t'},并对同类项进行合并,会得到: A^GAE,tπ=−V^(st)+rt+γ(1−λ)V^(st+1)+γλrt+1+γ2λ(1−λ)V^(st+2)+…\hat{A}_{\text{GAE}, t}^\pi = - \hat{V}(s_t) + r_t + \gamma(1-\lambda)\hat{V}(s_{t+1}) + \gamma\lambda r_{t+1} + \gamma^2\lambda(1-\lambda)\hat{V}(s_{t+2}) + \dots

value-based

舍弃显式的策略网络,直接使用 value 来做出决策选择行动,此时我们需要学习的只有 value function(Q 或 V),该函数可以用表格或神经网络表示。

Policy Iteration

学习的是状态价值 Vπ(s)V^\pi(s),交替循环评估当前策略 π\pi 的真实价值 Vπ(s)V^\pi(s)和利用 Vπ(s)V^\pi(s) 产生一个更好的新策略 π′\pi'。因为要试探所有动作,所以必须知道环境的状态转移概率 P(s′∣s,a)P(s'|s,a)。

π′(s)←arg⁡max⁡a(r(s,a)+γ∑s′P(s′∣s,a)Vπ(s′))\pi'(s) \leftarrow \arg\max_a \left( r(s,a) + \gamma \sum_{s'} P(s'|s,a) V^\pi(s') \right)

也可以将推广到学习动作价值 Qπ(s,a)Q^\pi(s,a),此时策略改进可以简化为 π′(s)←arg⁡max⁡aQπ(s,a)\pi'(s) \leftarrow \arg\max_a Q^\pi(s,a)),算出当前策略 π\pi 的 Qπ(s,a)Q^\pi(s,a),利用 Qπ(s,a)Q^\pi(s,a) 产生一个更好的新策略 π′\pi' 。

Fitted Value Iteration

算法的目标是找最优价值函数 V∗(s)V^*(s),设置目标为 yi←max⁡ai(r(si,ai)+γE[Vϕ(si′)])y_i \leftarrow \max_{\mathbf{a}_i} \left( r(\mathbf{s}_i, \mathbf{a}_i) + \gamma \mathbb{E}[V_\phi(\mathbf{s}'_i)] \right)

为了找出能让右边达到最大的动作 ai\mathbf{a}_i,我们必须知道当我们在状态 si\mathbf{s}_i 下采取任意不同的动作时,分别会转移到哪个新状态 si′\mathbf{s}'_i。

Fitted Q-Iteration

将拟合目标从 V(s)V(\mathbf{s}) 换成了 Q(s,a)Q(\mathbf{s}, \mathbf{a}),目标值变为:yi←r(si,ai)+γmax⁡ai′Qϕ(si′,ai′)y_i \leftarrow r(\mathbf{s}_i, \mathbf{a}_i) + \gamma \max_{\mathbf{a}'_i} Q_\phi(\mathbf{s}'_i, \mathbf{a}'_i)

这个过程完全在神经网络内部完成,不需要任何物理环境的模拟或预测。我们不需要知道转移概率,只要有采样获得的样本就能拟合函数。

但是非线性函数逼近不能保证收敛,由于 ℓ∞\ell_\infty 贝尔曼收缩算子(缩减最大误差)与ℓ2\ell_2 最小二乘投影算子(网络拟合)的冲突,深度值迭代极易发散。后来的 DQN 在 FQI 的基础上引入了 Target Network 和 Replay Buffer 来缓解非线性函数逼近器的不稳定性。

如果只是 argmax的策略初始可能每次都采取相同的动作而不去发现更好的动作,于是采用 epsilon-greedy 的方法,以 ϵ\epsilon 概率随机选择其他动作之一,以 1−ϵ1-\epsilon 选择argmax的动作。这样即使初始时我们的 Q 函数很差也可以随机地做出更好的动作,一个非常常见的选择是在训练过程中改变 ϵ\epsilon 的值。还有一个方法是 Boltzmann Exploration ,将每个动作的 Q 值转换为采取该动作的概率,概率与 Q 值的指数成正比,给那些次优动作更多的探索机会,而几乎不给那些差的动作机会,后面还会专门讨论更复杂的探索方法。

DQN

image-20260725174825320

在环境里每走一步就收集一个样本加到 B\mathcal{B},然后立刻就从 B\mathcal{B} 里随机采样一个 Mini-batch,并对当前网络 ϕ\phi 进行一次梯度更新,每隔 NN 步,将当前网络 ϕ\phi 的参数直接复制给目标网络 ϕ′\phi'。

image-20260725174819768

先让智能体在环境里连续跑很多步,收集一大批数据存入 B\mathcal{B}(不更新网络)。在数据收集完后,完全不与环境交互,集中从 B\mathcal{B} 中采样,对当前网络 ϕ\phi 连续进行 KK 次梯度更新。

Replay Buffer(经验回放区)稳定了 ℓ2\ell_2 投影算子 Π\Pi,在没有回放区时,智能体产生的样本 (st,at,rt,st+1)(s_t, a_t, r_t, s_{t+1}) 具有极强的时序相关性。这违背了机器学习中“样本独立同分布”的假设,导致神经网络产生严重过拟合或灾难性遗忘,使得投影算子 Π\Pi 在拟合时极不稳定。通过把数据存入 B\mathcal{B},并进行随机均匀采样,削弱短程时间相关性,并平滑不断变化的数据分布

Target Network(目标网络)稳定了 ℓ∞\ell_\infty 贝尔曼算子 B\mathcal{B},每更新一次网络参数 ϕ\phi,拟合目标 y 就跟着改变的自举过程会在范数冲突中产生致命的正反馈调节。网络微小的拟合偏差会立刻反映在目标值上,并在下一次更新中被放大,最终导致发散。引入一个参数暂时冻结的目标网络 ϕ′\phi',在几百个步长内,ϕ′\phi' 保持静止不变的,将强化学习的自举问题,在一段时间内降维改造成了标准的监督学习回归问题。Target Network 在一段时间内固定 bootstrap target,缓解 moving-target feedback,提高稳定性,但不保证每次同步前拟合收敛,也不提供一般收敛保证。

Double Q-learning

数学上存在一个不等式:E[max⁡(X1,X2)]≥max⁡(E[X1],E[X2])\mathbb{E}[\max(X_1, X_2)] \ge \max(\mathbb{E}[X_1], \mathbb{E}[X_2])

而在标准 DQN 中 Q function 在逼近 QQ 值时必然存在噪声(误差),我们知道 q-learing 目标值为 y=r+γmax⁡a′Qϕ′(s′,a′)=r+γmax⁡a′Qϕ′(s′,arg⁡max⁡a′Qϕ′(s′,a′))y = r + \gamma \max_{a'} Q_{\phi'}(s', a') = r + \gamma \max_{a'} Q_{\phi'}\Big( s', \arg\max_{a'} Q_{\phi'}(s', a')\Big)

也就构成了与上方不等式类似形式。由于自举机制,这个高估的误差会随着时序反向传播,导致所有状态的 QQ 值都被过高估计。这里高估的原因就在于选择动作(arg⁡max⁡\arg\max)和评估动作价值(Qϕ′Q_{\phi'})都是由同一个目标网络 ϕ′\phi' 完成的。如果它高估了某个动作,它就会选这个动作并直接给出高估的分数。

所以我们可以用两个噪声独立的网络(两个 Q function)来相互制约,一个负责选动作 a∗=arg⁡max⁡a′QA(s′,a′)a^* = \arg\max_{a'} Q_A(s', a'),一个负责评估价值Value=QB(s′,a∗)\text{Value} = Q_B(s', a^*)。这样,即使网络 A 因为噪声意外选了一个其实很差的动作,由于网络 B 的噪声与 A 独立,网络 B 大概率会给这个动作一个客观(较低)的分数,从而中和了过高估计。

in practice

在实践中会使用实时更新的 Current Network (QϕQ_\phi) 和 延迟复制的 **Target Network (Qϕ′Q_{\phi'})**作为两个Q function的来源,因为如果要训练两个完全独立的网络,计算量和内存会翻倍。虽然它们不是完全独立的(有延迟相关性),但它们的参数在大部分时候是不同的,噪声也是去相关的。最终合并出的 DDQN 目标值公式变为: y=r+γQϕ′(s′,arg⁡max⁡a′Qϕ(s′,a′))y = r + \gamma Q_{\phi'}\Big(s', \arg\max_{a'} \mathbf{Q_\phi}(s', a')\Big)。这样可以解决一部分过高估计的问题,但当然不是所有。

多步 Q-learning

目标值需要累加后续多步的真实历史奖励: yt=rt+γrt+1+γ2rt+2+⋯+γNmax⁡a′Q(st+N,a′)y_{t} = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \dots + \gamma^N \max_{a'} Q(s_{t+N}, a')

  • 如果learning off-policy,那么后续几步的真实奖励(如 rt+1,rt+2r_{t+1}, r_{t+2})是智能体过去在实际探索中产生的,可能产生较大偏差。

为了修正这个偏差,有三种解决方案:

  • 直接把数据集里的 NN 步奖励加起来算,假装它没有偏差。在实践中(例如早期的 NN-step DQN 变体)往往出奇地管用。因为如果我们的行为策略 μ\mu 和当前目标策略 π\pi 差别不太大(比如 ϵ\epsilon 很小),这种偏差在可接受范围内。

  • 一旦在历史轨迹中发现某个动作 at′a_{t'} 与当前最优动作不符,就立刻把后面的累加截断(强制将 NN 变小),直接在这一步进行 QQ 值自举。

  • 在累加后续每一步奖励时,都乘上新旧策略的概率比值(重要性权重) ρt′=π(at′∣st′)μ(at′∣st′)\rho_{t'} = \frac{\pi(a_{t'}|s_{t'})}{\mu(a_{t'}|s_{t'})},以此来修正概率分布的偏差。

为了彻底解决“重要性采样方差爆炸”和“截断轨迹太保守”的矛盾,DeepMind 2016 论文提出了 Retrace(λ\lambda) 算法,将重要性采样的乘积权重限制(截断)在 11 以下:cs=λmin⁡(1,π(as∣ss)μ(as∣ss))c_s = \lambda \min\left(1, \frac{\pi(a_s|s_s)}{\mu(a_s|s_s)}\right)。

Q-learning in continuous space

在经典的 Q-learning(如 DQN)中,计算目标值时需要求解一个核心项:y=r+γmax⁡a′Q(s′,a′)y = r + \gamma \max_{a'} Q(s', a')

在每一次迭代中对一个任意复杂的神经网络 Q(s,a)Q(s, a) 求解连续空间中全局最大值 max⁡aQ(s,a)\max_a Q(s, a),在数学上是一个极其困难且计算昂贵的非线性连续优化问题。

随机优化法

不追求求出绝对精确的数学最大值,而是通过随机采样和演化算法来近似求解 max⁡aQ(s,a)\max_a Q(s, a)

  • 随机采样:直接在连续动作空间中,随机均匀采样 NN 个动作 {a1,a2,…,aN}\{a_1, a_2, \dots, a_N\},计算它们对应的 QQ 值,并取其中的最大值作为近似:max⁡aQ(s,a)≈max⁡{Q(s,a1),…,Q(s,aN)}\max_{\mathbf{a}} Q(\mathbf{s}, \mathbf{a}) \approx \max \{ Q(\mathbf{s}, \mathbf{a}_1), \dots, Q(\mathbf{s}, \mathbf{a}_N) \}

  • 交叉熵方法 (Cross-Entropy Method, CEM) :

  1. 首先在动作空间中,根据一个高斯分布随机采样 NN 个动作。
  2. 计算这 NN 个动作的 QQ 值,选出表现最好的前 MM 个动作。
  3. 利用这 MM 个动作的均值和方差,重新拟合一个新的高斯分布。
  4. 从新的高斯分布中再次采样,重复上述步骤。经过几次迭代,采样分布会迅速收敛到最优动作附近。
  • 在动作空间维度较低时(通常在 40 维以内)效果很好,如果动作维度过高,采样效率会急剧下降。

设计易于优化的 Q 函数结构

抛弃通用的全连接神经网络,人为限制 QQ 函数的数学结构,使其天生就存在易于计算的解析最大值,比如NAF (Normalized Advantage Functions)。NAF 巧妙地将 QQ 函数强制约束为一个关于动作 aa 的二次型(Quadratic)函数:Qϕ(s,a)=−12(a−μϕ(s))TPϕ(s)(a−μϕ(s))+Vϕ(s)Q_\phi(\mathbf{s}, \mathbf{a}) = -\frac{1}{2}(\mathbf{a} - \mu_\phi(\mathbf{s}))^T P_\phi(\mathbf{s})(\mathbf{a} - \mu_\phi(\mathbf{s})) + V_\phi(\mathbf{s})

  • 神经网络设计为输入状态 s\mathbf{s},输出三个部分

    1. μϕ(s)\mu_\phi(\mathbf{s}):动作向量。

    2. Pϕ(s)P_\phi(\mathbf{s}):一个正定矩阵。

    3. Vϕ(s)V_\phi(\mathbf{s}):状态价值。

因为 Pϕ(s)P_\phi(\mathbf{s}) 是正定的,所以前面的二次型项 −12(a−μ)TP(a−μ)-\frac{1}{2}(\mathbf{a} - \mu)^T P (\mathbf{a} - \mu) 永远小于或等于 0。显然,当且仅当 a=μϕ(s)\mathbf{a} = \mu_\phi(\mathbf{s}) 时,这一项达到最大值 00。这个方法计算效率极高,完全不需要任何优化循环,一步就能拿到最大值。但表达能力会受限,因为它强行假设了 QQ 值在动作空间上呈单峰,这在面对复杂的多峰动作分布时会失效。

学习一个近似的最大值生成网络

既然直接求 max⁡\max 很难,那我们就专门训练第二个神经网络 μθ(s)\mu_\theta(\mathbf{s}),输入状态 s\mathbf{s},输出能够让 QQ 网络达到最大值的动作。

image-20260726182608032

DDPG 本质上就是一种将 Q-learning 推广到连续动作空间的 Deterministic Actor-Critic 算法。

策略网络 μθ\mu_\theta 的目标是让策略网络输出的动作能让 QQ 值最大,优化目标 maxθEsQϕ(s,μθ(s))max_\theta \mathbb{E}_{s} Q_\phi(\mathbf{s}, \mu_\theta(\mathbf{s}))。由于 QQ 网络对动作 a\mathbf{a} 是完全可导的,我们可以利用微积分的链式法则直接将 QQ 值的梯度反向传播给策略网络 dQϕdθ=dadθdQϕda\frac{dQ_\phi}{d\theta} = \frac{d\mathbf{a}}{d\theta} \frac{dQ_\phi}{d\mathbf{a}}。利用确定性策略梯度,朝向 QQ 值增大的方向更新策略 θ←θ+β∑jdμdθ(sj)dQϕda(sj,μ(sj))\theta \leftarrow \theta + \beta \sum_{j} \frac{d\mu}{d\theta}(\mathbf{s}_j) \frac{dQ_\phi}{d\mathbf{a}}(\mathbf{s}_j, \mu(\mathbf{s}_j))。

HW2:Policy Gradients

为什么这里的 Policy Gradient with Baseline 已经有了拟合 Value 的网络,也通过它算出了 Advantage,甚至用了 GAE,却仍归类为PG而不是actor-critic?

Sutton 在其《Reinforcement Learning: An Introduction》一书中是这样界定的:

虽然带 Baseline 的 REINFORCE 方法同时学习了策略和状态价值函数,但我们不认为它是一种 Actor-Critic 方法。因为它的价值函数只作为 Baseline,而没有用于自举(依据后续状态的估计值更新当前状态的价值估计),只作为待更新价值估计的状态所对应的基线。

在 pg_agent.py 中,虽然 Actor 使用了 GAE 来计算优势,但是价值网络 V^ϕ(s)\hat{V}_\phi(s)(即 Baseline)的目标值使用的是真实的蒙特卡洛累积回报:y_i = q_values(其中 q_values 是通过将整局轨迹的所有即时奖励一路累加到结尾算出来的),必须收集完一整条完整的轨迹去拟合 Baseline,在本质上依然属于蒙特卡洛策略梯度方法。

在这里的 Actor-Critic 中, Critic 网络更新的目标值不再是整局的 q_values,而是纯粹的单步自举时序差分目标yt=rt+γV^ϕ′(st+1′)y_t = r_t + \gamma \hat{V}_{\phi'}(s'_{t+1}) 用“当前即时奖励 + 下一步状态的估计值”来更新自己,这使得整个算法可以做到真正的单步在线更新,不再需要完整的轨迹。

HW3:DQN & SAC

我们训练 Actor(策略网络)的最终目标,是让它选出的动作 aa 能获得最大的 QQ 值:max⁡θEa∼πθ[Qϕ(s,a)]\max_\theta \mathbb{E}_{a \sim \pi_\theta}[Q_\phi(s, a)]。在深度学习的计算图中,“采样”是一个非连续、不可导的操作。那么如果动作 aa 是从概率分布 πθ\pi_\theta 中采样出来的,反向传播的梯度一旦碰到“采样”这个节点,就会立刻断掉,无法传回给 Actor 的参数 θ\theta。

REINFORCE(得分函数估计)

在基础的 Policy Gradient(比如 PPO、A2C)中,为了绕过这个不可导的采样节点可以使用一个对数导数技巧:∇θE[Q]=E[Q(s,a)⋅∇θlog⁡πθ(a∣s)]\nabla_\theta \mathbb{E}[Q] = \mathbb{E}[Q(s, a) \cdot \nabla_\theta \log \pi_\theta(a|s)]

  • 在这个公式里,Critic 网络 Q(s,a)Q(s, a) 只输出一个标量数字(比如得 10 分还是得 -5 分),网络不关心 QQ 函数内部的梯度长什么样。这种方法虽然可行,但方差极大,效率很低。

重参数化技巧(Reparameterization Trick)

为了能利用 Critic 的梯度,我们使用重参数化技巧把“带参数的采样”解耦成了“确定性公式 + 纯外部噪声”: aθ=μθ(s)+σθ(s)⋅ϵ(其中 ϵ∼N(0,1))a_\theta = \mu_\theta(s) + \sigma_\theta(s) \cdot \epsilon \quad (\text{其中 } \epsilon \sim \mathcal{N}(0, 1))

  • 现在,动作 aθa_\theta 变成了一个完全确定且处处可导的数学公式,所有的随机性(不可导性)都被扔给了那个不需要求导的外部常数 ϵ\epsilon。梯度可以畅通无阻地从 QQ 网络穿过动作 aa,直接流回 Actor 网络 μθ\mu_\theta 和 σθ\sigma_\theta。

既然我们想要最大化 QQ 值,那我们直接把 QQ 当作目标函数对参数 θ\theta 求导就行了。根据链式法则有∇θQϕ(s,aθ)=∂Qϕ∂a⏟Critic 指明的方向⋅∂aθ∂θ⏟Actor 的执行能力\nabla_\theta Q_\phi(s, a_\theta) = \underbrace{\frac{\partial Q_\phi}{\partial a}}_{\text{Critic 指明的方向}} \cdot \underbrace{\frac{\partial a_\theta}{\partial \theta}}_{\text{Actor 的执行能力}}

  • 为了用优化器最大化 QQ,我们直接让 Loss 等于 −Q-Q。LossActor=−Qϕ(s,aθ)\text{Loss}_{\text{Actor}} = -Q_\phi(s, a_\theta)

SAC

SAC 是一种基于最大熵强化学习框架的、Off-policy的 Actor-Critic 深度强化学习算法。

传统的强化学习目标是:“找到一个策略,使期望奖励总和最大化”,而 SAC 目标是:“找到一个策略,使期望奖励总和最大化的同时,策略的随机性(熵)也最大化”。目标函数就变成了:

J(π)=∑tE(st,at)∼π[r(st,at)+αH(π(⋅∣st))]J(\pi) = \sum_t \mathbb{E}_{(s_t, a_t) \sim \pi} \left[ r(s_t, a_t) + \alpha \mathcal{H}(\pi(\cdot|s_t)) \right]

SAC 首先将当前状态 ss 输入 Actor,Actor 输出一个分布,采样得到动作 aa。执行动作 aa,得到奖励 rr、下一步状态 s′s' 和结束标志 dd,将元组 (s,a,r,s′,d)(s, a, r, s', d) 存入 Replay Buffer,重复这个过程多次。然后从 Buffer 中随机抽取一个 Batch 的数据来先后更新Critic、Actor、Target Critic 网络,针对每一个 s′s',用 Actor 网络在 s′s' 下采样一个未来的假想动作 a′a',计算这个假想动作的熵:−log⁡π(a′∣s′)-\log \pi(a'|s')。用两个 Target Critic 网络评估这个动作,并取最小值:min⁡(Qtarg1(s′,a′),Qtarg2(s′,a′))\min(Q_{targ1}(s', a'), Q_{targ2}(s', a')),计算目标值得 y=r+γ(1−d)[min⁡(Qtarg1,2)+αH]y = r + \gamma (1-d) \left[ \min(Q_{targ1, 2}) + \alpha \mathcal{H} \right]。将实际状态 ss 和实际动作 aa 输入当前两个 Critic 网络,得到当前的预估值 Q1(s,a)Q_1(s,a) 和 Q2(s,a)Q_2(s,a),分别计算它们与目标值 yy 的均方误差,梯度下降更新 Critic 网络的参数。Actor 的目标是让 Q 值最大,同时熵也最大。将状态 ss 输入 Actor,通过重参数化采样得到新动作 anewa_{\text{new}}。用更新后的 Critic 评估这个新动作:Q评估=min⁡(Q1(s,anew),Q2(s,anew))Q_{\text{评估}} = \min(Q_1(s, a_{\text{new}}), Q_2(s, a_{\text{new}})),计算 Actor Loss(最小化负 Q 值和负熵):Lossactor=−[Q评估−αlog⁡π(anew∣s)]\text{Loss}_{\text{actor}} = -\left[ Q_{\text{评估}} - \alpha \log \pi(a_{\text{new}}|s) \right]。梯度下降更新 Actor 网络的参数,由于重参数化,这里的梯度会穿过 Q 网络,流回 Actor 网络。最后运行 soft_update_target_critic(tau)对目标网络软更新,让两个 Target Critic 网络的参数缓慢向当前的 Critic 网络靠近,让训练更加平滑。

SAC 可以看作是 DQN 思想在连续动作空间的进化版。它用 Actor 解决了连续动作无法 max⁡\max 的问题,用双 Q 网络解决了Q值的高估问题,用最大熵解决了探索和稳定性的问题。作为 Off-policy 算法,反复利用历史数据,实现稳定训练下极高的样本效率。

← 全部文章 edit on github →