PPO

PPO算法详解

看了两天总算弄明白了PPO算法的来龙去脉

1. PG策略

PG策略是最大化下面这个目标函数

Rˉθ=EτPθ(τ)[R(τ)P(τθ)]\bar{R}_{\theta} = E_{\tau \sim P ^{\theta} (\tau)} [ R(\tau)P(\tau \mid \theta) ]

对目标函数求导可得到

Rˉθ=EτPθ(τ)[t=1TR(τ)logP(atst,θ)]\nabla \bar{R}_{\theta} = E_{\tau \sim P^{\theta}(\tau)}[\sum_{t=1}^{T}R(\tau) \nabla logP(a_{t} \mid s_{t}, \theta) ]

通过大量采样,可以近似得到上述期望

Rˉθ=1Nn=1Nt=1TnR(τn)logP(atnstn,θ)\nabla \bar{R}_{\theta} = \frac{1}{N}\sum_{n=1}^{N}\sum_{t=1}^{T^{n}} R(\tau^{n}) \nabla log P (a_{t}^{n} \mid s_{t}^{n}, \theta)

具体推导过程可以参考:深度强化学习(DRL)-李宏毅

2. 优势函数

对于每个时间点的动作概率都将R(τ)R(\tau)显示是不够合理的,如果R(τ)R(\tau)是一个整数,最大化目标函数就会增大该局游戏中做出的所有动作出现的概率,但是不是所有动作都是“好”的,我们希望“好”的动作出现概率增加,“坏”的动作出现概率减小。那么如何评判一个动作的“好坏”?

通过计算做出该动作后,得到的折扣累积奖励和。

return=t=t0Tγtt0rt(γ<1)return = \sum_{t=t_0}^{T} \gamma ^{t-t_0} r_{t} \quad (\gamma < 1)

我们称其为该动作的回报。

显然,对于一局游戏中的每个时间点的returnreturn可能都大于0,这依旧会导致我们无脑的增大每个动作出现的概率,那我们就优中选优。

对于状态 sts_{t} 选择不同的动作 a0,a1,a2,,an{a_0, a_1, a_2, \ldots, a_n} 得到的回报是不一样的,假设我们可以知道采取不同动作的期望回报 bb,我们就可以只增大那些大于 bb 的动作概率。现在我们用 returnbreturn - b 替换之前的 R(τ)R(\tau)

Rˉθ=1Nn=1Nt=1Tn(return(tn)b)logP(atnstn,θ)\nabla \bar{R}_{\theta} = \frac{1}{N}\sum_{n=1}^{N}\sum_{t=1}^{T^{n}} (return(t^n) - b) \nabla log P (a_{t}^{n} \mid s_{t}^{n}, \theta)

现在就可以实现更好的动作概率提高,不那么好的动作概率减低。

但是现在有一个问题是,我怎么知道 bb 取多少合适?

其实它也是训练出来的,通过神将网络,输入状态,输出该状态的期望回报,我们称之为状态价值函数 $ V(s_t) $ 。

我们将下面这个式子称为优势函数,用于度量某个状态下的动作相对于该状态下其他动作的“好坏”:

A(st,at)=return(st,at)V(st)A(s_t, a_t) = return(s_t, a_t) - V(s_t)

现在,可以得到更加优雅的导函数:

Rˉθ=1Nn=1Nt=1TnAθ(stn,atn)logP(atnstn,θ)\nabla \bar{R}_{\theta} = \frac{1}{N}\sum_{n=1}^{N}\sum_{t=1}^{T^{n}} A^\theta(s_t^n, a_t^n) \nabla log P (a_{t}^{n} \mid s_{t}^{n}, \theta)

目标函数为:

J(θ)=1Nn=1Nt=1TnAθ(stn,atn)J(\theta) = \frac{1}{N}\sum_{n=1}^{N}\sum_{t=1}^{T^{n}} A^\theta(s_t^n, a_t^n)

3. PPO

上述过程有什么缺点?

基于PG的强化学习过程大概是采样一次,优化参数一次,采样一次,优化参数一次…如此反复。要知道RL中的采样是很慢的,如果每次优化参数之前都要进行采样,那么训练的效率就太慢了。那能不能不采样呢?答案是可以的,我们可以反复用同一批样本多次优化策略参数。

直觉来说,当我们第一次用样本更新策略参数之后,得到新策略,新策略下采样得到的样本和原来的样本压根不是同一个概率分布,也就是说,我们不能用旧样本直接优化新策略的参数了,但是如果我们进行适当修正,就可以继续使用旧样本

具体怎么做呢,先看看不同分布下的期望是如何互相转换的:

Exp[f(x)]=Exq[f(x)p(x)q(x)]E_{x \sim p}[f(x)] = E_{x \sim q}[f(x)\frac{p(x)}{q(x)}]

运用到目标函数的导函数就是如下形式:

Rˉθ=1Nn=1Nt=1TnAθ(stn,atn)Pθ(atnstn)Pθ(atnstn)logPθ(atnstn)\nabla \bar{R}_{\theta} = \frac{1}{N}\sum_{n=1}^{N}\sum_{t=1}^{T^{n}} A^\theta(s_t^n, a_t^n) \frac{P^\theta(a_t^n \mid s_t^n)}{P^ {\theta'} (a_t^n \mid s_t^n)} \nabla log P^\theta (a_{t}^{n} \mid s_{t}^{n})

这就是PPO的核心内容:通过修正,多次使用旧样本来优化当前策略

但是这两个不同的概率分布依旧不能相差的太过于离谱,可以将二者的KL散度作为惩罚项加到式子中

Jppo(θ)=J(θ)βKL(θ,θ)J_{ppo}(\theta) = J(\theta) - \beta KL (\theta, \theta ')

其中 β\beta 用于动态调节惩罚力度

另一种惩罚方式是对相似度进行裁剪, 将相似度的上下限框定:

Jppo(θ)=1Nn=1Nt=1Tnmin(Pθ(atnstn)Pθ(atnstn)Aθ(stn,atn),clip(Pθ(atnstn)Pθ(atnstn),1ε,1+ε)Aθ(stn,atn))J_{ppo}(\theta) = \frac{1}{N}\sum_{n=1}^{N}\sum_{t=1}^{T^{n}} min ( \frac{P^\theta(a_t^n \mid s_t^n)}{P^ {\theta'} (a_t^n \mid s_t^n)} A^\theta(s_t^n, a_t^n), clip( \frac{P^\theta(a_t^n \mid s_t^n)}{P^ {\theta'} (a_t^n \mid s_t^n)}, 1 - \varepsilon, 1 + \varepsilon )A^\theta(s_t^n, a_t^n) )

PPO伪代码如下

image-20250306175059513


PPO
http://xyxblog.com/2025/03/06/PPO/
作者
xyx
发布于
2025年3月6日
许可协议