马尔科夫决策过程:强化学习的第一块基石与实战避坑指南
1. 从“状态”说起为什么马尔科夫模型是强化学习的第一块基石如果你刚开始啃强化学习大概率会在前几页就撞上“马尔科夫决策过程”这个词。它看起来像一串数学符号的堆砌但说白了它就是一套用来描述“智能体在环境里怎么一步步做选择”的语言。没有这套语言后面所有的价值函数、策略梯度、Q-Learning都无从谈起。我最初接触这部分内容时最大的困惑不是公式本身而是“为什么非得是马尔科夫”。后来在实际项目中反复踩坑才明白马尔科夫性本质上是一个关于“记忆”的假设——它说当前状态已经包含了做出下一步决策所需的全部信息你不需要回头看更早的历史。这个假设一旦成立问题就被大大简化了一旦不成立你就得想办法把历史信息压缩进状态里否则算法会表现得像失忆一样。这篇笔记围绕David Silver强化学习课程第二讲的核心内容展开重点拆解马尔科夫过程、马尔科夫奖励过程和马尔科夫决策过程这三层递进结构。适合已经了解强化学习基本概念、但被数学定义卡住的读者也适合想重新梳理底层逻辑的从业者。我会尽量用生活化的例子把每个符号对应到实际含义上同时补充一些课程里没展开、但在动手实现时一定会遇到的细节。2. 马尔科夫过程没有奖励的“随机漫步”2.1 马尔科夫性的直观含义马尔科夫性用一句话概括就是未来只取决于现在与过去无关。用条件概率写出来是P(S_{t1} | S_t) P(S_{t1} | S_1, S_2, ..., S_t)右边那一长串条件里只有S_t是真正起作用的前面的S_1到S_{t-1}都是冗余信息。这就像你玩一个棋盘游戏当前棋盘的布局已经决定了所有合法的下一步走法至于这些棋子是怎么一步步走到这个局面的对下一步的选择没有任何影响。这里有个容易混淆的点马尔科夫性不是说“过去不重要”而是说“过去的信息已经被当前状态完全吸收了”。如果当前状态没有吸收足够的信息那它就不满足马尔科夫性。举个例子如果你只记录一个股票的价格而不记录它的成交量、市场情绪等那这个“状态”很可能不满足马尔科夫性因为价格的历史走势中隐含了趋势信息而当前价格本身没有包含这些。注意判断一个状态设计是否满足马尔科夫性标准是“给定当前状态未来和过去是否条件独立”。如果不独立要么扩充状态要么接受近似。2.2 状态转移矩阵的构建逻辑马尔科夫过程由两部分组成状态集合S和转移概率矩阵P。转移概率矩阵的每个元素P_{ss}表示从状态s转移到状态s的概率。这个矩阵有两个硬性约束每一行的元素非负且每一行的和为1。为什么行和必须为1因为从任何一个状态出发下一步必然转移到某个状态包括可能转移回自己所有可能去向的概率加起来必须是100%。这个约束在实现时经常被忽略导致采样时出现概率归一化错误。在实际建模中转移矩阵的规模可能非常大。比如一个简单的网格世界如果有100个格子矩阵就是100×100。如果状态是连续的呢那就没法用矩阵表示了需要用函数近似。但在基础阶段理解离散矩阵的构建方式是绕不开的。我个人的经验是先把状态空间设计清楚再考虑转移概率。很多初学者一上来就纠结概率数值怎么定结果状态定义得模棱两可后面全乱套。状态必须是互斥且完备的——每个可能的情况恰好对应一个状态不能有遗漏也不能有重叠。2.3 从一条采样轨迹理解马尔科夫链假设我们有一个三状态的马尔科夫链晴天、阴天、雨天。转移矩阵如下当前状态转移到晴天转移到阴天转移到雨天晴天0.60.30.1阴天0.30.40.3雨天0.20.30.5从晴天出发按照概率采样可能得到这样一条轨迹晴天→晴天→阴天→雨天→阴天→晴天……这条轨迹就是马尔科夫链的一个样本。注意每次转移只依赖当前状态和之前经过哪些状态无关。在代码实现时采样过程通常是这样给定当前状态对应的概率分布用累积分布函数加随机数的方式来决定下一个状态。这个操作在Python里可以用numpy.random.choice配合概率数组完成但要注意每次采样前确保概率数组已经归一化。3. 马尔科夫奖励过程给“漫步”加上分数3.1 奖励信号的引入与即时回报马尔科夫奖励过程在马尔科夫过程的基础上加了一个奖励函数R_s。每到达一个状态环境就给出一个即时奖励。这个奖励可以是正数、负数或零代表这个状态对智能体的“好坏”。这里要区分两个概念即时奖励和累积回报。即时奖励是到达某个状态那一刻拿到的分数而累积回报是从当前时刻开始把未来所有奖励按一定折扣累加起来的总和。强化学习的目标不是最大化某一步的即时奖励而是最大化长期累积回报。这个区别非常关键因为有些状态即时奖励很高但会导致后续陷入很差的状态有些状态即时奖励为负但它是通往高回报区域的必经之路。在实际项目中奖励函数的设计往往比算法选择更影响最终效果。我见过不少案例算法本身没问题但奖励给错了智能体学出来的行为完全不符合预期。比如在某个路径规划任务中如果每走一步都给一个小的负奖励智能体就会学会尽快结束任务如果终点奖励不够大它甚至可能选择原地不动来避免负奖励。3.2 折扣因子γ远见与短视的调节旋钮折扣因子γ的取值范围是0到1之间。它的作用是降低未来奖励的权重。γ越接近0智能体越短视只关心眼前的奖励γ越接近1智能体越有远见愿意为了未来的高回报牺牲当前利益。为什么需要折扣有两个层面的原因。从数学角度看如果γ等于1且过程是无限持续的累积回报可能发散到无穷大没法比较优劣。从实际角度看未来的不确定性更高今天的100块钱比一年后的100块钱更有价值折扣因子就是对这种不确定性的建模。γ的选择没有标准答案取决于具体任务。如果任务有明确的终止条件且步数有限γ可以设得接近1如果任务可能无限持续γ通常设在0.9到0.99之间。我个人的习惯是先用0.99跑一遍观察累积回报的量级再根据学习曲线的稳定性微调。3.3 回报的递归展开与贝尔曼方程的雏形累积回报G_t有一个非常重要的递归性质G_t R_{t1} γR_{t2} γ²R_{t3} ... R_{t1} γ(R_{t2} γR_{t3} ...) R_{t1} γG_{t1}这个递归关系是后面所有贝尔曼方程的基础。它把“从当前时刻开始的累积回报”拆解成“即时奖励”加上“折扣后的下一时刻累积回报”。这个拆解看起来简单但它意味着我们不需要把整条轨迹展开来计算回报只需要知道当前奖励和下一时刻的回报期望值就够了。在实现时这个递归关系直接对应时序差分学习中的更新公式。理解了这个递归后面看到TD误差、Q-Learning的更新规则时就不会觉得突兀。3.4 值函数评估每个状态有多“好”值函数v(s)定义为从状态s出发按照某个策略继续走下去期望能拿到的累积回报。注意这里说的是“期望”因为从同一个状态出发可能走出不同的轨迹每条轨迹的累积回报不同值函数是这些回报的期望值。对于马尔科夫奖励过程因为没有“动作”的概念所以值函数只依赖于状态和转移概率。它的贝尔曼方程是v(s) R_s γ Σ P_{ss} v(s)这个方程的含义是当前状态的价值等于即时奖励加上折扣后的下一状态价值的加权平均。权重就是转移概率。这个方程看起来简单但它是一个线性方程组。如果状态数量是N就有N个方程和N个未知数。理论上可以直接解线性方程组得到精确解但实际中状态数量往往很大直接求解的计算复杂度是O(N³)不可接受。所以实际中用的是迭代方法先给所有状态的值函数一个初始猜测然后反复用贝尔曼方程更新直到收敛。这个迭代过程就是迭代策略评估的基础。4. 马尔科夫决策过程动作的加入让一切“活”起来4.1 从“被动漫步”到“主动选择”马尔科夫决策过程在马尔科夫奖励过程的基础上引入了动作集合A。在马尔科夫奖励过程里智能体只能被动地等待状态转移在马尔科夫决策过程里智能体可以在每个状态主动选择一个动作动作会影响下一个状态的分布。这个变化看似不大但它是强化学习真正有意思的地方。因为有了动作就有了“策略”的概念——策略π(a|s)定义了在每个状态选择每个动作的概率。智能体的目标变成了寻找一个最优策略使得从任何状态出发的累积回报期望都最大。这里要特别注意在马尔科夫决策过程中转移概率变成了P_{ss}^a即“在状态s采取动作a后转移到状态s的概率”。奖励也变成了R_s^a即“在状态s采取动作a后获得的即时奖励”。这两个上标a是马尔科夫决策过程区别于马尔科夫奖励过程的核心标志。4.2 策略π智能体的行为准则策略是马尔科夫决策过程的核心概念。它可以是确定性的每个状态只选一个动作也可以是随机性的每个状态按概率选动作。随机策略在某些场景下是必要的比如在博弈中确定性策略容易被对手预测和针对。策略的优劣怎么比较如果策略π在所有状态下的值函数都不低于策略π就说π优于π。最优策略π*是至少存在一个策略优于或等于所有其他策略。这里有个重要结论对于任何马尔科夫决策过程至少存在一个确定性最优策略。这个结论保证了我们不需要在无限大的随机策略空间里搜索只需要找确定性策略就够了。但在实际实现中我们经常用随机策略来保证探索。比如ε-贪心策略以1-ε的概率选当前认为最优的动作以ε的概率随机选一个动作。这个策略不是最优策略但它能保证所有状态-动作对都被访问到从而让值函数估计收敛到真实值。4.3 状态值函数与动作值函数的区别和联系状态值函数v_π(s)表示在状态s下按照策略π行动能拿到的期望累积回报。动作值函数q_π(s,a)表示在状态s下先采取动作a然后再按照策略π行动能拿到的期望累积回报。两者的关系很直接v_π(s) Σ π(a|s) q_π(s,a)也就是说状态值函数是动作值函数在策略下的加权平均。反过来动作值函数也可以用状态值函数表示q_π(s,a) R_s^a γ Σ P_{ss}^a v_π(s)这个关系说明采取动作a之后拿到即时奖励然后转移到某个新状态之后的价值由新状态的状态值函数决定。为什么要同时定义两个值函数因为在实际算法中有些算法直接学状态值函数有些直接学动作值函数还有些两个都学。理解它们的区别和联系是看懂不同算法变体的前提。比如Q-Learning直接学动作值函数而策略梯度方法通常学状态值函数或者优势函数。4.4 贝尔曼期望方程与贝尔曼最优方程贝尔曼期望方程描述的是“给定策略π值函数满足什么关系”。对于状态值函数v_π(s) Σ π(a|s) [R_s^a γ Σ P_{ss}^a v_π(s)]对于动作值函数q_π(s,a) R_s^a γ Σ P_{ss}^a Σ π(a|s) q_π(s,a)这两个方程都是线性的可以用迭代方法求解。贝尔曼最优方程描述的是“最优策略下的值函数满足什么关系”。对于最优状态值函数v*(s) max_a [R_s^a γ Σ P_{ss}^a v*(s)]对于最优动作值函数q*(s,a) R_s^a γ Σ P_{ss}^a max_{a} q*(s,a)注意这里用max代替了期望。这个max操作是贝尔曼最优方程的核心也是它非线性的原因。因为max的存在贝尔曼最优方程不能像期望方程那样直接解线性方程组必须用迭代方法如值迭代来求解。提示贝尔曼期望方程对应“策略评估”贝尔曼最优方程对应“策略改进”。两者交替进行就是策略迭代的核心思想。4.5 最优策略的提取与动作值函数的优势一旦有了最优动作值函数q*(s,a)最优策略就可以直接提取出来在每个状态s选择让q*(s,a)最大的动作a。如果有多个动作同时达到最大值可以任选一个或者按均匀分布随机选。为什么用动作值函数提取策略比用状态值函数更方便因为如果只有v*(s)要选动作还需要知道转移概率和奖励函数通过一步搜索来确定哪个动作最好。而有了q*(s,a)直接比较大小就行不需要知道环境模型。这个区别在无模型强化学习中非常关键——我们通常没有环境模型所以直接学q*(s,a)更实用。这也是Q-Learning这类算法直接学动作值函数的原因。它不需要知道转移概率P_{ss}^a只需要通过采样来估计q值然后用max操作来更新。这种“无模型”的特性让Q-Learning在实际问题中非常受欢迎。5. 动手实现时绕不开的几个细节5.1 状态空间设计中的常见陷阱状态空间设计是马尔科夫决策过程落地时最容易出问题的地方。最常见的错误是状态信息不完整导致马尔科夫性被破坏。比如在一个库存管理问题中如果状态只包含当前库存量而不包含在途订单量那这个状态就不满足马尔科夫性因为未来的库存变化依赖于在途订单而当前状态没有包含这个信息。另一个陷阱是状态空间过大。如果状态是连续变量直接离散化可能导致状态数量爆炸。比如两个连续变量各离散成100份组合起来就是10000个状态再加上动作维度表格方法就完全不可行了。这时候需要考虑函数近似比如用神经网络来拟合值函数。我的经验是先用最简状态定义跑通流程再逐步增加状态维度。一开始就把所有可能相关的信息塞进状态里不仅会让状态空间爆炸还会引入噪声让学习变得更慢。正确的做法是先验证最简状态是否能满足马尔科夫性如果学习效果不好再分析缺失了哪些关键信息。5.2 奖励函数的尺度与稀疏性问题奖励函数的尺度会直接影响学习速度和稳定性。如果奖励值太大值函数估计的方差会很大学习曲线震荡剧烈如果奖励值太小梯度信号太弱学习进展缓慢。通常建议把奖励归一化到[-1, 1]或者[0, 1]区间内。稀疏奖励是另一个常见难题。如果只有到达目标状态才有奖励其他状态奖励都是零智能体在早期很难获得有效信号学习效率极低。解决思路包括设计中间奖励奖励塑形、使用内在激励如好奇心驱动、或者采用分层强化学习。但奖励塑形要小心如果塑形不当可能引导智能体学会“刷奖励”而不是真正完成任务。我踩过的一个坑是在一个导航任务中为了鼓励智能体靠近目标每靠近一步就给一个小奖励。结果智能体学会了在目标附近来回移动来反复获取奖励而不是真正到达目标。后来改成只在到达目标时给奖励同时用课程学习逐步增加难度才解决了这个问题。5.3 折扣因子与回合终止的配合折扣因子γ和回合终止条件需要配合设计。如果任务有明确的终止状态γ可以设得接近1因为累积回报不会无限增长。但如果任务没有终止条件γ必须小于1否则值函数可能发散。在实现时终止状态的值函数通常设为0。这意味着到达终止状态后不再有后续奖励。这个设定会影响贝尔曼更新对于终止状态v(s) 0不需要加上折扣后的下一状态价值。还有一个细节如果环境在终止时给出一个终止奖励这个奖励应该算在终止状态的前一个状态的即时奖励里而不是终止状态本身。因为智能体到达终止状态后就不再采取动作了终止状态没有“即时奖励”的概念。5.4 从表格方法到函数近似的过渡时机表格方法在状态空间较小的时候很好用每个状态-动作对的值单独存储和更新收敛性有理论保证。但当状态数量超过几万甚至几十万时表格方法就不可行了因为内存和计算时间都受不了。过渡到函数近似的时机没有硬性标准但有几个信号可以参考状态数量超过10万、状态是连续的、或者状态之间有明显的相似性可以利用。函数近似的核心思想是用一个参数化函数来拟合值函数输入是状态和动作输出是值。这样就不需要为每个状态单独存储值而是共享参数。但函数近似也带来了新的挑战收敛性不再有保证学习率的选择更敏感还可能出现过估计或欠估计。从表格方法过渡到函数近似时建议先用线性函数近似如 tile coding验证思路再上神经网络。直接上深度网络容易陷入调试困境因为问题可能出在状态设计、奖励设计、网络结构、超参数等多个环节很难定位。6. 马尔科夫模型在真实问题中的边界与扩展6.1 部分可观测问题当状态不再完整现实世界中很多问题并不满足完全可观测的马尔科夫性。智能体只能看到观测值而观测值可能不包含状态的全部信息。这类问题叫部分可观测马尔科夫决策过程。处理部分可观测问题有两种常见思路。一种是维护一个信念状态即对当前可能状态的概率分布。信念状态满足马尔科夫性因为它是基于所有历史观测和动作计算出来的。但信念状态的维度可能很高计算复杂。另一种是使用循环神经网络来压缩历史信息把RNN的隐状态当作近似信念状态。Deep Q-Network的变体DQN-RNN就是这种思路。在实际项目中判断问题是否部分可观测可以看智能体在相同观测下是否需要不同的动作。如果需要说明观测不包含足够信息要么扩充观测要么引入记忆机制。6.2 连续状态与连续动作的挑战当状态和动作都是连续的时候表格方法和离散化都不再适用。连续状态可以用函数近似处理但连续动作带来了新的困难在贝尔曼最优方程中max操作需要在连续动作空间上求最大值这通常无法解析求解。解决连续动作问题的方法包括策略梯度方法直接参数化策略并优化期望回报不需要在动作空间上求max演员-评论家方法结合策略梯度和值函数估计或者将动作空间离散化但维度高时不可行。选择哪种方法取决于具体问题的动作维度、平滑性和实时性要求。6.3 马尔科夫假设不成立时的补救措施如果状态设计无法满足马尔科夫性有几种补救措施。最直接的是扩充状态把缺失的历史信息加进去。比如用过去几帧的观测堆叠起来作为状态这在Atari游戏中被证明非常有效。另一种是使用特征工程提取历史中的关键统计量如均值、方差、趋势加入状态。还有一种思路是放松马尔科夫假设使用半马尔科夫决策过程允许状态持续时间可变。这在一些分层任务中很有用比如选项框架。但半马尔科夫模型的数学推导更复杂实际中使用较少。我个人的体会是不要试图追求完美的马尔科夫性而是追求“足够好”的马尔科夫性。实际项目中状态设计永远是对现实的近似关键是这个近似是否足以让算法学到有用的策略。如果学习效果不理想再回头分析状态设计而不是一开始就追求理论上的完美。6.4 从马尔科夫决策过程到现代深度强化学习现代深度强化学习的几乎所有算法底层都是马尔科夫决策过程。DQN用神经网络拟合动作值函数但更新目标仍然来自贝尔曼最优方程。A3C、PPO等策略梯度方法优化的目标仍然是累积回报的期望而累积回报的定义完全基于马尔科夫决策过程。理解马尔科夫决策过程的价值在于当算法表现不如预期时你可以回到这个框架来排查问题。是状态设计不满足马尔科夫性是奖励函数设计有误是折扣因子设置不当还是策略表示能力不足这些问题都可以在马尔科夫决策过程的框架下找到对应的分析角度。我见过不少从业者一上来就调神经网络的层数和学习率却忽略了状态和奖励这些更基础的设计。结果调了半天问题依然存在。后来回头重新设计状态和奖励效果立刻改善。这个经历让我意识到马尔科夫决策过程不是考试里的数学题而是排查问题的思维框架。把它吃透了后面学任何算法都会觉得有根可循。