简介:《强化学习的数学原理》是西湖大学赵世钰教授撰写的英文专著,面向具备线性代数、概率论与优化基础的研究生及算法工程师,系统解决强化学习理论理解不深、数学推导脱节、算法原理模糊等核心痛点。全书以马尔可夫决策过程为起点,逐章深入状态值与贝尔曼方程、最优策略与贝尔曼最优方程、值迭代与策略迭代、蒙特卡洛与时间差分方法、策略梯度与Actor-Critic框架,并在附录中严谨论证序列收敛性,辅以网格世界等直观示例和矩阵-向量形式的数学表达,显著提升理论可读性与可计算性。资源为单文件PDF,共1个18.9MB高清电子书,内容完整覆盖10章正文与附录,排版规范、公式清晰、章节逻辑严密,便于精读推导与课堂讲义参考。目前已有845人学习下载,适合希望夯实RL数学根基、开展理论研究或复现经典算法的学习者。
1. 这不是又一本“调库跑通就完事”的强化学习书:它用网格世界+手推公式,把贝尔曼方程、值迭代、策略梯度这些黑匣子全拆开给你看透
你有没有试过:照着《动手学强化学习》跑通一个 CartPole,但一看到论文里“由贝尔曼最优方程导出的策略梯度定理”就卡住?不是代码报错,是根本不知道那个 ∇θ log πθ(a|s) 是从哪冒出来的,更别说为什么它能和 Qπ(s,a) 相乘后还能无偏估计策略梯度。这不是你数学差——是绝大多数中文资料跳过了最关键的“数学缝合点”:从马尔科夫决策过程(MDP)的定义,到贝尔曼方程的构造,再到策略改进定理的证明,中间每一步的逻辑断层,都被默认用“读者自行脑补”填平了。而赵世钰老师这本《Mathematical Foundations of Reinforcement Learning》,就是专治这种“知道怎么写代码、但不知道为什么这么写”的认知断层。它不讲 PyTorch API,不堆 RLlib 配置项,而是用一个贯穿全书的 4×4 网格世界(grid world),从第 13 页第一个状态转移概率表开始,手把手推导每一个贝尔曼方程的矩阵形式、每一次值迭代的收敛边界、每一轮策略梯度更新的期望偏差来源。它假设你懂线性代数和概率论基础(附录 A/B/C 已帮你温习),但绝不假设你“应该懂”随机近似中的 Dvoretzky 收敛定理——第 6 章整整 23 页,就为讲清楚为什么 SGD 在非凸目标下仍能收敛。这本书不是让你“学会用强化学习”,而是让你在调试一个 diverging 的 Actor-Critic 损失时,能立刻反应过来:“哦,这里没做 baseline 减法,导致梯度方差爆炸,得回 Chapter 10.2.1 看 A2C 的 baseline 不变性证明”。它适合三类人:刚学完《统计学习方法》想啃 RL 数学内核的研究生;在工业界用 PPO 调参半年却总被问“为什么 clip ratio 设 0.2”的算法工程师;还有那些翻遍 Sutton 书评却还在纠结“off-policy 和 on-policy 的本质区别到底在测度空间还是策略空间”的理论爱好者。它不承诺“7 天速成”,但它保证:当你合上第 10 章最后一页,再看到任何一篇顶会论文里的 policy gradient theorem,你第一反应不再是复制公式,而是下意识去检查它的假设条件是否满足——这才是真正把强化学习从“玄学调参”变成“可验证工程”的起点。
2. 把贝尔曼方程从黑板公式变成可执行的数值解:状态值计算的两种路径与矩阵实现细节
2.1 为什么必须先手算一个 4×4 网格世界的贝尔曼方程?
翻开第 2 章第 1 节,你会看到一个看似简单的 4×4 网格世界:起始状态 s₀ 在左上角,目标状态 sₜ 在右下角,每个格子有上下左右四个动作,碰到边界则停留并获得 -1 奖励,到达目标获得 +10 奖励。这个例子绝非教学摆设。它被刻意设计成状态数足够小(16 个)、动作数固定(4 个)、转移概率完全已知(确定性+边界反射),从而让所有数学对象都能显式写出——这是后续所有算法可验证性的基石。比如,在 2.6 节“Matrix-vector form of the Bellman equation”中,作者直接给出状态转移矩阵 P ∈ ℝ¹⁶ˣ¹⁶ 和奖励向量 r ∈ ℝ¹⁶,其中 P[i,j] = Pr(s′=j | s=i, a=↑),r[i] 是在状态 i 执行任意动作的即时奖励期望。这种显式构造,使得你能在 Python 中用不到 20 行代码复现整个贝尔曼算子 T^π(v) = r + γPv:
import numpy as np # 构建 4x4 网格世界的状态索引映射:(row, col) -> state_id def state_to_id(row, col): return row * 4 + col # 初始化转移矩阵 P (16x16) 和奖励向量 r (16,) P = np.zeros((16, 16)) r = np.full(16, -1.0) # 默认碰壁惩罚 r[state_to_id(3, 3)] = 10.0 # 目标状态奖励 # 填充 P:以向上动作为例(其他方向同理) for row in range(4): for col in range(4): s = state_to_id(row, col) if row == 0: # 顶部边界,向上仍停留在原地 s_next = s else: s_next = state_to_id(row-1, col) P[s, s_next] = 1.0 # 确定性转移 # 定义贝尔曼算子 T^π(v) = r + γ * P @ v def bellman_operator(v, gamma=0.9): return r + gamma * P @ v # 初始状态值向量(全零) v = np.zeros(16) # 迭代一次 v_new = bellman_operator(v) print("第一次迭代后状态值 v[0](起始状态):", v_new[0])提示:这段代码的关键不在
@运算符,而在P的构造逻辑。P[s, s_next] = 1.0显式体现了 MDP 的核心假设——状态转移是马尔可夫的、且由策略 π 决定。如果你把P换成随机策略下的加权平均(如 π(a=↑)=0.25),P就变成了策略依赖的P^π,这正是 2.7.2 节“Iterative solution”中值迭代收敛的起点。没有这个显式矩阵,你永远只能模糊地说“贝尔曼方程把当前值和未来值联系起来”,而无法在调试时定位:到底是γ设太大导致振荡,还是P的某一行没归一化导致概率泄露。
2.2 闭式解 vs 迭代解:何时该用 (I − γP)^−¹,何时必须迭代?
2.7.1 节给出了状态值的闭式解:v^π = (I − γP^π)⁻¹ r^π。这看起来很美,但实际落地时,它是一把双刃剑。我们来对比两种求解路径:
| 求解方式 | 适用场景 | 计算复杂度 | 数值稳定性 | 可解释性 |
|---|---|---|---|---|
闭式解(I − γP)^−¹ r | 状态数 ≤ 1000,P 稀疏且良态 | O(n³) 矩阵求逆 | 对γ接近 1 敏感,易因条件数大而失真 | 直观显示 v^π 是 r 的线性变换,便于分析扰动影响 |
迭代解v_{k+1} = r + γP v_k | 任意规模,尤其适合稀疏 P 或函数逼近 | O(n²) 每轮,收敛轮数取决于 γ | 鲁棒性强,天然带阻尼 | 清晰展示收敛轨迹,可监控每轮误差 ` |
实践中,我一般会强制自己先跑一遍闭式解(哪怕只用于 16 状态的小世界),目的不是为了结果,而是为了校验 P 和 r 的构造是否正确。如果np.linalg.inv(np.eye(16) - 0.9 * P) @ r算出的v[0]是负无穷或 nan,那一定是P的某一行没归一化(比如边界状态的自循环概率没设为 1)。而迭代解则是真正的主力——第 4 章的值迭代(Value Iteration)和策略迭代(Policy Iteration)全部基于此。注意 2.7.2 节强调的收敛判据:||v_{k+1} − v_k||_∞ < ε。这个无穷范数(max norm)比 L2 范数更严格,因为它要求所有状态的值更新都小于阈值,避免了某些状态值已收敛、另一些却还在大幅震荡的假收敛现象。这也是为什么你在实现 VI 时,看到的终止条件总是np.max(np.abs(v_new - v)) < 1e-6,而不是np.linalg.norm(v_new - v)。
2.3 从状态值 v(s) 到动作值 q(s,a):贝尔曼方程的升维与策略解耦
2.8 节是全书第一个关键跃迁:把价值函数从状态空间v(s)扩展到状态-动作对空间q(s,a)。这步看似只是多了一个维度,实则彻底改变了策略优化的范式。v(s)描述的是“在状态 s 下,按策略 π 行动的长期收益”,而q(s,a)描述的是“在状态 s 下,先执行动作 a,再按策略 π 行动的长期收益”。这个“先执行 a”的操作,把策略 π 从价值计算中暂时剥离,使得q(s,a)成为一个策略无关的评估工具——你甚至可以评估一个你从未打算执行的策略(比如在悬崖行走环境中评估“向悬崖跳”这个动作)。其贝尔曼方程为:
q^π(s,a) = Σ_{s'} P(s'|s,a) [ r(s,a,s') + γ Σ_{a'} π(a'|s') q^π(s',a') ]这个公式在 2.8.2 节被重写为矩阵形式,但更重要的是它的实践含义:q(s,a)允许你做策略改进(policy improvement)。第 3 章的贝尔曼最优方程q*(s,a) = Σ_{s'} P(s'|s,a)[r(s,a,s') + γ max_{a'} q*(s',a')],本质上就是说:最优动作a*就是让q*(s,a)最大的那个a。这直接催生了 Q-learning(第 7.4 节)——它不再需要知道P和r,只需用采样得到的(s,a,r,s')元组,通过q(s,a) ← q(s,a) + α[r + γ max_{a'} q(s',a') − q(s,a)]来逼近q*。所以,如果你现在还在用v(s)做策略选择(比如argmax_a Σ_s' P(s'|s,a) v(s')),说明你还没真正跨过从“状态价值”到“动作价值”的门槛。而这本书,用整整一节(2.8)和三个示例(2.8.1),把这个门槛踩实了。
3. 贝尔曼最优方程不是终点,而是策略改进的起点:BOE 的收缩性证明与最优策略存在性验证
3.1 为什么“最优策略存在”这件事需要被严格证明?
初学者常误以为“最优策略”是天经地义的——既然每个策略都有一个性能指标 J(π),那取最大值的那个 π* 当然存在。但数学上,这远非显然。J(π) 的定义是E_π[Σ_t γ^t r_t],这是一个在无限维策略空间上的泛函,且策略 π 本身是一个从状态到动作分布的映射(即 π: S → Δ(A))。如果没有额外约束,这个最优化问题可能没有解(例如,J(π) 上确界可达但无对应策略),或解不唯一。第 3 章开篇(3.1 节)用一个精巧的网格世界反例直击要害:当折扣因子 γ=1(即不打折)且存在零成本循环路径时,J(π) 可能发散,此时“最优”失去意义。因此,3.2 节明确给出最优策略存在的充分条件:有限状态/动作空间 + 0 ≤ γ < 1。这个看似简单的条件,背后是第 3.3.3 节“Contraction mapping theorem”的支撑——它证明了贝尔曼最优算子T*是一个压缩映射(contraction mapping),从而保证其不动点q*存在且唯一。这个证明不是炫技,而是你后续所有算法收敛性分析的根基。比如,Q-learning 的收敛性(7.4.3 节)直接引用了T*的压缩性;而 DQN 的稳定性分析(8.4.1 节)则依赖于T*在神经网络参数空间上的近似压缩性。如果你跳过这一章,那么当你的 DQN 在训练后期 loss 突然飙升时,你只会归咎于“学习率太大”,而不会想到去检查γ是否设为 0.999(接近 1 导致压缩系数γ过小,收敛变慢且易受噪声干扰)。
3.2 贝尔曼最优方程(BOE)的矩阵形式:如何把max操作嵌入线性代数框架?
3.3.2 节将 BOE 写成矩阵形式:q* = r + γ P max_{a'} q*,这里的max_{a'}是一个非线性操作,无法像P^π那样直接写成矩阵乘法。作者没有回避这个难点,而是引入了策略相关矩阵P^π的集合:对每个策略 π,定义P^π,则T* q = max_π { r + γ P^π q }。这个表达式揭示了 BOE 的本质——它不是一个固定算子,而是所有策略对应的贝尔曼算子T^π的上包络(upper envelope)。这意味着,求解q*等价于在所有T^π中找到那个能产生最大q值的π。这个视角直接导向了第 4 章的策略迭代(Policy Iteration):π_{k+1}(s) = argmax_a q^{π_k}(s,a)。PI 的每一轮,都在用当前q^{π_k}去“投票”选出下一个更好的π_{k+1},而 BOE 的压缩性保证了这个投票序列必然收敛到π*。在代码实现中,这个argmax_a就是np.argmax(q_table[s, :]),但它的数学重量,远不止这一行代码。它意味着:策略改进不是启发式搜索,而是 BOE 压缩性在离散策略空间上的自然投影。
3.3 收缩映射定理(Contraction Mapping Theorem)的实操解读:为什么γ是收敛的命门?
3.3.3 节的收缩映射定理是本书的数学心脏。它说:若算子T满足||T u − T v|| ≤ γ ||u − v||(γ ∈ [0,1)),则T有唯一不动点,且迭代u_{k+1} = T u_k必收敛。在 BOE 中,T*的收缩系数就是折扣因子γ。这个γ不仅控制着未来奖励的衰减,更直接决定了算法收敛的速度和鲁棒性。我们来量化这个影响:
γ值 | 收缩系数 | 迭代收敛所需轮数(估算) | 对采样噪声的敏感度 | 典型适用场景 |
|---|---|---|---|---|
| 0.8 | 0.8 | ~15 轮达到1e-3误差 | 低,噪声被快速衰减 | 简单控制任务(如 GridWorld) |
| 0.99 | 0.99 | ~450 轮才能达到同等精度 | 高,早期噪声持续影响 | 长期规划任务(如机器人导航) |
| 0.999 | 0.999 | ~4500 轮,极易发散 | 极高,需极强正则化 | 理论分析,极少用于实践 |
这个表格不是凭空而来,它来自定理中收敛速率的显式界:||q_k − q*|| ≤ γ^k / (1−γ) ||q_0 − T* q_0||。当γ=0.999时,γ^k衰减极慢,分母1−γ=0.001又极小,导致初始误差被放大千倍。这就是为什么你在实现 Q-learning 时,如果γ设为 0.999 却没配合适当的 learning rate decay 或 target network,loss 曲线一定会出现剧烈震荡。而这本书在 3.3.4 节专门证明了T*确实满足收缩性,其系数就是γ——它不是经验参数,而是数学定理的输入变量。理解这一点,你就不会再盲目调γ,而是会先问:“我的任务 horizon 是多少?γ^H是否已衰减到可忽略(如 <0.01)?”。
4. 值迭代与策略迭代:不只是两个算法,而是“评估-改进”范式的两种实现哲学与收敛性边界
4.1 值迭代(VI):用单个算子T*同时完成评估与改进的极致简化
4.1 节的值迭代算法,表面看只有一行核心:q_{k+1}(s,a) ← Σ_{s'} P(s'|s,a)[r(s,a,s') + γ max_{a'} q_k(s',a')]。但这行代码承载着一种深刻的工程哲学:放弃对中间策略 π 的显式表示,只追踪价值函数q,让max操作隐式地完成策略改进。VI 的优势在于简洁和内存效率——你只需要维护一个|S|×|A|的q表,无需存储策略π。但它的代价是收敛轮数多。因为每次迭代,q_k只向q*靠拢γ的距离,而策略π_k的变化是滞后的。在 4.1.2 的示例中,作者用 4×4 网格世界展示了:即使q值已基本稳定(||q_{k+1}−q_k||<1e-5),π_k可能仍在微调。这在实践中意味着:如果你用 VI 训练一个智能体,并在q收敛后立即部署π(s)=argmax_a q(s,a),它可能是次优的,因为q的微小误差会被argmax放大。这也是为什么 VI 更适合离线规划(如机器人路径规划),而非在线学习。
4.2 策略迭代(PI):显式分离评估(Policy Evaluation)与改进(Policy Improvement)的稳健路径
4.2 节的策略迭代,则是另一种哲学:承认评估和改进是两个独立且可优化的步骤。PI 的循环是:
- 评估:固定
π_k,用迭代法(2.7.2)求解v^{π_k}或q^{π_k},直到收敛; - 改进:用
π_{k+1}(s) = argmax_a q^{π_k}(s,a)更新策略。
这个分离带来了两大好处:收敛轮数少、策略单调提升。4.2.1 节的算法分析指出,PI 的策略序列π_0, π_1, ...满足J(π_0) ≤ J(π_1) ≤ ... ≤ J(π*),即每一步都严格不降。这源于改进步骤的贪婪性:π_{k+1}在每个状态s都选择了比π_k更优的动作。但在实践中,“评估”步骤的“直到收敛”是个陷阱。4.2.2 节明确指出:完全收敛的评估是奢侈的,通常只需几轮迭代即可获得足够好的q^{π_k}来进行有效改进。这直接引出了 4.3 节的截断策略迭代(Truncated PI)——它规定评估只做m轮(如m=1就是著名的“值迭代”!),然后改进。这揭示了一个深刻事实:VI 和 PI 并非对立,而是m的连续统:m=∞是经典 PI,m=1是 VI,m=3~5是工业界常用的折中。我在某跨平台系统中实现 PI 时,就固定m=3,既避免了 PI 的长评估耗时,又比 VI 的策略更新更稳健。
4.3 截断策略迭代(Truncated PI):在收敛速度与计算开销间找平衡点的工程艺术
4.3.1 节的对比表格清晰列出了 VI、PI、Truncated PI 的特性。但真正决定你选哪个的,是你的计算瓶颈在哪。如果状态空间巨大(如图像输入),P和r不可得,你必须用采样(Monte Carlo 或 TD),此时 VI 的max操作无法执行,PI 的评估步骤也无从谈起——这正是第 5、7 章要解决的问题。但如果是在已知模型的中小规模问题(如资源调度、游戏 AI),Truncated PI 往往是最佳选择。它的伪代码(4.3.2)非常简单:
for k = 0,1,2,... until convergence: # Truncated Policy Evaluation: run m iterations of v_{i+1} = r + γ P^{π_k} v_i v = v^{π_k} # initial guess for i = 1 to m: v = r + γ P^{π_k} v # Policy Improvement π_{k+1}(s) = argmax_a Σ_{s'} P(s'|s,a)[r(s,a,s') + γ v(s')]这里的m是关键超参。m=1就是 VI;m=∞是 PI;m=2~4是黄金区间。我一般会先用m=1(即 VI)跑通 baseline,然后逐步增加m,监控J(π_k)的提升幅度。一旦J(π_{k+1}) − J(π_k)的增量小于1e-3,就停止增加m。这个过程,本质上是在用计算资源购买策略质量,而这本书,给了你精确衡量这笔交易的数学标尺。
5. 避坑指南:强化学习数学推导中最容易翻车的五个边界情况与血泪排查记录
5.1 现象:贝尔曼方程迭代v_{k+1} = r + γ P v_k发散,v值爆炸增长
原因:γ设置过大(≥1)或P矩阵未归一化(某行元素和 ≠ 1)。γ ≥ 1违反了收缩映射定理的前提;P行和不为 1 意味着概率泄露,导致P^k的谱半径 > 1,γ^k P^k项不衰减。
解决:首先用np.allclose(P.sum(axis=1), 1.0)检查P;其次确保0 ≤ γ < 1,若任务需长视界,优先调小 learning rate 而非增大γ;最后,打印np.linalg.eigvals(P),确认其最大特征值模长 ≤ 1。
5.2 现象:策略迭代(PI)中,π_{k+1}与π_k完全相同,但J(π_k)未达理论最优值
原因:策略评估(Policy Evaluation)未充分收敛。v^{π_k}的近似误差导致argmax_a q^{π_k}(s,a)选出了错误动作,而该错误动作恰好又使π_{k+1} = π_k,形成局部最优陷阱。
解决:提高评估迭代轮数m;或改用更鲁棒的评估方法,如在v更新中加入 damping:v_{i+1} = (1−β) v_i + β (r + γ P^{π_k} v_i)(β=0.1);最根本的是,用q^{π_k}而非v^{π_k}进行改进,因为q直接关联动作。
5.3 现象:蒙特卡洛(MC)方法估计的q(s,a)方差极大,学习曲线剧烈抖动
原因:MC 使用完整 episode 的回报G_t作为q(s,a)的无偏估计,但G_t方差随 episode 长度指数增长(尤其γ接近 1 时)。单个 episode 的随机性被全额传递给梯度。
解决:采用 MC Exploring Starts(5.3 节)确保所有(s,a)对被充分访问;或转向 TD 方法(7.1 节),用 bootstrapping 降低方差;在函数逼近场景(8.2 节),务必使用 experience replay 和 target network 来稳定训练。
5.4 现象:Q-learning 更新q(s,a) ← q(s,a) + α[r + γ max_{a'} q(s',a') − q(s,a)]中,max_{a'} q(s',a')总是选到同一个动作,探索停滞
原因:q值初始化偏差或学习率α过小,导致q值在早期就形成“强者恒强”的马太效应;或ε-greedy的ε衰减过快(5.4 节)。
解决:q表初始化为小随机数(如np.random.randn(|S|,|A|)*0.01),而非全零;ε衰减采用线性或指数衰减,确保在训练后期仍有ε > 0.01;在 7.4.2 节“Off-policy vs on-policy”中,作者强调 Q-learning 的 off-policy 特性允许你用ε-greedy行为策略收集数据,但用greedy目标策略更新,这本身就是一种探索保障。
5.5 现象:策略梯度(REINFORCE, 9.4 节)训练中,梯度∇_θ log π_θ(a|s) * G_t的方差导致 loss 不下降甚至上升
原因:G_t是高方差的回报估计,直接相乘放大了梯度噪声;且log π_θ(a|s)在π_θ(a|s)极小时会产生极大梯度(数值不稳定)。
解决:引入 baselineb(s),用G_t − b(s)替代G_t(10.2.1 节 A2C 的核心);b(s)可用状态值函数v_φ(s)近似,这就是 Actor-Critic 的起源;同时,对π_θ使用 softmax 输出,并添加 entropy regularization 项−β H(π_θ(·|s))来鼓励探索,防止π_θ(a|s)趋近于 0。
6. 用“策略梯度定理”的原始推导,反向验证你写的每一行 PPO 代码:从 REINFORCE 到 A2C 的数学一致性检验
6.1 REINFORCE 的梯度公式∇_θ J(θ) = E_π[∇_θ log π_θ(a|s) · G_t]是怎么来的?
9.3 节花了整整 12 页(9.3.1 + 9.3.2)推导这个公式,其核心是交换期望与梯度的顺序。J(θ) = E_{τ∼π_θ}[R(τ)],其中τ=(s₀,a₀,s₁,a₁,...)是轨迹,R(τ)=Σ_t γ^t r_t。关键一步是将轨迹τ的概率p(τ|θ)拆解为p(s₀) Π_t π_θ(a_t|s_t) p(s_{t+1}|s_t,a_t)。由于p(s₀)和p(s_{t+1}|s_t,a_t)与θ无关,它们的梯度为 0,只剩下∇_θ log π_θ(a_t|s_t)项。最终得到:
∇_θ J(θ) = Σ_τ p(τ|θ) R(τ) ∇_θ log p(τ|θ) = Σ_τ p(τ|θ) R(τ) Σ_t ∇_θ log π_θ(a_t|s_t) = E_{τ∼π_θ}[ Σ_t ∇_θ log π_θ(a_t|s_t) · R(τ) ]而R(τ)从t开始的部分就是G_t,故得 REINFORCE。这个推导的魔鬼细节在于:G_t是从时间t开始的回报,不是R(τ)的全部。这意味着,在代码中,你不能用G_0去更新所有t的梯度,而必须对每个(s_t,a_t)对,用对应的G_t。这是新手写 REINFORCE 时最常见的错误——用 episode 总回报G_0更新所有时间步的策略参数,导致梯度污染。
6.2 A2C 的 baselineb(s_t) = v_φ(s_t)如何做到“减小方差而不引入偏差”?
10.2.1 节的“Baseline invariance”是策略梯度方法的基石。它证明:对任意函数b(s),∇_θ J(θ) = E_π[∇_θ log π_θ(a|s) · (G_t − b(s))]依然成立。因为E_π[∇_θ log π_θ(a|s) · b(s)] = b(s) · E_π[∇_θ log π_θ(a|s)] = b(s) · ∇_θ E_π[1] = 0(E_π[1]=1是常数)。所以b(s)的加入不改变期望值(无偏),但能显著降低方差。最优的b(s)是E_π[G_t | s_t=s] = v^π(s),即状态值函数。A2C(10.2.2 节)正是用一个神经网络v_φ(s)来近似v^π(s),并在每个(s_t,a_t)更新时,计算advantage = G_t − v_φ(s_t),再用∇_θ log π_θ(a_t|s_t) · advantage更新策略网络。这个advantage就是“优势函数”,它回答了“在这个状态下执行这个动作,比平均好多少”。在代码中,这意味着你必须同步训练两个网络:Actor(输出π_θ(a|s))和 Critic(输出v_φ(s)),且 Critic 的 loss 是MSE(v_φ(s_t), G_t)。漏掉 Critic 或用G_t直接更新 Actor,就退化成了高方差的 REINFORCE。
6.3 从数学一致性看 PPO 的clip操作:它如何在策略梯度框架下保证更新的安全性?
PPO(Proximal Policy Optimization)虽未在本书中详述,但其核心思想根植于第 9、10 章。PPO 的clip操作min(r_t(θ) A_t, clip(r_t(θ), 1−ε, 1+ε) A_t),本质是对策略比率r_t(θ) = π_θ(a_t|s_t)/π_θ_old(a_t|s_t)施加硬约束,防止单步更新过大。这对应于策略梯度定理中一个隐含假设:π_θ与π_θ_old足够接近,使得∇_θ log π_θ ≈ ∇_θ log π_θ_old。当r_t(θ)远离 1 时,该线性近似失效,梯度方向可能错误。PPO 的clip就是人为制造一个“信任区域”,确保更新在局部有效。从本书视角看,PPO 是对 REINFORCE 和 A2C 的工程加固:它保留了advantage的低方差优势(来自 Critic),又通过clip规避了策略更新过大的风险。所以,当你调试 PPO 时,如果发现clip激活率(ratio被裁剪的比例)持续 > 50%,说明ε太小或learning_rate太大,应优先调大ε(如从 0.1 到 0.2)或减小learning_rate,而不是盲目增加advantage的 scale。
从那以后我每次写策略梯度代码,都会强制走一遍这个流程:先手推一遍∇_θ J(θ)的原始表达式,确认G_t的时间下标是否匹配;再检查advantage计算中v_φ(s_t)是否用了当前 Critic 的输出(而非 target);最后用 `np.histogram(ratio, bins=
本文还有配套的精品资源,点击获取