深入理解强化学习PPO算法(附带pyhton代码)
PPO1算法通过引入KL散度惩罚项来约束策略更新的幅度,确保新策略不会偏离旧策略太远。这种方法的主要优点是提供了理论上的稳定性保证,适合对安全性要求高的应用。主要缺点是计算相对复杂,需要计算KL散度并自适应调整惩罚系数,这增加了实现难度和计算开销。PPO2算法通过裁剪机制约束策略更新幅度,在保持训练稳定性的同时实现了高效优化。实现简单,无需复杂约束优化计算高效,适合大规模应用超参数少,易于调参在大
深入理解强化学习PPO算法
1 PPO算法概述
1.1 简介
近端策略优化(Proximal Policy Optimization,PPO)是OpenAI在2017年提出的一种强化学习算法,它通过引入约束机制来确保策略更新的稳定性,解决了传统策略梯度方法训练不稳定的问题。PPO属于策略梯度方法的家族,结合了策略梯度和值函数的优点,在许多实际应用中表现出色,具有较强的鲁棒性和效率。
1.2 ppo算法的由来
在强化学习中,策略梯度(Policy Gradient)方法直接优化策略参数,使得智能体最大化期望回报。
但普通的策略梯度方法(如 REINFORCE、QAC等)存在方差大、不稳定、更新步长不受控的问题。其中更新步长不受控可能会导致策略发生剧烈变化使得“训练崩溃”,例如策略优化过程中得到的相对较好的策略突然退化为一个非常差的策略
为了解决上述问题,研究者依次提出了:
- TRPO (Trust Region Policy Optimization):通过 KL 散度约束控制策略更新幅度(硬约束,计算相当复杂)。
- PPO1 (Proximal Policy Optimization – KL Penalty 版本):用 KL 惩罚项近似替代 TRPO 的约束(软约束,计算量相对与TRPO减小了一些)。
- PPO2 (Proximal Policy Optimization – Clipped 版本):用概率比率裁剪(clip)机制,进一步简化计算并提升稳定性(用裁剪代替约束,计算量进一步减小)。
三者都属于 Policy Gradient 家族,目标一致:
通过约束策略变化,使得稳定训练、避免过大更新。
简而言之,PPO的核心思想是在保证策略改进的同时,限制策略更新的幅度,防止策略发生剧烈的变化。这种约束机制使PPO能够避免传统策略梯度方法中的高方差问题,并且避免了TRPO(Trust Region Policy Optimization)复杂的约束条件。
PPO算法已经成为强化学习领域最流行的算法之一,在从游戏AI到机器人控制、甚至大语言模型的对齐优化等众多领域都有广泛应用。
1.2.1 训练崩溃的原因
在使用传统策略梯度方法(如REINFORCE或基础Actor-Critic)时,典型的问题现象包括:
- 训练不稳定:训练过程中的奖励曲线出现剧烈波动,或策略性能突然断崖式下降(俗称“训练崩溃”),导致模型无法收敛。
- 收敛困难:策略可能在局部最优值附近振荡,难以稳定提升性能;有时需要大量调整超参数(如学习率)才能收敛。
- 样本效率低:为达到相同性能,传统方法需要与环境交互的样本量远高于PPO等改进算法,因为在策略更新后,旧数据通常无法复用
原因:
- 策略梯度的高方差:策略梯度的估计依赖于蒙特卡洛采样,其计算公式为:
∇ θ J ( θ ) = E s t ∼ d π θ , a t ∼ π θ [ ∇ θ log π θ ( a ∣ s ) ⋅ A ( s , a ) ] \nabla_{\theta} J(\theta) = \mathbb{E}_{s_t \sim d^{\pi_{\theta}}, a_t \sim \pi_{\theta}} \left[ \nabla_{\theta} \log \pi_{\theta}(a|s) \cdot A(s, a) \right] ∇θJ(θ)=Est∼dπθ,at∼πθ[∇θlogπθ(a∣s)⋅A(s,a)]
其中优势函数 A(s,a)的估计本身具有高方差。当策略变化时,方差会进一步放大,导致梯度更新方向不稳定。 - 步长敏感性与策略突变:策略梯度更新步长(学习率)的选取非常关键。步长过大会使新策略与旧策略差异巨大,可能直接破坏已有学习成果;步长过小则收敛缓慢。传统方法缺乏对步长的自适应约束机制。
- 重要性权重失控:在利用旧数据通过重要性采样进行多次更新时,新旧策略的概率比 r ( θ ) r(\theta) r(θ)可能过大或过小,导致梯度估计偏差加剧,进而引发更新失控。
- 不同度量空间导致策略突变:参数(如神经网络的权重θ)本身及其更新步长在欧式空间中度量,而策略(即概率分布π(a|s))之间的真实差异需要在黎曼空间中度量。这两种空间在度量“距离”和“变化”方式上的根本不同,导致了“合理”的参数步长可能引发灾难性的策略变化。
1.3 不同度量空间为何会导致策略突变
1.3.1 空间特性对比表:
| 度量对象 / 特性 | 欧式空间 (参数空间) | 黎曼空间 (策略分布空间) |
|---|---|---|
| 度量的直接对象 | 策略函数的参数向量 θ | 策略函数输出的概率分布 π(a|s) |
| 空间的直观性质 | 平坦、均匀 | 弯曲、不均匀 |
| "距离"的度量方式 | 欧式距离: ∣ Δ θ ∣ |\Delta \theta| ∣Δθ∣ | KL散度,由Fisher信息矩阵定义黎曼度量 |
| "最速上升"方向 | 标准梯度 ∇ θ J ( θ ) \nabla_\theta J(\theta) ∇θJ(θ) | 自然梯度 F − 1 ( θ ) ∇ θ J ( θ ) F^{-1}(\theta) \nabla_\theta J(\theta) F−1(θ)∇θJ(θ) |
1.3.2 为何"合理"的步长会造成"巨变"?
1. 概率分布参数化的非线性
策略 π θ ( a ∣ s ) \pi_\theta(a|s) πθ(a∣s) 是参数 θ \theta θ$的一个非线性函数。参数空间的线性变化会被非线性变换映射到概率分布空间,导致概率的变化是非均匀的。
数学表达:
- 参数变化: Δ θ = θ 2 − θ 1 \Delta \theta = \theta_2 - \theta_1 Δθ=θ2−θ1(固定值)
- 策略变化: Δ π = π θ 2 ( a ∣ s ) − π θ 1 ( a ∣ s ) \Delta \pi = \pi_{\theta_2}(a|s) - \pi_{\theta_1}(a|s) Δπ=πθ2(a∣s)−πθ1(a∣s)(非线性,不均匀)
示例:
假设某个动作的逻辑值(logit)在旧策略下对应的参数是 θ 1 θ_1 θ1,经过一次更新后变为 θ 2 θ_2 θ2 。虽然参数的变化量 Δ θ = θ 2 − θ 1 Δθ=θ_2−θ_1 Δθ=θ2−θ1 是一个固定的数值,但通过Softmax函数计算出的该动作概率可能从1%急剧增加到50%。而在另一个参数区域,同样的 Δθ可能仅使概率从60%微调到65%。在欧式空间中,这两种更新的“步长”是相同的,但在策略空间(黎曼空间)中产生的影响却天差地别。
即:同样的参数变化量 Δ θ \Delta \theta Δθ,在不同参数区域可能产生完全不同的策略变化:
- 区域A:概率从1% → 50%(巨变)
- 区域B:概率从60% → 65%(微调)
2. 流形的曲率与黎曼度量
概率分布的集合构成黎曼流形,其局部几何性质由Fisher信息矩阵描述:
F ( θ ) = E [ ∇ log π θ ( a ∣ s ) ∇ log π θ ( a ∣ s ) T ] F(\theta) = \mathbb{E}[\nabla \log \pi_\theta(a|s) \nabla \log \pi_\theta(a|s)^T] F(θ)=E[∇logπθ(a∣s)∇logπθ(a∣s)T]
Fisher信息矩阵度量了策略分布对参数变化的敏感度:
- 在流形曲率大的地方(敏感区域),小参数步长 → 大策略变化
- 在流形曲率小的地方(平坦区域),大参数步长 → 小策略变化
1.3.3 PPO/TRPO的解决方案
理解了上述原因,就能明白PPO和TRPO的核心思想:将优化过程从危险的、不匹配的欧式参数空间,引导至更本质的、安全的黎曼策略空间。
- TRPO的严格方法:它直接在数学上形式化了一个信任区域(Trust Region),约束新旧策略之间的KL散度必须小于一个阈值 δ δ δ。这本质上就是在黎曼流形上划定一个范围,确保新策略不会偏离旧策略太远。其更新方向利用了自然梯度,这正是在黎曼度量下的最速上升方向。
- PPO的巧妙近似:PPO(特别是PPO-Clip)没有像TRPO那样进行复杂的自然梯度计算。它通过目标函数中的“裁剪(Clip)”操作,经验性地限制重要性权重 r t ( θ ) = π θ ( a ∣ s ) π θ o l d ( a ∣ s ) r_t(\theta) = \frac{\pi_\theta(a|s)}{\pi_{\theta_{old}}(a|s)} rt(θ)=πθold(a∣s)πθ(a∣s) 的幅度。这实际上是在效果上近似实现了在策略分布空间中对更新幅度的约束,从而避免了策略的剧烈突变,是一种更工程化、计算量更小的一阶近似方法
TRPO的严格方法
建立黎曼空间中的信任区域:
maximize θ L θ o l d ( θ ) = E [ r t ( θ ) A t ] \text{maximize}_\theta L_{\theta_{old}}(\theta)= \mathbb{E}[r_t(\theta)A_t] maximizeθLθold(θ)=E[rt(θ)At]
subject to D ˉ K L ( θ o l d ∥ ∥ θ ) ≤ δ \text{subject to } \bar{D}_{KL}(\theta_{old} \|\| \theta) \leq \delta subject to DˉKL(θold∥∥θ)≤δ
其中KL散度约束直接在黎曼空间中限制策略变化幅度。
PPO的巧妙近似
通过裁剪目标函数间接实现类似效果:
L ( θ ) = E [ min ( r t ( θ ) A t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A t ) ] L(\theta) = \mathbb{E}[\min(r_t(\theta)A_t, \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)A_t)] L(θ)=E[min(rt(θ)At,clip(rt(θ),1−ϵ,1+ϵ)At)]
其中 r t ( θ ) = π θ ( a ∣ s ) π θ o l d ( a ∣ s ) r_t(\theta) = \frac{\pi_\theta(a|s)}{\pi_{\theta_{old}}(a|s)} rt(θ)=πθold(a∣s)πθ(a∣s),用 c l i p ( ) clip() clip()函数裁剪操作经验性地约束了策略分布空间中的变化幅度。
核心洞察
PPO算法的成功关键在于认识到:在强化学习中,我们应该在策略分布空间(黎曼空间)而非参数空间(欧式空间)中控制和度量优化过程。这种几何视角的转换是确保训练稳定性的理论基础。
1.4TRPO算法
TRPO算法(Trust Region Policy Optimization)
1.4.1 核心思想
TRPO 通过引入信任域约束(Trust Region Constraint),保证每次策略更新不会偏离旧策略太多。
换句话说,TRPO 是一个带约束的优化问题:希望在期望回报上升的同时,保持新旧策略之间的距离(通过 KL 散度)不超过一个阈值。
1.4.2 目标函数(Objective Function)
TRPO 的优化目标为:
max θ E t [ r t ( θ ) A t ] \max_\theta \; \mathbb{E}_t \left[r_t(\theta) {A}_t \right] θmaxEt[rt(θ)At]
约束条件为:
E t [ D K L ( π θ o l d ( ⋅ ∣ s t ) ∥ π θ ( ⋅ ∣ s t ) ) ] ≤ δ \mathbb{E}_t \left[ D_{KL}\left( \pi_{\theta_{old}}(\cdot | s_t) \,\|\, \pi_\theta(\cdot | s_t) \right) \right] \leq \delta Et[DKL(πθold(⋅∣st)∥πθ(⋅∣st))]≤δ
其中:
- r t ( θ ) = π θ ( a t ∣ s t ) π θ o l d ( a t ∣ s t ) r_t(\theta) = \frac{\pi_{\theta}(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)} rt(θ)=πθold(at∣st)πθ(at∣st) 是新旧策略的概率比率。
- π θ ( a t ∣ s t ) \pi_\theta(a_t | s_t) πθ(at∣st):新策略下动作的概率;
- π θ o l d ( a t ∣ s t ) \pi_{\theta_{old}}(a_t | s_t) πθold(at∣st):旧策略下动作的概率;
- A t {A}_t At:优势函数;
- D K L D_{KL} DKL:KL 散度;
- δ \delta δ:控制更新幅度的阈值(如 0.01)。
TRPO 通过 共轭梯度法(Conjugate Gradient) 近似求解该约束优化问题,
在理论上保证了 单调性能改进(monotonic improvement)。
关于优势函数 A t A_t At的介绍请看我另一篇博客:广义优势估计(GAE):PPO算法的核心技术与数学深度解析
2.ppo算法的分类:ppo1、ppo2
2.1 PPO1和PPO2算法的优缺点
PPO算法主要有两种变体:PPO1(带KL散度惩罚)和PPO2(带裁剪目标函数)。
| 特性 | PPO1 (KL散度惩罚) | PPO2 (裁剪目标函数) |
|---|---|---|
| 核心目标函数 | L K L ( θ ) = E t [ r t ( θ ) A t − β ⋅ K L [ π θ o l d ∣ π θ ] ] L^{KL}(\theta) = \mathbb{E}_{t} \left[ r_t(\theta) A_t - \beta \cdot KL[\pi_{\theta_{old}}| \pi_{\theta}] \right] LKL(θ)=Et[rt(θ)At−β⋅KL[πθold∣πθ]] | L C L I P ( θ ) = E t [ min ( r t ( θ ) A t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A t ) ] L^{CLIP}(\theta) = \mathbb{E}_{t} \left[ \min\left( r_t(\theta) A_t, \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) A_t \right) \right] LCLIP(θ)=Et[min(rt(θ)At,clip(rt(θ),1−ϵ,1+ϵ)At)] |
| 计算复杂度 | 较高,需要计算KL散度 | 较低,只需简单裁剪 |
| 稳定性 | 非常稳定,有理论保证 | 相对稳定,经验验证 |
| 超参数调优 | 需要调整目标KL值和自适应参数 | 只需调整裁剪参数ε |
| 收敛速度 | 相对较慢 | 通常更快 |
| 实现难度 | 较复杂 | 较简单 |
| 适用场景 | 对稳定性要求极高的任务 | 大多数强化学习任务 |
PPO1的优点在于其有理论保证的稳定性,通过KL散度约束确保策略更新不会偏离太远。缺点是实现相对复杂,需要计算KL散度并调整自适应参数。
PPO2的优点是实现简单、计算高效,在大多数任务中表现良好且收敛速度较快。缺点是缺乏严格的理论保证,更多地依赖于经验验证。
在实际应用中,PPO2通常是首选方法,因为它实现简单、效果稳定且超参数少。
3 深入理解PPO1算法
3.1 核心思想
PPO1 通过在目标函数中加入 KL 散度惩罚项来约束新旧策略的差异(约束策略更新的幅度)。KL 散度越大,说明新旧策略差距越大,从而会产生更强的惩罚,使更新幅度受限。
PPO1 是对 TRPO 的一种简化近似。与 TRPO 不同,PPO1 不再严格约束 KL 散度(即不做硬约束),而是在目标函数中加入一个 KL 散度惩罚项(soft constraint),使优化问题变为“软约束”形式。
3.2 PPO1算法的目标函数
PPO1算法的目标函数结合了策略改进目标和KL散度惩罚项:
J P P O 1 ( θ ) = E t [ r t ( θ ) A t − β ⋅ K L [ π θ o l d ( ⋅ ∣ s t ) ∥ π θ ( ⋅ ∣ s t ) ] ] J^{PPO1}(\theta) = \mathbb{E}_{t} \left[ r_t(\theta) A_t - \beta \cdot KL[\pi_{\theta_{old}}(\cdot|s_t) \| \pi_{\theta}(\cdot|s_t)] \right] JPPO1(θ)=Et[rt(θ)At−β⋅KL[πθold(⋅∣st)∥πθ(⋅∣st)]]
展开式可以表示为:
J P P O 1 ( θ ) = E t [ π θ ( a t ∣ s t ) π θ o l d ( a t ∣ s t ) A t − β ∑ a π θ o l d ( a ∣ s t ) log π θ o l d ( a ∣ s t ) π θ ( a ∣ s t ) ] J^{PPO1}(\theta) = \mathbb{E}_{t} \left[ \frac{\pi_{\theta}(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)} A_t - \beta \sum_{a} \pi_{\theta_{old}}(a|s_t) \log \frac{\pi_{\theta_{old}}(a|s_t)}{\pi_{\theta}(a|s_t)} \right] JPPO1(θ)=Et[πθold(at∣st)πθ(at∣st)At−βa∑πθold(a∣st)logπθ(a∣st)πθold(a∣st)]
其中:
- π θ \pi_{\theta} πθ:参数化为 θ \theta θ的新策略
- π θ o l d \pi_{\theta_{old}} πθold:旧的策略(更新前的策略)
- r t ( θ ) = π θ ( a t ∣ s t ) π θ o l d ( a t ∣ s t ) r_t(\theta) = \frac{\pi_{\theta}(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)} rt(θ)=πθold(at∣st)πθ(at∣st) 是新旧策略的概率比率。
- A t A_t At:时间步t的优势函数估计值
- β \beta β:KL散度的惩罚系数(可自适应调整,若 KL 散度超过一定范围,可增加惩罚强度。)
- K L [ π θ o l d ∥ π θ ] KL[\pi_{\theta_{old}} \| \pi_{\theta}] KL[πθold∥πθ]:新旧策略之间的KL散度
这种方法避免了 TRPO 中复杂的共轭梯度优化, 可使用 普通的梯度下降 来更新参数,计算上更高效。
关于优势函数 A t A_t At的介绍请看我另一篇博客:广义优势估计(GAE):PPO算法的核心技术与数学深度解析
3.2 PPO1算法的求解方法
PPO1算法的求解涉及以下步骤:
- 初始化:初始化策略参数 θ 0 \theta_0 θ0,设定初始KL惩罚系数 β 0 \beta_0 β0
- 数据收集:使用当前策略 θ k \theta_k θk与环境交互,收集状态-动作-奖励数据
- 优势估计:使用收集的数据计算优势函数估计值 A t A_t At
- 优化目标函数:通过梯度上升优化带KL约束的目标函数:
θ k + 1 = arg max θ E t [ π θ ( a t ∣ s t ) π θ old ( a t ∣ s t ) A t − β k ⋅ KL [ π θ old ∥ π θ ] ] \theta_{k+1} = \arg\max_{\theta} \mathbb{E}_{t} \left[ \frac{\pi_{\theta}(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)} A_t - \beta_k \cdot \text{KL}[\pi_{\theta_{\text{old}}} \| \pi_{\theta}] \right] θk+1=argθmaxEt[πθold(at∣st)πθ(at∣st)At−βk⋅KL[πθold∥πθ]]
- 自适应调整 β \beta β:根据实际KL散度值调整惩罚系数,代码示例:
if kl < target_kl / 1.5:
beta = beta / 2 # KL散度过小,减小惩罚
elif kl > target_kl * 0.5:
beta = beta * 2 # KL散度过大,增加惩罚
- 重复:重复步骤2-5直到收敛
基础知识:
- KL散度(Kullback-Leibler Divergence):衡量两个概率分布之间的差异,是非负且不对称的
- 重要性采样:允许使用旧策略收集的数据来估计新策略的性能
- 优势函数: A ( s , a ) = Q ( s , a ) − V ( s ) A(s,a) = Q(s,a) - V(s) A(s,a)=Q(s,a)−V(s),表示某个动作相对于平均水平的优势程度
3.3 PPO1算法总结
3.3.1优缺点
PPO1算法主要的算法思想:通过在目标函数中加入 KL 散度惩罚项来约束新旧策略的差异(约束策略更新的幅度)。KL 散度越大,说明新旧策略差距越大,从而会产生更强的惩罚,使更新幅度受限。
主要优点:提供了理论上的稳定性保证,适合对安全性要求高的应用。
主要缺点:计算相对复杂,需要计算KL散度并自适应调整惩罚系数,这增加了实现难度和计算开销。
3.3.2TRPO与PPO1的联系与区别
| 对比项 | TRPO | PPO1 |
|---|---|---|
| 核心思想 | 限制策略更新在信任域内(硬约束) | 在目标函数中加入 KL 惩罚项(软约束) |
| 约束形式 | E [ D K L ] ≤ δ \mathbb{E}[D_{KL}] \le \delta E[DKL]≤δ(显式约束) | − β D K L -\beta D_{KL} −βDKL(惩罚项) |
| 优化方式 | 共轭梯度 + 二阶近似 | 一阶梯度下降即可 |
| 稳定性 | 理论上保证单调改进 | 稳定但需调整 β 参数 |
| 计算复杂度 | 较高,需要二阶信息 | 较低,更高效 |
| 收敛速度 | 稳定但较慢 | 更快、更灵活 |
| 提出关系 | PPO 是对 TRPO 的简化与改进 | 是 TRPO 的一阶近似形式 |
换句话说:
PPO1 ≈ TRPO 的一阶近似(使用惩罚替代约束)
3.3.3总结性对比与理解
| 概念 | 数学约束角度理解 | 优化直觉 |
|---|---|---|
| TRPO | 在优化过程中显式控制 KL 散度上界 | 严格控制更新步长,不超出“安全区” |
| PPO1 | 把 KL 散度移入目标函数,用惩罚项限制更新 | 不直接约束,而是惩罚“偏离” |
| 本质联系 | PPO1 是 TRPO 的近似形式(用 penalty 代替 constraint) | 二者目的相同:防止策略更新过大,保持训练稳定 |
4 深入理解PPO2算法
4.1 PPO2算法的目标函数
在 PPO2(Proximal Policy Optimization, Clip版本) 中,训练目标不仅仅是优化策略(Actor),
还要同时学习一个价值函数(Critic)并维持策略的探索能力(Entropy Regularization)。
因此,总的优化目标(总损失函数)由三部分组成:
L T O T A L ( θ ) = L A C T O R ( θ ) − c 1 ⋅ L C R I T I C ( ϕ ) + c 2 ⋅ L E N T R O P Y ( θ ) L^{TOTAL}(\theta) = L^{ACTOR}(\theta) - c_1 \cdot L^{CRITIC}(\phi) + c_2 \cdot L^{ENTROPY}(\theta) LTOTAL(θ)=LACTOR(θ)−c1⋅LCRITIC(ϕ)+c2⋅LENTROPY(θ)
其中:
- L A C T O R L^{ACTOR} LACTOR:策略网络的目标(Policy / Actor Loss) ,控制策略更新幅度,使训练稳定并逐步新方向更准确。
- L E N T R O P Y L^{ENTROPY} LENTROPY:熵正则项(Entropy Bonus) ,提高策略多样性,防止过快陷入局部最优。
- c 1 , c 2 c_1, c_2 c1,c2:平衡三个目标的系数,通常 c 1 ≈ 0.5 c_1 \approx 0.5 c1≈0.5, c 2 ≈ 0.01 c_2 \approx 0.01 c2≈0.01
说明:符号上的正负号取决于实现框架(有的以最小化损失定义),但本质不变—> PPO2 同时追求高回报、准确价值估计与良好的探索。
PPO 同时要:
最大化策略的期望回报(policy objective)→ L A C T O R ( θ ) L^{ACTOR}(\theta) LACTOR(θ);
最小化价值函数预测误差(value function loss) → L C R I T I C ( ϕ ) L^{CRITIC}(\phi) LCRITIC(ϕ);
最大化策略熵(entropy bonus) → L E N T R O P Y ( θ ) L^{ENTROPY}(\theta) LENTROPY(θ)。
如果直接从「最大化问题」写成「最小化问题」,就需要对方向(正负号)做变换。
总损失函数的3个组成部分的简要对比
| 模块 | 数学表达式 | 主要作用 | 在训练中的功能 |
|---|---|---|---|
| Actor (策略损失) | a r g m a x θ L A C T O R = E [ min ( r t ( θ ) A t , clip ( r t ( θ ) ) A t ) ] argmax_{\theta}L^{ACTOR} = \mathbb{E}[\min(r_t(\theta) {A}_t, \text{clip}(r_t(\theta)){A}_t)] argmaxθLACTOR=E[min(rt(θ)At,clip(rt(θ))At)] | 提高策略性能,控制更新幅度 | 负责决策改进与更新稳定性 |
| Critic (价值损失) | a r g m i n ϕ L C R I T I C = E [ ( V ϕ − V ) 2 ] argmin_{\phi}L^{CRITIC} = \mathbb{E}[(V_\phi - {V})^2] argminϕLCRITIC=E[(Vϕ−V)2] | 精确估计状态价值 | 降低方差,指导策略改进方向 |
| Entropy (熵正则) | L E N T R O P Y = E [ H ( π θ ) ] L^{ENTROPY} = \mathbb{E}[\mathcal{H}(\pi_\theta)] LENTROPY=E[H(πθ)] | 鼓励策略探索 | 防止过早收敛,增加随机性 |
✅ 一句话总结:
PPO2 的总目标函数是“性能提升 + 稳定学习 + 保持探索”的平衡体,
通过三部分(Actor、Critic、Entropy)的加权组合实现鲁棒而高效的策略优化。
4.1.1 Actor Loss:策略裁剪损失函数
PPO2使用裁剪机制来约束策略更新,其中Actor损失函数是PPO2的核心组成部分:
L U N C L I P ( θ ) = E t [ r t ( θ ) A t ] L^{UNCLIP}(\theta) = \mathbb{E}_{t} \left[ r_t(\theta) A_t \right] LUNCLIP(θ)=Et[rt(θ)At]
L C L I P ( θ ) = E t [ min ( r t ( θ ) A t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A t ) ] L^{CLIP}(\theta) = \mathbb{E}_{t} \left[ \min\left( r_t(\theta) A_t, \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) A_t \right) \right] LCLIP(θ)=Et[min(rt(θ)At,clip(rt(θ),1−ϵ,1+ϵ)At)]
其中:
- L U N C L I P ( θ ) L^{UNCLIP}(\theta) LUNCLIP(θ):不带裁剪的目标函数
- L C L I P ( θ ) L^{CLIP}(\theta) LCLIP(θ):带裁剪的目标函数
- r t ( θ ) = π θ ( a t ∣ s t ) π θ o l d ( a t ∣ s t ) r_t(\theta) = \frac{\pi_{\theta}(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)} rt(θ)=πθold(at∣st)πθ(at∣st):新旧策略的概率比率,反映新策略相对于旧策略的变化程度
- A t A_t At:优势函数,衡量当前动作相对于平均动作的优势
- ϵ \epsilon ϵ:裁剪参数,控制更新幅度的小常数,通常设置为0.1-0.2
- min ( ) \min() min():取两个值中的最小值,确保更新是悲观的,防止过度优化
- clip ( ) \text{clip}() clip():将比率限制在 [ 1 − ϵ , 1 + ϵ ] [1-\epsilon, 1+\epsilon] [1−ϵ,1+ϵ]范围内
关于优势函数 A t A_t At的介绍请看我另一篇博客:广义优势估计(GAE):PPO算法的核心技术与数学深度解析
注意:
PPO2算法实际使用的是带裁剪的目标函数,之所以这里要给出不带裁剪的目标函数是为了体现出俩者目标函数在表达式上的区别,进而引出该目标函数的由来,如果读者感兴趣的话可以查看我另一篇关于梳理ppo2的目标函数发展历程的博客:强化学习策略梯度算法梳理:从REINFORCE到PPO2(REINFORCE、QAC、A2C、Off-Policy AC、PP01、PPO2)
4.1.1.1 损失函数的由来
请查看:强化学习策略梯度算法梳理:从REINFORCE到PPO2(REINFORCE、QAC、A2C、Off-Policy AC、PP01、PPO2)
4.1.1.2 裁剪机制
裁剪机制通过限制概率比率 r t ( θ ) r_t(\theta) rt(θ)在 [ 1 − ϵ , 1 + ϵ ] [1-\epsilon, 1+\epsilon] [1−ϵ,1+ϵ]范围内,防止策略更新幅度过大。具体而言:
clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) = { 1 − ϵ if r t ( θ ) < 1 − ϵ 1 + ϵ if r t ( θ ) > 1 + ϵ r t ( θ ) otherwise \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) = \begin{cases} 1-\epsilon & \text{if } r_t(\theta) < 1-\epsilon \\ 1+\epsilon & \text{if } r_t(\theta) > 1+\epsilon \\ r_t(\theta) & \text{otherwise} \end{cases} clip(rt(θ),1−ϵ,1+ϵ)=⎩ ⎨ ⎧1−ϵ1+ϵrt(θ)if rt(θ)<1−ϵif rt(θ)>1+ϵotherwise
4.1.1.3 取min操作
取min操作的目的是确保策略更新是"悲观的" - 只有当变化对性能有确信的改进时才进行更新。
示例:
假设 A t > 0 A_t > 0 At>0(该动作优于平均水平):
- 如果 r t ( θ ) = 2.0 r_t(\theta) = 2.0 rt(θ)=2.0(新策略选择该动作的概率是旧策略的2倍)
- ϵ = 0.2 \epsilon = 0.2 ϵ=0.2,那么 clip ( 2.0 , 0.8 , 1.2 ) = 1.2 \text{clip}(2.0, 0.8, 1.2) = 1.2 clip(2.0,0.8,1.2)=1.2
- min ( 2.0 × A t , 1.2 × A t ) = 1.2 × A t \min(2.0 \times A_t, 1.2 \times A_t) = 1.2 \times A_t min(2.0×At,1.2×At)=1.2×At
- 这样即使概率比率很高,我们也只使用1.2倍的 A t A_t At,防止过度更新
同理,如果 A t < 0 A_t < 0 At<0(该动作劣于平均水平):
- 如果 r t ( θ ) = 0.5 r_t(\theta) = 0.5 rt(θ)=0.5(新策略选择该动作的概率是旧策略的一半)
- clip ( 0.5 , 0.8 , 1.2 ) = 0.8 \text{clip}(0.5, 0.8, 1.2) = 0.8 clip(0.5,0.8,1.2)=0.8
- min ( 0.5 × A t , 0.8 × A 极 ) = 0.8 × A t \min(0.5 \times A_t, 0.8 \times A极) = 0.8 \times A_t min(0.5×At,0.8×A极)=0.8×At(因为 A t < 0 A_t < 0 At<0,所以0.8 × A_t比0.5 × A_t更小)
- 这样我们使用0.8倍的 A t A_t At,防止过度降低该动作的概率
4.1.2 Critic Loss:值函数裁剪损失函数
注意:此处先给出损失函数的表达式,损失函数怎么来的请看 4.1.2.1小节
Critic 的目标函数有2个版本:
未裁剪版–Critic损失函数(un-clip)用于学习价值函数:
L ϕ C R I T I C − u n c l i p = E t [ ( V ϕ ( s t ) − V t t a r g e t ) 2 ) ] L^{CRITIC-{unclip}} _{\phi}= \mathbb{E}_{t} \left[ (V_{\phi}(s_t) - V_t^{target})^2 ) \right] LϕCRITIC−unclip=Et[(Vϕ(st)−Vttarget)2)]
裁剪版–Critic损失函数(clip)用于学习价值函数:
L ϕ C R I T I C − c l i p = E t [ max ( ( V ϕ ( s t ) − V t t a r g e t ) 2 , ( V ϕ c l i p ( s t ) − V t t a r g e t ) 2 ) ] L^{CRITIC-clip} _{\phi}= \mathbb{E}_{t} \left[ \max\left( (V_{\phi}(s_t) - V_t^{target})^2, (V_{\phi_{clip}} (s_t) - V_t^{target})^2 \right) \right] LϕCRITIC−clip=Et[max((Vϕ(st)−Vttarget)2,(Vϕclip(st)−Vttarget)2)]
V ϕ c l i p ( s t ) = clip ( V ϕ ( s t ) , V ϕ o l d ( s t ) − ϵ , V ϕ o l d ( s t ) + ϵ ) V_{\phi_{clip}} (s_t)=\text{clip}(V_{\phi}(s_t), V_{\phi_{old}}(s_t)-\epsilon, V_{\phi_{old}}(s_t)+\epsilon) Vϕclip(st)=clip(Vϕ(st),Vϕold(st)−ϵ,Vϕold(st)+ϵ)
V t target = A t + V ϕ old ( s t ) V_t^{\text{target}} = A_t + V_{\phi_{\text{old}}}(s_t) Vttarget=At+Vϕold(st)
其中:
- V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st):Critic网络对状态 s t s_t st的价值预测
- V ϕ old ( s t ) V_{\phi_{\text{old}}}(s_t) Vϕold(st):Critic网络对状态 s t s_t st的旧价值预测
- V ϕ clip ( s t ) V_{\phi_{\text{clip}}}(s_t) Vϕclip(st):裁剪后的价值预测
- V t t a r g e t V_t^{target} Vttarget:目标价值(通常基于实际回报和Bootstrapping计算)
- ϵ \epsilon ϵ:裁剪参数,(一般与Actor的 ϵ \epsilon ϵ相同)
4.1.2.1 损失函数的由来
注意:本小节以未裁剪的Critic loss为例
在强化学习中,Critic 网络的任务是预测状态的真实价值函数:
V π ( s t ) = E π [ ∑ k = 0 ∞ γ k r t + k | s t ] V^{\pi}(s_t) = \mathbb{E}_{\pi}\!\left[\sum_{k=0}^{\infty}\gamma^k r_{t+k}\,\middle|\,s_t\right] Vπ(st)=Eπ[k=0∑∞γkrt+k
st]
Critic 的目标是学习一个值函数 V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st),使其接近当前策略 π \pi π下的真实的价值函数 V π ( s t ) V^{\pi}(s_t) Vπ(st)。通常使用均方误差 (MSE) 作为损失函数:
L ϕ C R I T I C − u n c l i p − π = E t [ ( V ϕ ( s t ) − V π ( s t ) ) 2 ) ] L^{CRITIC-{unclip}-{\pi}} _{\phi}= \mathbb{E}_{t} \left[ (V_{\phi}(s_t) - V^{\pi}(s_t))^2 ) \right] LϕCRITIC−unclip−π=Et[(Vϕ(st)−Vπ(st))2)]
然而,这个“真实值”没法直接获得,因为未来是未知的,我们只能基于采样到的轨迹经验来近似计算这个期望值 V π ( s t ) V^{\pi}(s_t) Vπ(st),于是定义了训练时使用的目标价值(Target Value):
V t target = A t + V ϕ old ( s t ) V_t^{\text{target}} = A_t + V_{\phi_{\text{old}}}(s_t) Vttarget=At+Vϕold(st)
它是 Critic 的“学习目标”,用以近似模型希望预测的真实状态价值。关于 V t target V_t^{\text{target}} Vttarget的计算请看4.1.2.3小节
所以在Critic 的目标就变成了:学习一个值函数 V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st),使其接近实际的回报 V t t a r g e t V_t^{target} Vttarget。即: L ϕ C R I T I C − u n c l i p = E t [ ( V ϕ ( s t ) − V t t a r g e t ) 2 ) ] L^{CRITIC-{unclip}} _{\phi}= \mathbb{E}_{t} \left[ (V_{\phi}(s_t) - V_t^{target})^2 ) \right] LϕCRITIC−unclip=Et[(Vϕ(st)−Vttarget)2)]
4.1.2.2 目标价值 V t t a r g e t V_t^{target} Vttarget的由来和计算
我们前面提到目标价值 V t target V_t^{\text{target}} Vttarget是Critic 的“学习目标”,用以近似模型希望预测的真实状态价值 V π ( s t ) V^{\pi}(s_t) Vπ(st)。那么 V t target V_t^{\text{target}} Vttarget的表达式应该是什么样的呢?一个很自然的想法引入时序差分的思想,用即时奖励加上下一状态的折扣价值来近似真实的状态价值,
即单步TD目标:
V t target = r t + γ V ϕ old ( s t + 1 ) V_t^{\text{target}} = r_t + \gamma V_{\phi_{\text{old}}}(s_{t+1}) Vttarget=rt+γVϕold(st+1)
其中:
- r t r_t rt:当前步奖励;
- γ \gamma γ:折扣因子(通常为 0.99);
- V ϕ old ( s t + 1 ) V_{\phi_{\text{old}}}(s_{t+1}) Vϕold(st+1):旧 Critic 网络对下一状态的价值预测。
然而,上式只使用了与环境的单步交互获取的经验,这会导致 V t target V_t^{\text{target}} Vttarget对 V π ( s t ) V^{\pi}(s_t) Vπ(st)的近似呈现高偏差低方差的特点
另一个想法是,引入蒙特卡洛的思想,用一整个回合的总折扣回报来近似真实的状态价值
即MC目标:
V t target = G t ( n ) = ∑ k = 0 n − 1 γ k r t + k V_t^{\text{target}} =G_t^{(n)} = \sum_{k=0}^{n-1}\gamma^k r_{t+k} Vttarget=Gt(n)=k=0∑n−1γkrt+k
然而,上式会导致 V t target V_t^{\text{target}} Vttarget对 V π ( s t ) V^{\pi}(s_t) Vπ(st)的近似呈现低偏差高方差的特点
所以,结合广义优势估计(GAE)的思想, 对n步目标的做加权,平均兼顾偏差和方差,则有
GAE目标:
V t target = A t G A E ( γ , λ ) + V ϕ old ( s t ) \boxed{V_t^{\text{target}} = A_t^{GAE(\gamma,\lambda)} + V_{\phi_{\text{old}}}(s_t)} Vttarget=AtGAE(γ,λ)+Vϕold(st)
A t G A E ( γ , λ ) = ∑ l = 0 ∞ ( γ λ ) l δ t + l A_t^{GAE(\gamma,\lambda)} = \sum_{l=0}^{\infty} (\gamma\lambda)^l \delta_{t+l} AtGAE(γ,λ)=l=0∑∞(γλ)lδt+l
其中:
当 λ \lambda λ→0时, V t target V_t^{\text{target}} Vttarget→单步TD目标,此时偏差大方差小
当 λ \lambda λ→1时, V t target V_t^{\text{target}} Vttarget→MC目标,此时偏差小方差大
当0 < λ \lambda λ < 1时,是 n 步目标的几何加权平均,以平衡偏差与方差(PPO 通常取 λ \lambda λ = 0.95)。
GAE目标如何推导得到?
定义 TD 残差(Temporal Difference Error):
δ t = r t + γ V ϕ old ( s t + 1 ) − V ϕ old ( s t ) \delta_t = r_t + \gamma V_{\phi_{\text{old}}}(s_{t+1}) - V_{\phi_{\text{old}}}(s_t) δt=rt+γVϕold(st+1)−Vϕold(st)
定义 广义优势估计(GAE):
A t = ∑ l = 0 ∞ ( γ λ ) l δ t + l A_t = \sum_{l=0}^{\infty} (\gamma\lambda)^l \delta_{t+l} At=l=0∑∞(γλ)lδt+l
展开可得:
A t = G t ( λ ) − V ϕ old ( s t ) A_t = G_t^{(\lambda)} - V_{\phi_{\text{old}}}(s_t) At=Gt(λ)−Vϕold(st)
其中:
G t ( λ ) = ( 1 − λ ) ∑ n = 1 ∞ λ n − 1 G t ( n ) ) G_t^{(\lambda)} = (1-\lambda)\sum_{n=1}^{\infty}\lambda^{n-1} G_t^{(n)}) Gt(λ)=(1−λ)n=1∑∞λn−1Gt(n))
G t ( n ) = ∑ l = 0 n − 1 γ l r t + l + γ n V ϕ old ( s t + n ) G_t^{(n)}=\sum_{l=0}^{n-1}\gamma^l r_{t+l} + \gamma^n V_{\phi_{\text{old}}}(s_{t+n}) Gt(n)=l=0∑n−1γlrt+l+γnVϕold(st+n)
G t ( λ ) G_t^{(\lambda)} Gt(λ)就是所谓的 λ \lambda λ-回报( λ \lambda λ-return),它是所有 n 步 TD 目标的加权平均。
由此可得:
A t = G t ( λ ) − V ϕ old ( s t ) A_t = G_t^{(\lambda)} - V_{\phi_{\text{old}}}(s_t) At=Gt(λ)−Vϕold(st)
等号两边同时加上 V ϕ old ( s t ) V_{\phi_{\text{old}}}(s_t) Vϕold(st):
A t + V ϕ old ( s t ) = G t ( λ ) A_t + V_{\phi_{\text{old}}}(s_t) = G_t^{(\lambda)} At+Vϕold(st)=Gt(λ)
于是得到目标价值:
V t target = A t + V ϕ old ( s t ) = G t ( λ ) \boxed{V_t^{\text{target}} = A_t + V_{\phi_{\text{old}}}(s_t) = G_t^{(\lambda)}} Vttarget=At+Vϕold(st)=Gt(λ)
即目标价值其实就是 λ-return。
为什么 V t target V_t^{\text{target}} Vttarget可以有效地近似 V π ( s t ) V^{\pi}(s_t) Vπ(st)?
- 统计视角直观地理解:
当 V ϕ old V_{\phi_{\text{old}}} Vϕold越接近真值, δ t \delta_t δt 的期望越趋近 0, 则 V t target V_t^{\text{target}} Vttarget 的期望越接近真实状态价值 V π ( s t ) V^{\pi}(s_t) Vπ(st)
4.1.2.3 Critic loss的裁剪机制
裁剪机制与Actor loss的裁剪机制类似,是为了限制值函数更新的幅度,防止价值估计变化过大。
V ϕ c l i p ( s t ) = clip ( V ϕ ( s t ) , V ϕ o l d ( s t ) − ϵ , V ϕ o l d ( s t ) + ϵ ) = { V ϕ o l d ( s t ) − ϵ if V ϕ ( s t ) < V ϕ o l d ( s t ) − ϵ V ϕ o l d ( s t ) + ϵ if V ϕ ( s t ) > V ϕ o l d ( s t ) + ϵ V ϕ ( s t ) otherwise V_{\phi_{clip}} (s_t)=\text{clip}(V_{\phi}(s_t), V_{\phi_{old}}(s_t)-\epsilon, V_{\phi_{old}}(s_t)+\epsilon) = \begin{cases} V_{\phi_{old}}(s_t)-\epsilon & \text{if } V_{\phi}(s_t) < V_{\phi_{old}}(s_t)-\epsilon \\ V_{\phi_{old}}(s_t)+\epsilon & \text{if } V_{\phi}(s_t) > V_{\phi_{old}}(s_t)+\epsilon \\ V_{\phi}(s_t) & \text{otherwise} \end{cases} Vϕclip(st)=clip(Vϕ(st),Vϕold(st)−ϵ,Vϕold(st)+ϵ)=⎩ ⎨ ⎧Vϕold(st)−ϵVϕold(st)+ϵVϕ(st)if Vϕ(st)<Vϕold(st)−ϵif Vϕ(st)>Vϕold(st)+ϵotherwise
4.1.2.4 取max操作
首先一句话总结取max操作的作用:确保我们使用更保守的更新值,防止价值函数的不稳定变化。
下面我们来拆解为什么会有这个作用:
Critic Loss的单步损失为:
ℓ t ( ϕ ) = max ( ( V ϕ ( s t ) − V t target ) 2 , ( V ϕ clip ( s t ) − V t target ) 2 ) \ell_t(\phi) = \max\!\Big( (V_{\phi}(s_t)-V_t^{\text{target}})^2, (V_{\phi_{\text{clip}}}(s_t)-V_t^{\text{target}})^2 \Big) ℓt(ϕ)=max((Vϕ(st)−Vttarget)2,(Vϕclip(st)−Vttarget)2)
我们做的事情是:
比较原始误差项: ( V ϕ ( s t ) − V t t a r g e t ) 2 (V_{\phi}(s_t) - V_t^{target})^2 (Vϕ(st)−Vttarget)2 和 裁剪误差项: ( V ϕ c l i p ( s t ) − V t t a r g e t ) 2 (V_{\phi_{clip}} (s_t) - V_t^{target})^2 (Vϕclip(st)−Vttarget)2
取两者中较大的值(即max操作)
其中:
- V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st):Critic网络对状态 s t s_t st的价值预测
- V ϕ old ( s t ) V_{\phi_{\text{old}}}(s_t) Vϕold(st):Critic网络对状态 s t s_t st的旧价值预测
- V t t a r g e t V_t^{target} Vttarget:目标价值(通常基于实际回报和Bootstrapping计算)
- ϵ \epsilon ϵ:裁剪参数,(一般与Actor的 ϵ \epsilon ϵ相同)
- V ϕ clip ( s t ) V_{\phi_{\text{clip}}}(s_t) Vϕclip(st):裁剪后预测
- 其表达式为: V ϕ clip ( s t ) = clip ( V ϕ ( s t ) , V ϕ old ( s t ) − ϵ , V ϕ old ( s t ) + ϵ ) V_{\phi_{\text{clip}}}(s_t) = \text{clip}\!\left(V_{\phi}(s_t),\; V_{\phi_{\text{old}}}(s_t)-\epsilon,\; V_{\phi_{\text{old}}}(s_t)+\epsilon\right) Vϕclip(st)=clip(Vϕ(st),Vϕold(st)−ϵ,Vϕold(st)+ϵ)
所以,裁剪误差项也可以记为: ( V ϕ c l i p ( s t ) − V t t a r g e t ) 2 = ( clip ( V ϕ ( s t ) , V ϕ o l d ( s t ) − ϵ , V ϕ o l d ( s t ) + ϵ ) − V t t a r g e t ) 2 (V_{\phi_{clip}} (s_t) - V_t^{target})^2 = (\text{clip}(V_{\phi}(s_t), V_{\phi_{old}}(s_t) - \epsilon, V_{\phi_{old}}(s_t) + \epsilon) - V_t^{target})^2 (Vϕclip(st)−Vttarget)2=(clip(Vϕ(st),Vϕold(st)−ϵ,Vϕold(st)+ϵ)−Vttarget)2
- 其表达式为: V ϕ clip ( s t ) = clip ( V ϕ ( s t ) , V ϕ old ( s t ) − ϵ , V ϕ old ( s t ) + ϵ ) V_{\phi_{\text{clip}}}(s_t) = \text{clip}\!\left(V_{\phi}(s_t),\; V_{\phi_{\text{old}}}(s_t)-\epsilon,\; V_{\phi_{\text{old}}}(s_t)+\epsilon\right) Vϕclip(st)=clip(Vϕ(st),Vϕold(st)−ϵ,Vϕold(st)+ϵ)
为什么用 max?它发挥了什么作用?
一句话:max 保证“别靠裁剪来降低损失”。
上一小节我们提到:
V t target = A t + V ϕ old ( s t ) V_t^{\text{target}} = A_t + V_{\phi_{\text{old}}}(s_t) Vttarget=At+Vϕold(st)
在算法迭代过程中:
当 V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st) 跳得太猛时(即 V ϕ ( s t ) 离 V ϕ o l d ( s t ) V_{\phi}(s_t) 离 V_{\phi_{old}}(s_t) Vϕ(st)离Vϕold(st)远时),会越界(超过允许范围)触发裁剪。
裁剪会把它“夹回去”( V ϕ c l i p ( s t ) 离 V ϕ o l d ( s t ) V_{\phi_{clip}}(s_t) 离 V_{\phi_{old}}(s_t) Vϕclip(st)离Vϕold(st)更近)。
那么,显然有 V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st)跳的比 V ϕ c l i p ( s t ) V_{\phi_{clip}}(s_t) Vϕclip(st)远
此时, V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st)相比于 V ϕ c l i p ( s t ) V_{\phi_{clip}}(s_t) Vϕclip(st)可能有2种结果,①越界但“离目标更近” ②越界且“目标更远”
如果出现情况②,会使得 V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st) 跳得越远越容易触发裁剪,裁剪比未裁剪里离目标更近,于是鼓励大跳步,越跳越远
如果出现情况①,也会鼓励大跳步,步子越变越大,刚开始可能快速接近目标,然后刹不住车,变成情况②
所以,如果我们直接用裁剪后的价值网络 V ϕ clip ( s t ) V_{\phi_{\text{clip}}}(s_t) Vϕclip(st)训练,可能出现“越跳越远,离目标价值越近,critic误差越小”的假象
综上,max 的作用就是:对于 V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st)和 V ϕ c l i p ( s t ) V_{\phi_{clip}}(s_t) Vϕclip(st),谁离 V t target V_t^{\text{target}} Vttarget远,谁的Critic loss就大,谁的Critic loss大就用谁的,从而“惩罚”过度跳跃,避免模型“利用裁剪降低损失”。
更具体地说:
-
在允许范围内(未触发裁剪)
V ϕ ( s t ) ∈ [ V ϕ old − ϵ , V ϕ old + ϵ ] V_{\phi}(s_t)\in[V_{\phi_{\text{old}}}-\epsilon,\; V_{\phi_{\text{old}}}+\epsilon] Vϕ(st)∈[Vϕold−ϵ,Vϕold+ϵ]
此时 V ϕ clip ( s t ) = V ϕ ( s t ) V_{\phi_{\text{clip}}}(s_t)=V_{\phi}(s_t) Vϕclip(st)=Vϕ(st),两项相等,max不起额外作用,和普通的 MSE 一致。 -
越界但“朝向目标”那一侧(容易被利用的情形)
V ϕ ( s t ) V_{\phi}(s_t) Vϕ(st) 超过裁剪边界,且裁剪后的 V ϕ clip ( s t ) V_{\phi_{\text{clip}}}(s_t) Vϕclip(st) 更接近目标值。
如果只用裁剪误差训练,优化器会“发现”大胆越界可以让(被裁剪后的)损失更小,于是鼓励过度更新。max强制用原误差(更大的那一个)来训练,惩罚越界行为,杜绝“钻裁剪空子”。 -
越界且“远离目标”那一侧
不论是否裁剪,误差都大;max会选更大的那项,进一步对过度偏移施压,形成硬约束。
比喻:裁剪像“护栏”,
max像“罚分器”。撞到护栏(越界)不光不加分,还要多扣分,模型自然就不想老撞护栏了。
4.1.3 熵正则项
熵正则项鼓励探索,防止策略过早收敛到局部最优:
L E N T R O P Y = β ⋅ E t [ ∑ a π θ ( a ∣ s t ) log π θ ( a ∣ s t ) ] L^{ENTROPY} = \beta \cdot \mathbb{E}_{t} \left[ \sum_{a} \pi_{\theta}(a|s_t) \log \pi_{\theta}(a|s_t) \right] LENTROPY=β⋅Et[a∑πθ(a∣st)logπθ(a∣st)]
其中:
- β \beta β:熵正则项的权重系数
- ∑ a π θ ( a ∣ s t ) log π θ ( a ∣ s t ) \sum_{a} \pi_{\theta}(a|s_t) \log \pi_{\theta}(a|s_t) ∑aπθ(a∣st)logπθ(a∣st):策略的熵,衡量策略的随机性
4.1.3.2 熵正则项的作用机制
1.1 离散动作(Categorical/Softmax)策略
若策略为分类分布 π θ ( a ∣ s ) = p a \pi_\theta(a|s)=p_a πθ(a∣s)=pa,则
H ( π θ ( ⋅ ∣ s ) ) = − ∑ a p a log p a \mathcal{H}(\pi_\theta(\cdot|s)) = -\sum_{a} p_a \log p_a H(πθ(⋅∣s))=−a∑palogpa
若存在任意的a,当 p a → 1 p_a→1 pa→1, 则 log p a → 0 \log p_a→0 logpa→0, 此时有 H → 0 \mathcal{H}→0 H→0,
因为 ∑ a p a = 1 \sum_{a} p_a=1 ∑apa=1,所以当所有的 p a p_a pa的值互相之间相差很小时, H → m a x \mathcal{H}→max H→max
直观理解:当各动作的概率越均匀(接近均匀分布),熵越大;概率越集中,熵越小。
log的函数图像如下:
1.2 连续动作(高斯策略)
常见设定: π θ ( a ∣ s ) = N ( μ θ ( s ) , Σ θ ( s ) ) \pi_\theta(a|s)=\mathcal{N}\!\big(\mu_\theta(s),\Sigma_\theta(s)\big) πθ(a∣s)=N(μθ(s),Σθ(s)),若协方差对角(对每个维度 σ i 2 \sigma_i^2 σi2 独立):
H ( π θ ( ⋅ ∣ s ) ) = 1 2 ∑ i = 1 k ( 1 + log ( 2 π σ i 2 ( s ) ) ) = k 2 ( 1 + log 2 π ) + ∑ i = 1 k log σ i ( s ) . \mathcal{H}(\pi_\theta(\cdot|s)) = \frac{1}{2}\sum_{i=1}^k \left(1+\log(2\pi\sigma_i^2(s))\right) = \frac{k}{2}\big(1+\log 2\pi\big) + \sum_{i=1}^k \log \sigma_i(s). H(πθ(⋅∣s))=21i=1∑k(1+log(2πσi2(s)))=2k(1+log2π)+i=1∑klogσi(s).
关键点:熵与 σ \sigma σ(标准差)单调相关;更大的方差意味着更大的熵、更强的探索。
熵正则项通过增加策略的随机性来促进探索:
- 当策略趋于确定性时(熵值低),熵正则项会惩罚策略,鼓励探索其他动作
- 当策略随机时(熵值高),熵正则项的惩罚较小
- 通过调整 β \beta β可以控制探索与利用的平衡
4.1.3.2 熵在优化中如何发挥作用(梯度/更新机制)
1 离散动作的直觉梯度效应
熵为 H = − ∑ a p a log p a \mathcal{H}=-\sum_a p_a\log p_a H=−∑apalogpa,对 p a p_a pa 的梯度为
∂ H ∂ p a = − ( log p a + 1 ) . \frac{\partial \mathcal{H}}{\partial p_a}=-(\log p_a + 1). ∂pa∂H=−(logpa+1).
- 当 p a p_a pa 很小(罕见动作)时, log p a \log p_a logpa 很负, − ( log p a + 1 ) -(\log p_a+1) −(logpa+1) 变大 ⇒ 提升小概率动作的概率。
- 当 p a p_a pa 很大(常选动作)时, − ( log p a + 1 ) -(\log p_a+1) −(logpa+1) 变小 ⇒ 抑制过度确定性。
配合 softmax 链式法则,对 logits 的梯度会把过分尖锐的分布拉回更平滑、更多样。
2 连续动作的方差推动
对高斯策略, H \mathcal{H} H 对 log σ i \log\sigma_i logσi 的导数为常数 1(见上式的最后一项),
因此熵奖励会直接推动标准差增大。这使策略在无明显优势(advantage 微弱或噪声大)时保持更大的探索半径;当优势信号稳定一致时,策略仍可凭借 Actor 损失收敛变“窄”。
3 与策略梯度的叠加
以 PPO2(Clip)为例,Actor 损失(需最大化)为
L A C T O R ( θ ) = E [ min ( r t ( θ ) A ^ t , c l i p ( r t , 1 − ϵ , 1 + ϵ ) A ^ t ) ] , L^{ACTOR}(\theta)=\mathbb{E}\!\left[\min\!\big(r_t(\theta)\hat{A}_t,\;\mathrm{clip}(r_t,1-\epsilon,1+\epsilon)\hat{A}_t\big)\right], LACTOR(θ)=E[min(rt(θ)A^t,clip(rt,1−ϵ,1+ϵ)A^t)],
加入熵奖励后(同样是最大化目标)
L T O T A L = L A C T O R − c 1 L C R I T I C + c 2 E [ H ( π θ ) ] . L^{TOTAL} = L^{ACTOR} - c_1 L^{CRITIC} + c_2 \mathbb{E}[\mathcal{H}(\pi_\theta)]. LTOTAL=LACTOR−c1LCRITIC+c2E[H(πθ)].
因此总梯度中出现一项 + c 2 ∇ θ E [ H ] +\,c_2 \nabla_\theta \mathbb{E}[\mathcal{H}] +c2∇θE[H],
这项会在“Actor 想要把分布变尖(利用)”与“熵想要把分布变宽(探索)”之间形成张力,使训练在探索/利用之间自动权衡。
4.1.3.3 实践细节与常见技巧
-
系数调度(Entropy Coefficient Scheduling)
- 训练早期: c 2 c_2 c2 可稍大,鼓励广泛探索;
- 训练后期:逐步减小 c 2 c_2 c2(线性或指数衰减),让策略更专注利用。
-
目标熵(Target Entropy)/ 自适应调整
- 设定一个期望的熵水平 H target \mathcal{H}_\text{target} Htarget,根据当前熵与目标熵的偏差自适应更新 c 2 c_2 c2(SAC 等算法中常见思想)。
- 在 PPO2 中同样可借鉴:若熵低于目标,增大 c 2 c_2 c2;反之减小。
-
尺度选择
- c 2 c_2 c2 过大 ⇒ 策略一直很散,难以收敛;
- c 2 c_2 c2 过小 ⇒ 容易过早确定性,陷入局部最优或多样性不足。
- 经验范围: c 2 ∈ [ 10 − 3 , 10 − 2 ] c_2\in[10^{-3},10^{-2}] c2∈[10−3,10−2] 常见(需按任务/回报尺度调整)。
-
与 Advantage 估计的协同
- 当 A ^ t \hat{A}_t A^t 噪声较大或符号不稳定时,熵帮助避免策略被偶发高估牵着走;
- 当 A ^ t \hat{A}_t A^t 稳定且方向一致时,Actor 梯度占主导,策略仍会逐步从“宽”变“窄”。
4.2 PPO2算法的算法流程
PPO2算法的详细流程如下:
- 初始化:初始化策略参数 θ 0 \theta_0 θ0和价值函数参数 ϕ 0 \phi_0 ϕ0
- 数据收集:使用当前策略 π θ o l d \pi_{\theta_{old}} πθold与环境交互,收集多个episode的数据
- 优势估计:使用GAE(Generalized Advantage Estimation)计算优势估计值:
A ^ t = ∑ l = 0 ∞ ( γ λ ) l δ t + l \hat{A}_t = \sum_{l=0}^{\infty} (\gamma \lambda)^l \delta_{t+l} A^t=l=0∑∞(γλ)lδt+l
δ t = r t + γ V ( s t + 1 ) − V ( s t ) \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) δt=rt+γV(st+1)−V(st)
- 更新策略:对K个epoch执行:
- 将数据分成M个minibatch
- 对每个minibatch,计算并最大化裁剪目标函数
- 重复:重复步骤2-4直到收敛
4.2.1 使用GAE的优势函数计算
广义优势估计(GAE)结合了多步TD误差的优势:
A ^ t G A E = ∑ l = 0 T − t − 1 ( γ λ ) l δ t + l \hat{A}_t^{GAE} = \sum_{l=0}^{T-t-1} (\gamma \lambda)^l \delta_{t+l} A^tGAE=l=0∑T−t−1(γλ)lδt+l
其中:
- γ \gamma γ:折扣因子
- λ 极 \lambda极 λ极:GAE参数(介于0和1之间)
- δ t = r t + γ V ( s t + 1 ) − V ( s t ) \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) δt=rt+γV(st+1)−V(st):TD误差
4.3 PPO2算法核心概念解释
4.3.1 关键概念解释
- Epoch:完整遍历整个数据集的次数。在PPO中,我们使用同一批数据更新多次策略
- Rollout:从环境中收集经验的过程,通常包括多个episode或一定时间步的数据
- Clip:裁剪操作,限制概率比率或价值更新的幅度,确保稳定性
- Minibatch:将大数据集分成小批量,用于随机梯度下降
- Shuffle:随机打乱数据顺序,防止训练过程中的偏差
- Episode:从初始状态到终止状态的完整序列
- GAE:广义优势估计,通过结合多步TD误差来减少方差同时保持偏差较小
- 阻止跨episode累积:确保在计算回报和优势时,不混合不同episode的数据
4.3.2 示例说明
考虑CartPole环境(平衡杆游戏):
- 状态:小车位置、速度、杆角度、角速度
- 动作:向左或向右推小车
- 奖励:每步保持平衡获得+1奖励
Rollout过程:
- 使用当前策略与环境交互256个时间步,收集(s, a, r, s’)数据
- 计算每个状态的价值估计 V ( s ) V(s) V(s)
- 使用GAE计算优势估计 A ^ t \hat{A}_t A^t
Minibatch和Shuffle:
- 将256个时间步的数据随机打乱
- 分成4个minibatch,每个包含64个时间步的数据
Epoch更新:
- 对每个minibatch计算损失并更新策略
- 重复4个epoch,共16次更新
Actor Loss的Clip操作:
- 对于每个动作,计算概率比率 r t ( θ ) = π n e w ( a t ∣ s t ) π o l d ( a t ∣ s t ) r_t(\theta) = \frac{\pi_{new}(a_t|s_t)}{\pi_{old}(a_t|s_t)} rt(θ)=πold(at∣st)πnew(at∣st)
- 如果 A t > 0 A_t > 0 At>0,限制 r t ( θ ) r_t(\theta) rt(θ)不超过1.2
- 如果 A t < 0 A_t < 0 At<0,限制 r t ( θ ) r_t(\theta) rt(θ)不低于0.8
GAE计算:
- 设置 γ = 0.99 \gamma = 0.99 γ=0.99, λ = 0.95 \lambda = 0.95 λ=0.95
- 计算TD误差: δ t = r t + 0.99 × V ( s t + 1 ) − V ( s t ) \delta_t = r_t + 0.99 \times V(s_{t+1}) - V(s_t) δt=rt+0.99×V(st+1)−V(st)
- 计算GAE: A ^ t = δ t + 0.99 × 0.95 × δ t + 1 + ( 0.99 × 0.95 ) 2 × δ t + 2 + ⋯ \hat{A}_t = \delta_t + 0.99 \times 0.95 \times \delta_{t+1} + (0.99 \times 0.95)^2 \times \delta_{t+2} + \cdots A^t=δt+0.99×0.95×δt+1+(0.99×0.95)2×δt+2+⋯
阻止跨episode累积:
- 当遇到终止状态时,将后续的价值和优势计算清零
- 确保不将不同episode的数据混合计算
4.4 例子(ppo2算法解决平衡杆小车问题)
说明:
- 该案例将PPO2算法(ppo-clip)应用于解决Cartpole问题,给出ppo算法的想法思想和常用的ppo优化技巧,给出了python编码实现ppo2算法的细节
- 平衡杆小车问题简介
Cartpole是一种经典的控制问题,旨在通过对一个倒立摆系统的控制,使之保持平衡状态。该系统由一个固定在水平轴上的小车和一个垂直安装的杆组成。杆连接到小车上的铰链处,通过对小车施加水平力来控制杆的运动。
4.5 PPO2算法总结
PPO2算法通过裁剪机制约束策略更新幅度,在保持训练稳定性的同时实现了高效优化。其主要优点包括:
- 实现简单,无需复杂约束优化
- 计算高效,适合大规模应用
- 超参数少,易于调参
- 在大多数任务中表现良好
PPO2已成为强化学习领域的基准算法之一,在从游戏AI到机器人控制的各种应用中表现出色。
5 总结
PPO算法通过引入约束机制解决了传统策略梯度方法的不稳定问题,在强化学习领域做出了重要贡献。PPO1使用KL散度惩罚来约束策略更新,提供了理论上的稳定性保证;而PPO2采用更简单的裁剪机制,在实践中表现更好且更易于实现。
PPO算法的关键创新在于:
- 使用重要性采样实现样本高效利用
- 通过约束机制(KL散度或裁剪)控制更新幅度
- 结合价值函数学习减少方差
- 支持并行数据收集提高效率
随着强化学习的发展,PPO算法仍在不断改进和扩展,如应用于多智能体系统、结合模仿学习等,未来将继续在各种决策智能任务中发挥重要作用。
附录:PPO2算法Python实现示例
效果示例:
后记
在deepseek、GPT5辅助下完成。
更多推荐
所有评论(0)