
1. 为什么从MDP开始学深度强化学习很多朋友一上来就啃PPO、DQN这些具体的深度强化学习算法结果看不了几行就被各种符号和公式劝退。我自己刚入门那会儿也踩过这个坑先看了几篇“手写DQN玩CartPole”的教程代码能跑训练曲线也能看到奖励上升但稍微改一下环境、调一下奖励策略就完全乱套。后来才意识到问题不在于网络结构或超参数而在于我对强化学习的基本问题框架根本没吃透。深度强化学习本质上是用深度神经网络去逼近强化学习里的策略、价值函数或环境模型。所以门槛不在“深度”而在“强化学习”这一层的抽象框架。而强化学习最底层的数学模型就是马尔科夫决策过程Markov Decision ProcessMDP。贝尔曼方程Bellman Equation是求解MDP的理论核心价值迭代Value Iteration和策略迭代Policy Iteration则是两种最基础的精确求解算法。把这四块东西串起来你就掌握了读任何深度强化学习论文所需要的共同语言。这篇笔记适合刚接触强化学习、被各路公式劝退过的初学者也适合已经能跑通某个算法、但回头补理论基础的人。我要强调一句这些东西不是纯理论、不接地气。DQN的更新公式就是贝尔曼方程的近似版本AlphaGo里的蒙特卡洛树搜索本质上也在做价值迭代和策略改进的交替。把MDP和两类迭代算法搞清楚后面理解深度强化学习算法会轻松非常多。2. MDP强化学习用什么语言描述问题2.1 五元组状态、动作、转移、奖励、折扣MDP的经典定义是一个五元组 (S, A, P, R, γ)。逐个拆开看S状态集合描述智能体所能观察到的所有可能情形。可以是离散的比如网格世界的每个格子也可以是连续的比如机器人的关节角度和速度。A动作集合描述智能体在每个状态下可以采取的行为。同样可以是离散或连续。P状态转移概率P(s|s,a) 表示在状态 s 执行动作 a 之后转移到状态 s 的概率。这是环境动态特性的数学描述。R奖励函数R(s,a,s) 或更常见地简写为 R(s,a)表示执行某个动作后环境给出的即时反馈。γ折扣因子取值在 [0,1] 之间用于衡量未来奖励相对于当前奖励的重要程度。我在刚接触MDP时最困惑的一点是为什么需要一个严格的数学框架后来用游戏来类比就想通了。把MDP想象成你和游戏环境签的一份“交互合同”你给出一个动作环境根据它的规则转移概率改变游戏画面状态并给你一个分数奖励然后循环往复。任何满足这种“状态-动作-奖励-新状态”循环的问题理论上都能用MDP建模。无论是机器人控制、棋类对弈、推荐系统还是自动驾驶决策本质上都在这个框架内。2.2 马尔科夫性质为什么可以只看当前状态MDP的核心假设是马尔科夫性质下一时刻的状态只依赖当前状态和当前动作与更早的历史无关。用公式表达就是P(s_{t1} | s_t, a_t, s_{t-1}, a_{t-1}, ..., s_0, a_0) P(s_{t1} | s_t, a_t)这句话看起来很简单但它极大简化了问题。如果没有这个假设智能体为了做决策就得记住从开局到现在的完整历史状态空间会随着时间爆炸式增长任何算法都无从下手。但我必须提醒一句现实世界中的很多问题并不严格满足马尔科夫性质。最典型的例子是自动驾驶只看单帧摄像头画面你无法判断前方车辆是在减速还是准备变道因为这类信息隐含在连续多帧之中。解决办法通常是做状态增广——把最近几帧画面拼接起来作为当前状态或者用循环神经网络让网络内部自己维护“记忆”。这类技巧都是为了在工程上逼近马尔科夫性质而非完全消除这一假设。2.3 回报与折扣因子为什么未来的钱要打折在MDP里智能体的目标不是最大化当前这一瞬间的奖励而是最大化长期累积奖励也就是回报Return。定义如下G_t R_{t1} γ R_{t2} γ² R_{t3} ... Σ_{k0}^{∞} γ^k R_{tk1}为什么需要折扣因子γ有三个原因。第一从数学上保证无限时域问题的回报收敛为有限值。如果γ1且奖励恒为1回报就是无穷大策略没法比较优劣。第二反映现实偏好绝大多数场景下越早获得的回报越有价值就像我们贷款买房时今天的钱比二十年后的钱更值钱。第三处理环境动态中的不确定性远期事件的预测难度更高给它们打个折扣相当于对不确定性的一种惩罚。γ的取值会直接影响智能体的行为偏好。γ接近0时智能体变得极度短视只顾眼前利益γ接近1时智能体愿意为了长期收益牺牲短期回报。经典的迷宫问题就能看出差异走出迷宫到达终点给奖励γ0.9的智能体会优先走较短的路径因为绕路带来的远期收益会被折扣稀释而γ0.99时智能体对路径长度的敏感度会下降更看重终点本身。2.4 策略智能体的决策规则策略Policy定义了智能体在每个状态下选择动作的规则。它有两种形式确定性策略和随机性策略。确定性策略π(s) a每个状态对应唯一确定的动作。随机性策略π(a|s) P(A_ta | S_ts)在状态s下按一定概率分布选择动作。初学者会觉得随机性策略绕弯子既然已知哪个动作好为什么不直接选最好的原因在于探索与利用的平衡。在训练初期你对环境动态的估计是不准的可能需要故意尝试一些看起来次优的动作来收集信息。随机性策略天然支持这种探索行为。此外在博弈类场景中随机策略还能防止对手预测你的行为。深度强化学习领域策略梯度类算法如PPO、A2C通常直接建模随机策略网络输出的是动作的概率分布而DQN这类基于价值的方法最终导出的策略是确定性的——选择当前状态下Q值最大的动作。3. 贝尔曼方程递归拆解价值函数3.1 状态价值函数 V(s) 到底在算什么我们想知道“处于某个状态有多好”最简单的想法是从当前状态开始一路走到天荒地老把所有奖励打折扣加总。但问题是未来的动作选择还取决于策略所以V(s)的定义必须绑定一个给定策略πV_π(s) E_π[G_t | S_t s]这个期望符号里的下标π表示所有未来动作都按策略π采样。V_π(s)衡量的是“在策略π下从状态s出发的期望回报”。注意一个细节V值可以有非常大的跨度。假设每步奖励在[-1, 1]之间γ0.99那么V的范围大概在±100左右。如果你做神经网络逼近价值函数一定要注意输出层的尺度问题否则容易训练震荡。3.2 动作价值函数 Q(s,a)做决策真正用到的东西从应用角度更常用的是动作价值函数Action Value Function也叫Q函数Q_π(s,a) E_π[G_t | S_t s, A_t a]它表示在状态s下先执行动作a之后都按策略π行动所获得的期望回报。V和Q之间只差一步V是对Q按策略求平均Q比V多携带了“具体动作”的信息。正因为如此决策时直接比较Q值就行哪个动作的Q大就选哪个动作。这两个价值函数之间的数学关系如下V_π(s) Σ_a π(a|s) Q_π(s,a)如果策略是确定性的V就等于选择那个特定动作后的Q值。这个关系式在后面推导贝尔曼方程时经常用到。3.3 贝尔曼期望方程的推导与直觉贝尔曼方程的核心思想是拆解回报。把G_t写成即时奖励加上后续回报G_t R_{t1} γ G_{t1}两边同时取期望就得到V_π的贝尔曼期望方程V_π(s) Σ_a π(a|s) Σ_{s} P(s|s,a) [R(s,a,s) γ V_π(s)]Q函数的版本更直接Q_π(s,a) Σ_{s} P(s|s,a) [R(s,a,s) γ Σ_{a} π(a|s) Q_π(s,a)]用大白话解释当前状态的价值等于“立即奖励 捏着鼻子把未来价值打折后拿回来”。或者说这就像你评估一门生意时今天的利润加上未来所有预期利润的折现值就是这门生意的总价值。贝尔曼方程把无限步的回报变成了一个递推关系这才是它革命性的地方。没有这个递归你每评估一次策略都要模拟到环境终止这在理论上不可行。我提一个具体的例子帮助理解。假设一个2×2网格状态s0可以执行“左”或“右”。执行“左”的即时奖励为1并以0.8的概率进入状态s1以0.2的概率留在s0执行“右”的即时奖励为0并以1.0的概率进入s2。假设γ0.9且s1的价值为5s2的价值为10。那么Q(s0, 左) 0.8 × (1 0.9 × 5) 0.2 × (1 0.9 × V_π(s0))Q(s0, 右) 1.0 × (0 0.9 × 10) 9如果策略π在s0选“左”和“右”的概率各为0.5那么最终V_π(s0) 0.5 × Q(s0,左) 0.5 × Q(s0,右)。这组计算虽然简单但能清晰看到价值如何通过递归关系互相影响。3.4 最优价值函数与贝尔曼最优方程我们最终要的不是评估某个策略而是找到最优策略。定义最优状态价值函数为所有策略中能得到的最大期望回报V_*(s) max_π V_π(s)类似地定义最优动作价值函数Q_*(s,a) max_π Q_π(s,a)贝尔曼最优方程将价值函数递归地写成最优形式V_(s) max_a Σ_{s} P(s|s,a) [R(s,a,s) γ V_(s)]Q_(s,a) Σ_{s} P(s|s,a) [R(s,a,s) γ max_{a} Q_(s,a)]注意这里的关键变化期望方程对策略π求平均最优方程直接取max。这个max操作不仅体现了“从当前状态出发选择能带来最大价值的动作”这一贪心思想更妙的是如果已知Q_*最优策略就直接是π_(s) argmax_a Q_(s,a)不需要再做任何搜索或规划。这就是为什么很多深度强化学习算法如DQN、Double DQN、Dueling DQN都把重心放在近似Q_*上。4. 价值迭代与策略迭代两种求解思路4.1 策略评估给定策略算价值在讲解两类迭代算法之前先要铺垫一个基础操作策略评估Policy Evaluation。给定一个策略π我们通过不断套用贝尔曼期望方程来更新价值函数V_{k1}(s) Σ_a π(a|s) Σ_{s} P(s|s,a) [R(s,a,s) γ V_k(s)]这一步其实就是在解一个联立线性方程组。理论上有闭式解但状态空间一大会导致矩阵求逆的计算量和存储量爆炸所以工程上普遍用迭代法。每轮迭代所有状态的价值都会向贝尔曼方程对应的解靠近一步。收敛之后V_π就求出来了。从数值计算的角度看这一步就是经典的不动点迭代。只要策略π保持不变V更新一圈后如果变化很小说明已经接近V_π。实际操作中不需要完全收敛可以设一个阈值比如两次迭代间的最大差值小于1e-4就算过关。这样做能显著减少计算量。4.2 策略改进贪心提升策略有了当前策略的价值函数下一步是改进策略。用贪心思想在每个状态选择能使Q值最大的动作π(s) argmax_a Q_π(s,a)这个改进理论上保证π不差于π即V_{π}(s) ≥ V_π(s)对所有状态成立。这就是策略改进定理是强化学习理论大厦的关键支撑之一。你不需要完整的Q函数表只需利用V_π和已知的转移概率P、奖励R就能算出每个动作的Q值Q_π(s,a) Σ_{s} P(s|s,a) [R(s,a,s) γ V_π(s)]所以策略改进步骤是依赖环境模型的。这正是经典表格型算法和现代无模型深度强化学习的一个重要分水岭后者没有P和R只能通过采样来估计Q值。4.3 策略迭代交替执行评估和改进策略迭代Policy Iteration的思路非常直观先评估当前策略的价值再按贪心方式改进策略重复这两步直到策略不再变化。算法流程初始化 V(s) 和 π(s)可以全零或全随机。策略评估固定π迭代更新V直到收敛。策略改进对每个状态s令 π(s) argmax_a Σ_{s} P(s|s,a) [R(s,a,s) γ V(s)]。如果π发生了变化回到第2步否则输出π和V。策略迭代的收敛速度通常很快尤其对于小规模状态空间的问题往往只需要几次迭代就能达到最优策略。它的每一步单次开销比价值迭代大因为要完成一轮完整的策略评估但整体迭代次数少很多。打个比方策略迭代像登山时先看好全山地图确定方向后大步走价值迭代则每迈一步都重新确认方向步子小但路径更短。4.4 价值迭代把评估和改进融合成一步价值迭代Value Iteration在贝尔曼最优方程的基础上直接更新V_{k1}(s) max_a Σ_{s} P(s|s,a) [R(s,a,s) γ V_k(s)]初看和前面对V_π的评估更新很像但有两个关键差异。第一更新目标不是对策略π的动作取平均而是对动作取max。第二它没有单独的“策略”变量策略只是从最终收敛的价值函数中显式推导出来的副产品。因此价值迭代等于把策略评估和策略改进压缩到了一个式子中。价值迭代的收敛逻辑和策略迭代不同。策略评估要求内层充分收敛价值迭代则每步都只做一次扫描通过反复迭代让V逐渐逼近V_*。最后从V_*中提取策略提取方式和策略改进步骤完全一致选argmax动作。我在做实验时发现价值迭代对γ很敏感。γ越大收敛所需的迭代次数越多因为信息在状态间传递得越慢。即使只有几百个状态γ0.99时也可能需要上千次迭代才能收敛到较高精度而γ0.9时往往几十次就够了。这与贝尔曼算子的收缩率有关。4.5 两类迭代的选型与适用场景对比做了多次实验之后我总结出两者的适用规律放在一张表格里比较清楚对比维度策略迭代价值迭代核心操作评估与改进交替执行直接在最优方程上更新计算开销每轮需要完整策略评估单轮开销大每轮只更新一次价值单轮开销小收敛轮数通常很少几轮到几十轮轮数较多随γ增大明显增加适用规模小规模、状态空间清晰的问题中等规模、对实现简洁度要求高的场景工程实现需要显式维护策略表不需要单独维护策略实现更简单与深度学习的关联类似Actor-Critic中评估与改进交替的思想类似DQN中直接用Q值更新并贪心选动作一个常用的经验准则是如果状态空间在百万以内且转移概率和奖励函数精确已知优先用策略迭代因为轮数少调参成本低。如果状态空间较大、每轮计算代价高或者你只想快速验证一个环境的动态就用价值迭代。深度强化学习的大规模环境下精确求解已不可行实际做法是用神经网络近似但思想仍然离不开这两者。4.6 一个动手实验网格世界中的两种算法对比为了让抽象公式落地我用Python写了一个5×5网格世界的对比实验。环境规则如下智能体从左上角(0,0)出发目标是到达右下角(4,4)的终点。动作空间为上下左右四个方向。每个常规格子移动一步获得奖励-1进入终点获得奖励10进入终点后游戏结束。转移到墙壁时位置不变但仍获得-1奖励。折扣因子γ0.9初始价值均为0。策略迭代的核心循环如下import numpy as np GRID_SIZE 5 ACTIONS [(-1, 0), (1, 0), (0, -1), (0, 1)] GAMMA 0.9 THETA 1e-4 def step(state, action): r, c state dr, dc ACTIONS[action] nr, nc r dr, c dc if nr 0 or nr GRID_SIZE or nc 0 or nc GRID_SIZE: return state, -1 if (nr, nc) (GRID_SIZE - 1, GRID_SIZE - 1): return (nr, nc), 10 return (nr, nc), -1 V np.zeros((GRID_SIZE, GRID_SIZE)) policy np.zeros((GRID_SIZE, GRID_SIZE), dtypeint) while True: # 策略评估 while True: delta 0 for r in range(GRID_SIZE): for c in range(GRID_SIZE): s (r, c) if s (GRID_SIZE - 1, GRID_SIZE - 1): continue v V[r, c] a policy[r, c] s_next, reward step(s, a) nr, nc s_next V[r, c] reward GAMMA * V[nr, nc] delta max(delta, abs(v - V[r, c])) if delta THETA: break # 策略改进 policy_stable True for r in range(GRID_SIZE): for c in range(GRID_SIZE): s (r, c) if s (GRID_SIZE - 1, GRID_SIZE - 1): continue old_action policy[r, c] q_values [] for a in range(len(ACTIONS)): s_next, reward step(s, a) nr, nc s_next q_values.append(reward GAMMA * V[nr, nc]) best_a int(np.argmax(q_values)) policy[r, c] best_a if old_action ! best_a: policy_stable False if policy_stable: break价值迭代的代码更短V np.zeros((GRID_SIZE, GRID_SIZE)) while True: delta 0 for r in range(GRID_SIZE): for c in range(GRID_SIZE): s (r, c) if s (GRID_SIZE - 1, GRID_SIZE - 1): continue v V[r, c] q_values [] for a in range(len(ACTIONS)): s_next, reward step(s, a) nr, nc s_next q_values.append(reward GAMMA * V[nr, nc]) V[r, c] max(q_values) delta max(delta, abs(v - V[r, c])) if delta THETA: break运行后可以发现策略迭代因为每次改进是全局性的通常只需要3到5轮外循环就能稳定价值迭代则需要几百轮迭代才能让角落状态的值充分传导出来。但从代码行数看价值迭代明显简洁。这个微观对比基本映照了二者在真实项目中的取舍策略迭代更“聪明”但单步代价大价值迭代更“笨”但实现极其简单。如果你用更大的网格比如20×20再跑一遍会更加明显。5. 从表格到深度网络为什么还需要深度学习5.1 精确求解的致命局限维度灾难与模型依赖价值迭代和策略迭代虽然理论漂亮但在真实深度强化学习任务中直接失效。原因有两个。第一维度灾难。假设一个Atari游戏画面是210×160×3的像素矩阵每个像素256个取值那状态空间大小就是天文数字。你不可能为每个状态单独存一个V值或查表选择策略。工程上必须用函数逼近器来泛化——这正是深度神经网络登场的理由。第二这两类迭代算法都假设环境动态P和奖励R已知而绝大多数实际环境没有精确模型。机器人关节的物理动态很难精确建模股市交易环境更是根本无法建模。深度强化学习恰恰是为了解决“模型不可知”的情况而设计不依赖P和R只靠与环境交互的样本来学习。5.2 DQN本质上是价值迭代的近似DQNDeep Q-Network从方法论上可以看作价值迭代的可扩展版本。价值迭代的更新公式V_{k1}(s) max_a [R γ V_k(s)] 或 Q_{k1}(s,a) R γ max_{a} Q_k(s,a)DQN在做的事情就是用神经网络Q_θ(s,a)逼近Q_*用当前网络的输出去构造目标值y r γ max_{a} Q_θ(s, a)然后通过监督学习更新θ让Q_θ(s,a)越来越接近y。这里的Q_θ就是目标网络用于缓解自举带来的训练不稳定。和经典价值迭代的主要差异在于状态空间太大无法枚举全部状态只能用小批量经验样本更新。没有已知的P因此无法对s求期望只能用采样替代。没有直接计算max因为动作空间可能连续所以用另一个网络Actor来近似argmax。所以我会跟朋友说理解了价值迭代就理解了DQN的骨架剩下的细节全是在处理“深度”带来的工程挑战。5.3 Actor-Critic架构里的策略迭代影子策略迭代的评估-改进两阶段结构在Actor-Critic演员-评论家类算法中以现代形式延续了下来。策略评估对应Critic网络的学习目标是准确估计当前策略π的价值函数V_π或Q_π策略改进对应Actor网络的更新目标是朝着价值函数更高的方向调整策略参数。两者交替进行正是策略迭代思想在参数化策略空间中的推广。这里我提醒一点Actor-Critic和经典策略迭代有一个显著区别。经典策略改进是贪心的直接把策略指向当前最优动作Actor则只能小步调整因为策略是参数化函数你无法保证一步就跳到全局最优。所以Actor-Critic类算法的训练更依赖学习率、熵正则等技巧比经典算法要脆弱得多。理解了这一点你就能理解为什么深度强化学习里策略网络和价值网络之间要反复交替训练而不是一步到位。6. 学习路径与常见坑位预警6.1 给初学者的学习路线建议我把自己走过的弯路整理成一条比较靠谱的学习顺序先理解MDP五元组能够把任意实际问题比如倒立摆、迷宫寻路、棋类对弈翻译成MDP语言。吃透V、Q两个价值函数的定义动手算一个3到4个状态的小MDP的V_π和Q_π。手写策略迭代和价值迭代在网格世界或随机游走环境上跑通并画出不同γ下的收敛曲线。理解策略梯度定理明白为什么要直接参数化策略。再看DQN、PPO等具体算法。这时候你会发现很多符号已经眼熟读论文的效率成倍提升。这个顺序最忌讳的是倒过来。如果先上来就调PPO你对价值网络的loss都理解不到位一旦训不出结果排查问题会非常痛苦。6.2 新手最容易踩的五个坑我在带人入门时高频遇到的问题有以下五个提前列出来帮你避开。坑一混淆V和Q的更新目标。价值迭代更新的是max后的V策略评估更新的是按策略π平均后的V。两者公式表面上只差一个max或求和但语义完全不同写代码时更容易错。坑二忽略折扣因子对收敛速度的影响。用γ0.99跑价值迭代收敛阈值设1e-4时所需迭代次数比γ0.9大了将近一个数量级。看到收敛慢先检查γ而不是盲改阈值。坑三在随机性环境中用确定性转移假设。很多教程为了简单把P(s|s,a)当成0/1处理导致代码在随机环境中完全失效。写step函数时一定要明确返回的next state是从概率分布中采样而不是固定映射。坑四终止状态处理不当。终止状态的价值应被固定为0不参与更新。如果忘记跳过终止状态价值会在终点附近反复自举数值很快就爆掉。坑五把表格型算法的思想直接套到神经网络上。深度强化学习里target network、经验回放、gradient clip这些机制不是锦上添花而是保证稳定性的必需品。做对比实验时不要轻易去掉这些组件。6.3 后记这些基础概念为什么值得反复咀嚼我后来回到这些基础概念时发现一个现象每读一篇新论文回头再看贝尔曼方程都会有不同的理解。最初它只是一条递推公式后来它变成了分析偏差-方差权衡的工具再后来我理解了它在近似动态规划中的算子视角。深度强化学习看起来日新月异但绝大部分工作都是在这套经典框架上做局部改动。把MDP、贝尔曼方程、两类迭代算法当作常读常新的地基远比追逐每次一出的新算法更划算。最后说一个我实测下來很有效的做法每接触一个新环境或新问题先用价值迭代在简化版小状态空间上跑出“标准答案”再用深度强化学习算法去逼近。这样你永远知道神经网络离精确解还差多远也更容易定位是算法问题还是实现问题。这套方法我一直用到现在几乎成了判断模型性能的试金石。