参考链接:spinningup
前置知识点#
强化学习的基本循环:
智能体(Agent)在环境(Environment)中观察当前状态(State,简称
策略(Policy,
策略就是智能体大脑里的“行为准则”。在深度强化学习里,策略通常是一个神经网络。输入当前的画面/状态
优势函数(Advantage Function,
这个概念极其重要!它表示在状态
- 如果
:说明这个动作比平均水平好,我们应该鼓励(增加以后做这个动作的概率)。 - 如果
:说明这个动作比较糟糕,比乱玩还差,我们应该惩罚(降低做这个动作的概率)。
传统策略梯度(Vanilla Policy Gradient)的致命弱点:
传统的做法是:利用收集到的数据,计算梯度,直接更新神经网络。
痛点: 神经网络的更新步长(Learning Rate)极难把握!
- 步子迈小了:训练比蜗牛还慢。
- 步子迈大了: 策略一下子更新过头,可能从一个“还不错的策略”直接跌入深渊,导致彻底崩溃。更惨的是,由于后续还要用这个崩溃的坏策略去收集新数据,收集来的全都是垃圾数据,模型再也恢复不回来了。
PPO诞生背景#
为了解决策略更新过程中“步长过大导致训练不稳定”的问题,学者们先发明了 TRPO (Trust Region Policy Optimization, 信任区域策略优化)。TRPO 的核心思想是:限制每次策略更新的幅度,保证新策略和旧策略不要差得太远。
虽然 TRPO 效果很好,但它的数学推导极其复杂,涉及到复杂的二阶偏导矩阵运算(海森矩阵),代码写起来简直让人头秃,而且计算很慢。
于是,PPO 诞生了!PPO 的目标和 TRPO 一模一样,但它使用了一种极其巧妙、简单的一阶数学技巧(只用到了简单的 min 和 clip 裁剪函数)就达到了相同的限制效果。这也是为什么现在大家都用 PPO 而不用 TRPO 的原因。
PPO公式推导#
在 Spinning Up 的文档中,重点讲解了目前最常用的 PPO-Clip(裁剪版 PPO)。
1. 定义新旧策略的比率 (Ratio)#
首先,我们定义一个参数
- 分子:新策略(正在训练的策略)下,在状态
采取动作 的概率。 - 分母:旧策略(收集这批数据时的老策略)下,在状态
采取动作 的概率。
如果
2. 最原始的目标函数(未限制版)#
如果我们把刚才学到的比率和优势函数结合,最原始的优化目标是我们要最大化:
这很容易理解:如果动作好(
神经网络的唯一目标,就是把
的值变得“越大越好”(Maximize)。 无论是好动作还是烂动作,优化器都在拼命地最大化 。
3. PPO 的神来之笔:Clip(裁剪)机制#
为了不让新旧策略差距过大,PPO 引入了一个很小的超参数
PPO 会强制把比率
请看文档中的最终核心公式:
这公式为啥要取个 min?为什么要裁剪?我们分两种情况,用大白话翻译一下文档里的原理解释:
情况 A:当优势函数
- 我们希望增大新策略做这个动作的概率(即
越大越好,争取大于 1)。 - 但是,如果
增大到超过了 (比如变成了 1.5),clip函数就会把它强行“一刀切断”,死死摁在 。 - 因为最外层有个
min(取最小值),所以虽然你原本的项涨到了 ,但被裁剪的项是 。取两者较小的一个,目标函数的值就被锁死在 了。再往上走,目标函数也不会增加,神经网络也就失去了继续推高概率的动力。 - 大白话结论: 对于好动作,PPO 鼓励你多做,但见好就收,新策略涨幅超过旧策略 20% 就不再奖励你了。这就防止了策略突变。
情况 B:当优势函数
- 我们希望减小做这个动作的概率(即
越小越好,争取小于 1)。 - 此时
是个负数。如果 不断减小,跌破了 (变成了 0.8 以下,比如 0.5),clip函数会把它下限锁死在 0.8。 - 同样因为外层有个
min(注意这里 是负的,所以 0.5 * (-10) = -5,而 0.8 * (-10) = -8。取更小的值,即 -8)。 - 大白话结论: 对于烂动作,PPO 让你以后少做,但做动作的概率降幅超过 20% 也就差不多了,没必要赶尽杀绝。
情况B有些绕,我们为什么说-8的降幅反而更小?
例子:假设现在智能体做了一个烂动作,优势函数
。 概率比率
的原先值是 1.0。 为什么?因为在刚刚开始更新这批数据时,新策略就等于旧策略。所以
。 KPI得分(目标函数
)的原先值是 -10。 既然一开始
,而这个动作是个烂动作(优势 ),那么一开 始的得分 。 记住这个基准点:神经网络还没开始发力时,它在这个动作上的初始 KPI 是 -10分。它的目标是把这个分数越变越大(比如变成 -8,-5,甚至 0)。
关于“做动作的概率(
)”:
- 从 1.0 降到 0.8:概率降了 20%(降幅小)。
- 从 1.0 降到 0.5:概率降了 50%(降幅大)。
- 你说得对,0.5 的概率降幅确实更大!
关于“KPI得分(
)”:(注意,分数是越大越好)
如果概率降到 0.8,KPI 从 -10 涨到了 -8。
如果概率降到 0.5,KPI 从 -10 涨到了 -5。
对于神经网络来说,-5 分比 -8 分更高! 所以,如果不加
min限制,神经网络为了拿到最高的 -5 分,它会选择把概率降幅搞得非常大(降到 0.5)。但是,教导主任(
min函数)介入了:当你把概率降到 0.5 时,教导主任不给你 -5 分,强行只给你 -8 分。既然降 50% 只能拿 -8 分,降 20% 也能拿 -8 分,神经网络就会“偷懒”,只降 20% 就停手了。这就成功实现了“限制策略更新幅度(不让降幅太大)”的目的。
如果不加限制(概率往 0 压),是不是表示不会探索新的动作了?
恰恰相反!如果烂动作的概率被瞬间压到 0,它会去疯狂做别的动作,但这会导致一个极其可怕的后果:策略崩溃(Catastrophic Forgetting)。
如果
,这就意味着在这个特定的状态下,神经网络输出做这个动作的新概率变成了 0。 那么,为什么说“如果新概率变成了 0,它会去疯狂做别的动作”,这又怎么导致了“策略崩溃”呢?
1. 为什么新概率变成 0,就意味着“疯狂做别的动作”?#
强化学习中的策略(Policy,即那个神经网络),在任何一个状态下输出的,是所有可能动作的概率分布。
概率分布有一个铁律:所有动作的概率加起来必须等于 1(或 100%)。
假设在状态
下,你有 3 个可能的动作:动作 A、动作 B、动作 C。 一开始(旧策略),它们被选中的概率是:
- A: 33%
- B: 33%
- C: 33%
现在,你试了动作 A,发现是个烂动作(优势
)。 如果你不加 PPO 的限制,优化器为了把 KPI(目标函数
)最大化,会瞬间把做动作 A 的新概率压到 0(即 变成 0)。 那么,剩下的概率(那 100%)去哪了呢?
由于所有概率加起来必须是 100%,神经网络被迫要把这 100% 的概率分配给剩下的动作 B 和 C。
于是,新策略的概率可能瞬间变成了:
- A: 0% (之前是 33%)
- B: 50% (之前是 33%)
- C: 50% (之前是 33%)
你看,虽然你只是把 A 压到了 0,但作为连锁反应,你被迫大幅度提高了做 B 和 C 的概率。这就是我说的“去疯狂做别的动作”。
2. 为什么这种“瞬间把某个动作压到 0,强抬其他动作”会导致“策略崩溃”?#
这正是没有 PPO 限制时最致命的问题,主要有两点原因:
致命点一:你可能错杀了“好动作”#
在强化学习刚开始训练的时候,你的价值网络(Critic,用来评价动作好坏的)是极不准确的。
你以为动作 A 是个烂动作(算出来
),但实际上,它可能是一个极好的动作,只是因为你后续没走好,或者你的评价网络还没训练好,给了它一个错误的差评。
- 如果没有限制: 你因为一个错误的评价,瞬间把动作 A 压成了 0。一旦概率变成 0,智能体在接下来的探索中永远不可能再选到动作 A 了。它永远失去了发现动作 A 真实价值的机会。这就叫“盲目封杀”。
- 如果用 PPO 限制: 就算评价网络说它是烂动作,PPO 的
min和clip机制也只允许你把动作 A 的概率最多降 20%(比如从 33% 降到 26.4%)。它依然有机会被选中,如果在未来几轮更新中,评价网络变聪明了,发现动作 A 其实很好,它还有机会把概率涨回来。致命点二:神经网络的“牵一发而动全身”(灾难性遗忘)#
这是深度学习(神经网络)底层的特性。神经网络不是一个一个独立的抽屉,它是一个复杂的黑盒,参数是高度纠缠的。
当你不加限制,要求神经网络在这一次更新中发生剧烈变化(比如硬生生把某个输出从 33% 掰到 0%),这在数学上需要产生极其巨大的梯度(参数更新量)。
这一大脚油门踩下去,整个神经网络的参数全乱套了。
为了迎合这个“把动作 A 变成 0”的极端要求,网络可能会彻底破坏掉它在其他状态下好不容易学到的好策略。这就像是你要修正文章里的一个错别字,结果一锤子下去把整台电脑砸烂了。这就叫策略崩溃(Policy Collapse)或灾难性遗忘(Catastrophic Forgetting)。
注意:在绝大多数经典的强化学习场景中,动作空间(能做什么动作)是人类(开发者)提前定义好的,也就是“列出来的”。智能体不能凭空“发明”出你没有定义过的全新动作。
例子:超级玛丽 你能做的动作就是手柄上的按钮组合:[上、下、左、右、跳、加速]。 或者更简单点,我们就定义 3 个动作:A(往左跑)、B(往右跑)、C(原地跳)。
核心总结: PPO 的公式完美地贯彻了一个人生哲理——“步子不要迈太大,新策略不要偏离旧策略太多,稳扎稳打,每天进步一点点就好”。