Reading

Reinforcement Learning: Policy Gradient 与 Advantage Estimation


Fanyi Pu · GPT‑5.6 Sol · GPT-6 Astra

· Updated

Reinforcement learning 中,一个 action 不只带来眼前的 reward,还会改变后续能遇到的 state。这篇从轨迹的期望 return 出发,依次推导 REINFORCE、reward-to-go、baseline、actor-critic 和 GAE,回答如何从采样轨迹构造策略的梯度。

系列导读 · 下一篇

Problem setup

先明确策略在优化什么,再区分几类算法如何表示和改进这个策略。

Definition

我们把 ⟨st,at⟩ 打包起来,在 Markov 环境和只依赖当前 state 的策略下,其实它就构成了一个 Markov chain。记一条轨迹为 τ=(s1,a1,…,sT,aT,sT+1):

pθ(τ)=p(s1)∏t=1Tπθ(at∣st)P(st+1∣st,at).

这里 πθ(at∣st) 是策略,P 是环境转移;初始状态分布与环境转移不依赖 θ。后文也把整条轨迹的分布 pθ(τ) 简记为 πθ(τ)。

对于 learning objective:

θ∗=arg⁡maxθJ(θ)=arg⁡maxθEτ∼πθ[r(τ)].

我们定义我现在在 st,做了 action at,然后按照 π 所得到的期望总 reward 为

Qπ(st,at)=Eπ[∑t′=tTr(st′,at′)∣st,at].

然后我们定义 V 表示现在我在 st 的时候遵循 π 所得到的期望总 reward:

Vπ(st)=Eπ[∑t′=tTr(st′,at′)∣st]=Eat∼π(⋅∣st)[Qπ(st,at)].

先考虑有限时域、不打折的 return;有限时域中把剩余时间也视为 state 的一部分,并令终止状态的 value 为 0。后面再引入 discount factor。

Types of Algorithms

  • Policy Gradients:跟往常一样,就是求导然后去做优化。
  • Value-based:去估计最优的 Q 或 V,然后通过这个推出 π。
  • Actor-critic:通过估计当前策略的 Q^ 和 V^,然后用它们指导策略优化。
  • Model-based RL:学习或使用环境的转移、reward 模型,再借助模型规划或优化策略。

Policy Gradient Algorithms

Direct policy differentiation

记整条轨迹的总 reward 为 r(τ)=∑t=1Tr(st,at),我们想最大化它在当前策略下的期望:

J(θ)=Eτ∼πθ[r(τ)]=∫πθ(τ)r(τ)dτ.

采样得到一条 τ 后,很容易觉得:既然有它的概率 πθ(τ),又有它的 reward r(τ),那就直接最大化两者的乘积。这里漏掉了积分:πθ(τ)r(τ) 只是被积函数在这条轨迹上的取值,目标 J(θ) 是对所有轨迹的积分。 如果能算出整个积分,直接对 J 求导当然可以;但只拿到一条采样轨迹时,直接对这个乘积求导,并不能给出整个目标梯度的无偏估计。

实际训练通常无法遍历所有轨迹,只能按当前策略采样。我们希望每条样本给出一个梯度,平均起来就能无偏地估计整个目标的梯度。下面推导的目的,就是把 ∇θJ(θ) 写成一个可以用采样估计的期望,从而确定每条样本应该贡献什么梯度。

沿用环境与 reward 不依赖 θ 的假设,在积分与求导可以交换的条件下,利用 ∇θlog⁡πθ(τ)=∇θπθ(τ)/πθ(τ),得到 REINFORCE (Williams, 1992) 的梯度表达式:

∇θJ(θ)=∫r(τ)∇θπθ(τ)dτ=∫πθ(τ)∇θπθ(τ)πθ(τ)r(τ)dτ=Eτ∼πθ[r(τ)∇θlog⁡πθ(τ)].

这就告诉我们,对 τ∼πθ,r(τ)∇θlog⁡πθ(τ) 是所需的无偏梯度估计。为了用反向传播得到它,取下面的 loss (Achiam, 2018),求导时固定采到的轨迹和 reward:

ℓθ(τ)=−r(τ)log⁡πθ(τ),−∇θℓθ(τ)=r(τ)∇θlog⁡πθ(τ).

负号用于把最大化写成梯度下降。使用 log⁡πθ(τ) 的理由就在这里:这个 loss 的负梯度,在采样所用的策略参数处,是目标梯度的无偏估计。

实现时,由于初始状态分布和环境转移与 θ 无关,有

∇θlog⁡πθ(τ)=∑t=1T∇θlog⁡πθ(at∣st).

因此,对一条轨迹,把实际采到的各步 action 的 log probability 相加,再乘总 reward 即可:

python
trajectory_log_prob = action_log_probs.sum()
loss = -trajectory_return.detach() * trajectory_log_prob

这里 trajectory_return 是总奖励,求导时作为常量;action_log_probs 保留策略参数的计算图。对一个 batch,再平均各条轨迹的 loss。这个估计虽然无偏,但 variance 很高,接下来考虑怎么减小它。

Reduce Variance

仔细观察这个式子,其实这玩意儿是 MLE 那个梯度对 r(st,at) 加权了:

∇θJ(θ)=Eτ∼πθ[∑t=1TΨt∇θlog⁡πθ(at∣st)]

当前我们是有:Ψt=∑t′=1Tr(st′,at′)

Don't Let the Past Distract You

一种简单的方法来减小 variance,是我们令 Ψt=∑t′=tTr(st′,at′)

因为其实对于 at 来说,他做啥对于 t 之前的 reward 来说是不具有参考价值的。因此我们主要考虑后面的 reward。这玩意儿直觉上挺清楚的,但数学上想了半天才想明白为啥是对的。主要参考了这篇文章 (Achiam, 2018)。

证明的不造为啥让我想起了 MLE。主要用到的就是一个叫做 EGLP lemma 的东西(其实好像用这个 lemma 需要积分和导数的可交换性,貌似 (Hogg et al., 2013) 里写挺详细的):

Ex∼Pθ[∇θlog⁡Pθ(x)]=∫Pθ(x)∇θlog⁡Pθ(x)dx=∫Pθ(x)∇θPθ(x)Pθ(x)dx=∇θ∫Pθ(x)dx=0

其实跟 MLE 是一样的嘛:

E[∂∂θlog⁡L(x∣θ)]=0

其实我们是要证明嘟是:

Eτ∼πθ[∑t=1T∑t′<tr(st′,at′)∇θlog⁡πθ(at∣st)]=0

也就是要证明当 t′<t 这个时候:

Est,at,st′,at′∼πθ[r(st′,at′)∇θlog⁡πθ(at∣st)]=0

那么中心思想其实就是咋来区分 t′<t 捏,我们考虑 t′<t 是先 reward,再选择:

Est′,at′∼πθ[r(st′,at′)⋅Est,at∼πθ(⋅∣st′,at′)[∇θlog⁡πθ(at∣st)∣st′,at′]]

关键是先固定过去的历史,再对当前 action 取条件期望:给定 st,有 Eat∼πθ(⋅∣st)[∇θlog⁡πθ(at∣st)]=0。过去的 reward 可以和当前 state 相关,但不会由之后采样的 action 改写。

所以说最终结果是整个期望 0。

Introducing Baselines

另一个优化是我们考虑加入 baseline。这个直觉就更对了。就是我们考虑把 r(s,a) 替换成 r(s,a)−b。这里减去的是梯度估计器中的 baseline,不是在改环境的 reward;baseline 不依赖当前 action 时,它乘上 score gradient 的期望为零。

不改变期望,不代表方差不变:baseline 的选择会改变梯度估计的波动。先看常数 baseline 的最优取值。

最小化梯度估计方差的常数 baseline

我们考虑

∇θJ(θ)=Eτ∼πθ[∇θlog⁡πθ(τ)⋅(r(τ)−b)]

的方差(对于向量梯度,这里取各分量方差之和)

σ2=Eτ∼πθ[‖∇θlog⁡πθ(τ)⋅(r(τ)−b)‖2]−‖Eτ∼πθ[∇θlog⁡πθ(τ)⋅(r(τ)−b)]‖2=Eτ∼πθ[‖∇θlog⁡πθ(τ)⋅(r(τ)−b)‖2]−‖Eτ∼πθ[∇θlog⁡πθ(τ)⋅r(τ)]‖2

我们解

∂∂bσ2=∂∂bEτ∼πθ[‖∇θlog⁡πθ(τ)⋅(r(τ)−b)‖2]=0

可以得到

b=Eτ∼πθ[‖∇θlog⁡πθ(τ)‖2⋅r(τ)]Eτ∼πθ[‖∇θlog⁡πθ(τ)‖2]

这啥捏,这其实是 reward 的加权期望。

但其实这个 baseline 挺难算的,所以我们通常不会用这个最优的 baseline。而是去找一个相对比较好的。

Actor Critic Methods

前面的 reward-to-go 和 baseline 都在调整每个 action 的梯度权重。接下来用 value function 估计这个权重:先得到 advantage,再讨论 critic 的训练和 GAE。

General Idea

我们回到式子

∇θJ(θ)≈1N∑i=1N∑t=1TΨi,t∇θlog⁡πθ(ai,t∣si,t).

我们观察这个 Ψt(先不考虑 baseline):Ψt=∑t′=tTr(st′,at′)。

我们发现一件事情,就是它其实是在估计 Qπ(st,at)。也就是我做了这个 action,之后继续按照 π,会得到一个什么样的结果。这个和是 Qπ(st,at) 的一个无偏估计。

于是我们可以尝试 Ψt=Qπ(st,at)。我的理解是,如果能算出这个条件期望,就可以去掉后续轨迹采样带来的部分噪声。

然后我们考虑 baseline。我们大概这么想,就是某个操作比我现在的平均效果好,那么 Ψt 要大于 0,让它的概率增大。如果比我现在的 π 还要垃圾,就减小这个 action 的概率。

所以我们考虑 b=Vπ(st),于是我们定义:

Aπ(st,at)=Qπ(st,at)−Vπ(st).

也就是做了这个操作,相比当前策略的平均表现能好多少。然后

∇θJ(θ)≈1N∑i=1N∑t=1TAπ(si,t,ai,t)∇θlog⁡πθ(ai,t∣si,t).

在采样策略就是 π=πθ、advantage 使用真值或条件无偏估计的情况下,这东西是无偏的。那我们考虑怎么算这个 Aπ(st,at)。

我们考虑

Qπ(st,at)=r(st,at)+Est+1∼P(⋅∣st,at)[Vπ(st+1)].

所以说

Aπ(st,at)=Est+1∼P(⋅∣st,at)[r(st,at)+Vπ(st+1)−Vπ(st)].

也就是说,r(st,at)+Vπ(st+1)−Vπ(st) 是对 Aπ(st,at) 的一个条件无偏估计。这里需要真实的 Vπ;换成学出来的近似值后,一般会引入 bias。

也就是我们现在的问题来到了怎么搞这个 Vπ,最直接的方法是大力去做,然后求平均。

当然,更成熟的想法是我们可以训一个模型 ϕ 去预测这个 Vπ。我们考虑 loss,一种直接的方法是:

L(ϕ)=12∑i=1N∑t=1T‖V^ϕπ(si,t)−∑t′=tTr(si,t′,ai,t′)‖2.

但是我们考虑有没有方差更低一些的方法,就是用 r(st,at)+V^ϕπ(st+1) 来代替整个求和。这就变成了 TD error 的平方:

L(ϕ)=12∑i=1N∑t=1T‖V^ϕπ(si,t)−sg[r(si,t,ai,t)+V^ϕπ(si,t+1)]‖2.

这里 sg 表示 stop-gradient:当前更新把 bootstrap target 当作固定目标。它降低了对完整 Monte Carlo return 的依赖,但 target 本身的估计误差也会传过来。

Introducing Discount Factors

有时候我们会考虑 T→∞ 的情况。为了在 reward 有界时让总 return 也是有穷的,我们可以取 0≤γ<1,增加一个 discount factor。这个其实是比较直觉的,因为现在给你一块钱和以后给你一块钱,肯定选马上要。

r(τ)=∑t=1Tγt−1r(st,at).

那么我们就需要稍稍改一改式子。此时 Vπ,γ 从当前时刻开始计算折扣 return:

Aπ,γ(st,at)=Est+1∼P(⋅∣st,at)[r(st,at)+γVπ,γ(st+1)−Vπ,γ(st)].

这时候其实我们在估计导数的时候,要小心折扣的位置。直接用整条轨迹的 return,可以写成:

∇θJ(θ)≈1N∑i=1N(∑t=1Tγt−1r(si,t,ai,t))(∑t=1T∇θlog⁡πθ(ai,t∣si,t)).

利用 reward-to-go,也可以使用下面的估计量:

g^=1N∑i=1N∑t=1Tγt−1∇θlog⁡πθ(ai,t∣si,t)(∑t′=tTγt′−tr(si,t′,ai,t′)).

外层的 γt−1 与 return 内的 γt′−t 作用不同,不能直接漏掉。两种估计量的期望相同,同一批轨迹上算出的数值不必相同。Thomas (Thomas, 2014) 专门讨论了 discount 与 policy gradient bias 的问题,有空填坑。

Implementation Details

在真正写代码的时候,我们需要构造一个能产生 policy gradient 的 surrogate。和前面 REINFORCE 的 loss 一样,考虑一个看似无意义的函数:

J~(θ)=1N∑i=1N∑t=1Tsg[A^ϕ(si,t,ai,t)]log⁡πθ(ai,t∣si,t).

求导时,采到的 state、action 和 A^ϕ 都作为常量,所以这个 ∇θJ~(θ) 就是相应的 actor gradient 估计。也就是说,我们其实是借助自动求导程序去计算前面推出来的更新。它的数值不是 J(θ);critic 若有误差,也不能直接声称这个梯度无偏。对于前面从初始状态定义的 discounted objective,还要给第 t 项乘上 γt−1。

也就是说我们要训练两个网络 θ 和 ϕ。用当前策略采到的数据集 Dk,一轮更新里的两个目标可以写成:

LV(ϕ)=E^(s,a,r,s′)∈Dk[12‖sg⁡[r+γV^ϕ(s′)]−V^ϕ(s)‖2],Lπ(θ)=−E^(s,a)∈Dk[sg⁡[A^ϕ(s,a)]log⁡πθ(a∣s)].

两者都用梯度下降;actor loss 前面的负号对应最大化 surrogate。这里沿用不额外写外层时间权重的实现记法,具体采样与折扣约定仍要和目标一致。

Generalized Advantage Estimation

Actor-critic 用 advantage 判断一个 action 比当前策略的平均表现好多少。实际训练时,真实的 Q 和 V 都未知,我们需要从采到的轨迹和 critic 的预测中构造 A^t。

我们需要决定观察多少步真实 reward,再让 critic 预测剩下的收益。只观察一步,估计很依赖 critic;一直观察到终点,又会混入后续 action 和环境带来的随机性。Schulman 等人提出的 Generalized Advantage Estimation(GAE) (Schulman et al., 2015) 把不同步数的估计结合起来,用 λ 调节两者的取舍。

From one step to multiple steps

固定采样策略 π 和 discount factor γ,记 rt=r(st,at),把 critic 对 Vπ,γ(st) 的预测简记为 vt=V^ϕ(st)。在同一条轨迹上,我们可以在不同位置交给 critic 接手:

从一步到多步:逐渐推迟 bootstrap 的位置三行分别展示一步、两步和三步 advantage 估计。实线框表示实际观察到的折扣 reward,虚线框表示由 critic 预测的剩余收益;每一行最后都减去当前状态的 value。向下看时,实际 reward 覆盖的时间变长,交给 critic 接手的位置变晚。已观察到的 rewardcritic 预测剩余收益
A^t(1)=
rt
+
γ1vt+1
−vt
A^t(2)=
rt
+
γrt+1
+
γ2vt+2
−vt
A^t(3)=
rt
+
γrt+1
+
γ2rt+2
+
γ3vt+3
−vt
向下:用更多实际 reward 替换对未来的预测
每行都是“已观察的收益 + 预测的剩余收益 − 当前状态的 baseline”。GAE 接下来会把这些不同长度的估计加权平均。

观察 n 步后,前半段用实际 reward,后半段用 vt+n 补足。这种用估计值预测尚未观察到的收益的做法叫做 bootstrap。再减去当前状态的 baseline vt,得到 n-step advantage estimate:

A^t(n)=∑l=0n−1γlrt+l⏟observed rewards+γnvt+n⏟bootstrap−vt.

n=1 时,它就是 TD residual:

δt=rt+γvt+1−vt.

增加 n,就是用更多实际发生的 reward 替换 critic 对未来的预测。这样通常能减少 bootstrap 误差的影响,但也纳入了更多后续轨迹的随机性。

Mixing the horizons

GAE 为这些不同长度的估计分配指数衰减的权重。先考虑 0≤λ<1:

A^tGAE(γ,λ)=(1−λ)∑n=1∞λn−1A^t(n).

这些权重之和为 1。较小的 λ 把权重集中在短步数估计上;较大的 λ 让长步数估计参与得更多。对于已经终止的 episode,可以把终止后的 reward 和 value 都延拓为 0。

把各个 n-step estimate 展开并合并,GAE 就变成了 TD residual 的折扣和:

A^tGAE(γ,λ)=∑l=0∞(γλ)lδt+l=δt+γλδt+1+(γλ)2δt+2+⋯.

前一个式子说明 GAE 如何结合不同步数的估计,后一个式子更方便计算。λ=1 时使用后一个表达式,或取前一个表达式在 λ→1 时的极限。

从 n-step average 到 TD residual sum

把 TD residual 展开后,中间的 value 项相消:

A^t(n)=∑l=0n−1γlδt+l=∑l=0n−1γlrt+l+γnvt+n−vt.

δt+l 出现在所有 n≥l+1 的估计里,因此它在加权平均中的系数是

(1−λ)γl∑n=l+1∞λn−1=(γλ)l.

若只采到后续 H 步,有限长度版本把剩余权重交给最长的估计:

A^tGAE,H=(1−λ)∑n=1H−1λn−1A^t(n)+λH−1A^t(H)=∑l=0H−1(γλ)lδt+l.

其中 H=1 时只有 A^t(1)。最长那一项仍可以在采样边界使用 critic 的预测。

What λ controls

λ使用的信息主要取舍
0一步 reward 和下一状态的 value,A^t=δt通常方差较低,更依赖 critic 的准确性
0<λ<1不同步数估计的加权平均在 bootstrap 误差和轨迹采样噪声之间折中
1若采到真正终止,使用完整 discounted return 减去 vt后续收益完全来自采样,通常方差较高

Bootstrap 可能把 critic 的预测误差带入 policy gradient。若 critic 恰好等于真实的 Vπ,γ,一步 TD 就已经是 advantage 的条件无偏估计;在同样的采样与边界条件下,其他 λ 也不会额外引入这种 bias。

γ 和 λ 的作用不同:γ 定义本节要估计的 discounted return;固定 γ 后,λ 调节估计这个量时观察多长的轨迹。改变 λ 不会改变真实 advantage 的定义。

Advantage bias 与 policy-gradient bias

GAE 最终要放进 actor 的梯度里,因此还要区分 advantage 数值的误差与它给 policy gradient 带来的 bias。原论文把满足下面条件的估计量称为 γ-just:

E[A^t∇θlog⁡πθ(at∣st)]=E[Aπθ,γ(st,at)∇θlog⁡πθ(at∣st)].

当 vt=Vπ,γ(st) 时,

E[δt∣st,at]=Aπ,γ(st,at).

此时一步估计已经满足要求。使用近似 critic 并且 λ<1 时,bootstrap 误差一般会传入 policy gradient。

记完整的 discounted return 为 Gt。当 λ=1 且采到真正终止时,A^t=Gt−vt。即使 vt 不准确,Gt 仍是 discounted Q 的条件无偏估计,而 vt 是不依赖当前 action 的 baseline,所以这个估计量仍是 γ-just。但它的条件期望是 Qπ,γ(st,at)−vt,未必等于真实 advantage。

这里固定采样策略,并把 critic 当作给定的函数。γ-just 讨论的是 discounted policy-gradient 项;对于前文从初始状态定义的 discounted objective,仍沿用相应的外层时间权重。

Computing GAE on a rollout

实际收集到的轨迹是有限的。设最后一个 action 是 aT,下一状态为 sT+1。从后往前计算即可:

A^t=δt+γλA^t+1,A^T+1=0.

这里的 A^T+1=0 表示没有更多已采样的 TD residual;未来收益仍通过最后一个 δT 中的 vT+1 进入估计。边界 value 按轨迹停止的原因确定:

  • 真正终止:未来没有 reward,令 vT+1=0。
  • rollout 收集结束或外部 time limit 截断:任务本可继续,使用停止前最后一个状态的 critic 预测作为 vT+1。

Spinning Up 的 PPOBuffer 实现 就通过最后一个 value 处理这两种情况。Gymnasium (Farama Foundation, n.d.) 用 terminated 和 truncated 区分真正终止与外部截断;任务本身定义的有限时域终点属于前者。

有限 rollout 下,即使 λ=1,仍有

A^t=∑l=0T−tγlrt+l+γT−t+1vT+1−vt.

采到真正终止时,边界项为零,才得到纯 Monte Carlo return 减 baseline;截断时则保留 bootstrap。

下面用普通列表实现单段 rollout 的计算。rewards 长度为 T,values 长度为 T+1,最后一个元素已经按上面的规则设置。它们都是采样时记录并固定下来的数值。

python
def gae(rewards, values, gamma, lam):
    assert len(values) == len(rewards) + 1
    advantages = [0.0] * len(rewards)
    carry = 0.0
    for t in reversed(range(len(rewards))):
        delta = rewards[t] + gamma * values[t + 1] - values[t]
        carry = delta + gamma * lam * carry
        advantages[t] = carry
    return advantages

多条 episode 应分别计算;截断后 reset 得到的新初始状态也不属于上一段轨迹,不能把它的 value 或 advantage 接到上一段。

例如,一条三步后终止的轨迹只有最后一步得到 reward。取 γ=0.9、λ=0.8,因此 γλ=0.72,并设终止状态 v4=0:

trtvtδtA^t
100.40.050.28616
200.50.040.328
310.60.40.4

从最后一步开始,先得到 A^3=0.4,再算 A^2=0.04+0.72×0.4=0.328,最后得到 A^1=0.05+0.72×0.328=0.28616。终点的信息通过这次反向递推传到更早的 action。

训练 actor 时,把算好的 advantage 当作固定权重,代入前面的 policy-gradient loss 或 PPO objective。GAE 负责构造这个权重;下一篇的 TRPO 和 PPO 则控制策略如何利用它更新。


系列导读 · 下一篇

References

Achiam, J. (2018). Spinning Up in Deep Reinforcement Learning. spinningup.openai.com
Farama Foundation. (n.d.). Handling Time Limits. gymnasium.farama.org
Hogg, R. V., McKean, J. W., & Craig, A. T. (2013). Introduction to Mathematical Statistics (7th ed.). Pearson. scholarworks.wmich.edu
Schulman, J., Moritz, P., Levine, S., Jordan, M., & Abbeel, P. (2015). High-dimensional continuous control using generalized advantage estimation. arXiv Preprint arXiv:1506.02438. arxiv.org
Thomas, P. (2014). Bias in natural actor-critic algorithms. International Conference on Machine Learning, 441–448. proceedings.mlr.press
Williams, R. J. (1992). Simple statistical gradient-following algorithms for connectionist reinforcement learning. Machine Learning, 8(3–4), 229–256. doi.org

Cite this post

@misc{pu2024mlmlrevisitrlpolicygradient,
  author = {Pu, Fanyi and {GPT‑5.6 Sol} and {GPT-6 Astra}},
  title  = {Reinforcement Learning: Policy Gradient 与 Advantage Estimation},
  year   = {2024},
  month  = {10},
  url    = {https://pufanyi.com/blog/ml/ml-revisit/rl-policy-gradient}
}