资讯详情

时序差分TD详解:从蒙特卡洛到TD(λ)的强化学习实战指南

📅 2026/10/17 8:36:20 | 华诺云谱 👁 阅读
时序差分TD详解:从蒙特卡洛到TD(λ)的强化学习实战指南
时序差分Temporal Difference TD这个名字第一次听到的时候我总觉得它是个很高冷的东西。直到我自己动手写了第一个导航Demo遇到一个特别实际的困境智能体在迷宫里每走一步到底该信谁是信走到终点后的“事后总结”还是信眼前这一步的“即时反馈”把这个问题想明白之后我再回头看TD方法发现它根本没有想象中那么难它解决的就是“一个还在路上的选手如何利用已经走过的路况不断调整方向”的问题。这篇文章我会把自己从理解TD到真正在项目里用上TD的全过程写下来包括那个让我卡了很久的直觉断层还有我在实测中总结的几条调参经验。无论你是正在啃教材的学生还是想把强化学习落地到某个小项目的开发者这篇应该都能帮你省下不少弯路。1. 为什么TD能“边走路边学走路”——从等一局结束说起1.1 蒙特卡洛方法留给我的“延迟满足”之痛强化学习里有一类最朴素的方法叫蒙特卡洛Monte Carlo MC。我刚接触它的时候觉得逻辑很对一个完整的回合走完看到最终拿了多少奖励再回过头来更新过程中每个状态的价值。就像你期末考试结束拿到总成绩才知道自己哪些章节学得不好。但我在自己写的那个模拟导航环境里很快就受不了这个方法的“延迟”。我的环境是一条很长的走廊智能体从起点出发要走几百步才能到达终点。如果每一步都用MC的方式更新意味着智能体每走完一整条走廊才能学习一次。走错一步路要等到几百步之后才知道“原来刚才那个岔路口选错了”。更要命的是如果任务根本不是“有终点”的回合制任务呢举个例子一个持续运行的股票交易Agent它没有“走完一局”的概念每一秒都在产生新的状态和奖励。你不可能让它先把一整天走完再回头更新上午9点30分的那个状态。MC在这里彻底失效因为根本没有回合边界。这就是TD方法真正解决的第一个问题它不需要等到回合结束走一步就更新一步。1.2 迷宫老鼠实验与“一个回合内的自我修正”理解TD最经典的入门案例是迷宫中的老鼠我这里是自己在代码里模拟了一遍。老鼠在迷宫里找奶酪奶酪的位置是固定的。MC的做法是等老鼠真的找到奶酪之后把整个路径上每个格子都标记成“高价值”。TD的做法就完全不一样了——它让老鼠每走一步就把当前格子的价值向“下一步格子的价值加上这一步的奖励”修正一下。这一步修正意味着什么我想了很久才反应过来它相当于在回合内部建立了一条价值传递链。假设某一次老鼠走了一条歪路绕了好多圈才找到奶酪那么MC会把这些绕路的格子也标记成“高价值”因为它们确实出现在了通向奶酪的路径上。但TD不会——它让信息从奶酪的位置沿着走过的路径一步一个脚印往回传。那些绕路但最终没直接靠近奶酪的格子它们的价值会被后续的探索慢慢拉低。同一个回合TD一边走一边改这个差异在实际训练中非常明显。我当时自己写了一个30格的地图把同一个环境分别用MC和TD跑结果让我很意外MC在100个回合之后路径才基本稳定而TD大概40回合就已经能找到一条比较合理的路了。原因并不复杂——MC的每一次更新都依赖完整的轨迹信号稀疏而TD在每一步都在用“当前结果修正当前判断”信号密度高得多。1.3 先抛一个直觉版更新公式先不管教科书里的严谨符号我当初是这样理解TD更新的当前状态的估值 当前状态的估值 学习率 × (即时奖励 下一步状态的估值 - 当前状态的估值)这个式子里最关键的部分是括号里那三项。如果你先不看“下一步状态的估值”这几乎就是普通强化学习的更新方式一旦加上“下一步状态的估值”它就像是让智能体用“未来的一点猜测”来帮助现在的判断。我当时打了个比方理解这件事你要估算从家到公司通勤要多久。你每过一个路口心里就会修正一次“刚开过这段路用了5分钟前面那段路估计还要10分钟所以全程大概是35分钟。”这个估算不需要开完全程才得出它是边走边算的。TD做的事和这个极其相似。2. 用数字看TD一次手动算完的通勤时间例子2.1 更新公式里的三个关键角色当前状态、下一步状态、奖励TD更新完全离不开三个量当前状态St、下一步状态S{t1}、以及从St走到S{t1}时获得的即时奖励R{t1}。我用代码里的变量名来标示它们的关系V(S_t) \leftarrow V(S_t) \alpha \left[ R_{t1} \gamma V(S_{t1}) - V(S_t) \right]其中α是学习率表示这次修正的幅度有多大。γ是折扣因子表示未来价值的“打折程度”通常在0.9到0.99之间。中括号里的部分叫做TD误差TD error。很多教材把R{t1} γV(S{t1})称为“TD目标”。为什么叫“目标”因为它是当前状态价值的一个“更新版答案”。它里面含了“真实的即时奖励”和“当前对未来的估计”两者混合在一起就是TD与MC最大的区别。2.2 手动走一遍从走廊模型看数值怎么变化我不喜欢空讲公式直接用一个手算的例子。假设一个四格的走廊环境起点S1 - S2 - S3 - 终点S4(奖励1)所有状态初始价值都是0。γ取0.9α取0.1。第一步智能体从S1行动到S2即时奖励为0。更新S1TD目标 0 0.9 × V(S2) 0 0.9 × 0 0 TD误差 0 - 0 0 V(S1) 0 0.1 × 0 0看起来什么都没发生因为未来也没有信息。再来一步从S2到S3V(S3)还是0依然没有信息。然后从S3走到终点S4此时即时奖励是1TD目标 1 0.9 × V(S4)注意S4是终点进入之后回合结束价值V(S4)本身可以定义为0或者你把它看作没有后续奖励的状态所以TD目标 1 0.9 × 0 1 TD误差 1 - V(S3) 1 - 0 1 V(S3) 0 0.1 × 1 0.1这一步S3的价值从0变成了0.1。下次再跑到S2到S3这时V(S3)已经不是0了。假设第二次到达S2准备向S3走TD目标 0 0.9 × V(S3) 0 0.9 × 0.1 0.09 TD误差 0.09 - V(S2) 0.09 - 0 0.09 V(S2) 0 0.1 × 0.09 0.009你可以看到价值就是这样一点一点从终点往回“渗”的。经过很多轮之后V(S1)、V(S2)、V(S3)都会收敛到接近某个合理值。这个“从后往前逐步渗透”的过程就是TD算法最核心的动力学机制。2.3 为什么TD目标比“纯粹的真实回报”更有工程意义我之前一直有个疑问既然最后能得到真实的长期回报为什么不直接用真实回报来更新原因有两个。第一个原因是方差。真实回报是整条轨迹上所有随机性的累积。环境稍微有点随机性最后的总回报可能天差地别。我做一个带随机风的格子世界时同一段路径每次总奖励会相差很多直接用总回报更新V值的曲线会抖得像心电图。而TD目标只用一步的即时奖励加下一步的估值随机因素积累得少曲线平稳很多。第二个原因是实时性。这一点前面已经强调过——非回合制任务没有“最终回报”可用。用TD你可以在任意时刻做更新这在许多真实系统里是刚需。我用一个对比表说明两者的差异对比维度MC蒙特卡洛TD时序差分更新时机等完整回合结束每一步都更新是否使用未来估计否只使用真实累计奖励是使用“即时奖励未来估计”方差高低偏差相对低相对高因为用了估计值适用任务必须有回合边界任意任务学习速度慢依赖完整轨迹快边走边学表格做出来之后很容易发现一件事TD不是全面碾压MC它是在偏差和方差之间做了一个对工程更友好的权衡。3. TD、MC、动态规划的三角关系为什么TD是那个“夹在中间反而赢”的方法3.1 三种方法的四维对比教科书里说TD方法结合了蒙特卡洛的采样思想和动态规划的“自举”bootstrap思想。我一开始听这句话完全没感觉直到我把三样东西并排摆在一起看。动态规划要求完全知道环境的转移概率然后利用贝尔曼方程直接迭代计算价值。它的问题是现实项目里你根本拿不到环境模型。MC不需要模型但必须等回合结束再说。而TD不需要模型也不用等回合结束——它就是那个想“既要又要”的方法。对比维度动态规划 DP蒙特卡洛 MC时序差分 TD是否需要环境模型需要不需要不需要是否自举用估计更新估计是否是更新时机遍历所有状态回合结束后每一步对初始值的依赖有较弱有3.2 偏差与方差的跷跷板为什么TD选择“相对有偏但稳定”“偏差”和“方差”这两个词在这个语境下可以这么理解偏差是你的估计系统和真实答案之间的系统性差距方差是你的估计值在不同次实验之间波动的大小。MC用真实回报更新理论上无偏。但真实回报是超长序列的累积随机因素多所以它的方差特别大。TD用“一步真实奖励一步估计值”更新因为估计值不完美所以它是有偏的。但它的方差很小因为每次更新涉及的随机变量少。我当时在编程作业里对比了两种方法的收敛曲线MC的V值曲线像一个醉汉走路晃得厉害TD的曲线虽然一开始可能方向有点偏但非常顺滑而且最终大多能修到一个不错的位置。所以TD在工程上非常实用——大多数时候你宁愿要一个稳定且能持续改进的结果也不要一个偶尔精确但经常剧烈变动的结果。3.3 随机游走实验里那个被反复验证的结论很多教材里都会提到一个随机游走实验一条由5个状态组成的链左端和右端各有不同的终点奖励。实验结论是在同样多的经验数据下TD方法学到的状态价值往往比MC方法更接近真实值。我在自己搭的简化版环境里亲自验证过这个结论。总共跑500个回合TD最后计算出的状态价值和理论真实价值的平均误差大概是0.04而MC做同样数量的回合平均误差还停在0.10左右。这个差距的来源主要是TD把每个回合内的每一步都变成了学习信号而MC一个回合只有一个信号。但这不意味着MC一无是处。在某些“奖励非常稀疏、单步信息几乎没有”的任务里TD可能学得很慢甚至被误导反而MC的整段总结有决定性作用。这也是为什么这两个方法在现代算法里经常以不同形式共存。4. 从TD(0)到TD(λ)把单步视角拉长的进阶玩法4.1 n步回报怎么让TD“看得更远”一点点前面讲的TD是最基础的版本每一步只看“下一步的估值 当前奖励”。这个版本叫TD(0)代表只看0步额外信息只往前看一个状态。但“只看一步”也有它的毛病如果一步之内根本没有有价值的信号学习速度依然不够快。于是有了n步回报的概念不是只看下一步而是看完接下来的n步真实奖励然后再加上第n步之后的那个状态的价值。这个方法的做法是介于MC和TD(0)之间的。n1时它就是TD(0)n∞ 时它其实就是MC。我当时在实现n步TD时最大的体会是n的选择是个典型的工程折中。n太小信号还是稀疏n太大方差又上来了。在我的导航Demo里n8到n16之间效果都不错几乎没有必要追求一步到位。n值特性适用场景1TD(0)方差最小更新最快但可能有偏差在线学习信号密集中间值如n8平衡偏差与方差大多数工程场景∞等价MC无偏但方差大学习慢回合清晰、随机性小4.2 λ与资格迹一个参数让TD从单步连续滑到MCn步回报需要你明确设定一个n而TD(λ)用另一种方式把“多步”揉进一个参数λ里。λ的取值范围是0到1。λ0就是TD(0)λ1就接近MC。TD(λ)的工程实现通常不是直接“往前看n步”而是引入一个称为资格迹eligibility trace的辅助变量。它为每个状态维护一个“最近被访问过多久”的记忆状态每被访问一次资格迹增加1每过一个时间步资格迹衰减γλ。那么价值更新的时候就不只是更新当前状态而是所有资格迹不为0的状态都被一并更新只是更新幅度按资格迹的不同而不同。我当时第一次看资格迹公式时觉得头大后来想明白一个类比它就像你在一张桌上擦掉污渍你不是只擦当前手指按的那一下而是整个接触过抹布的区域都跟着被擦了一遍。只不过离得远的区域擦得轻一点。所以TD(λ)可以在一次真实经验里同时更新很多相关状态学习效率极大提升。4.3 存在“离线”版本的资格迹这里要提一个我踩过的坑。TD(λ)有两种视角前向视角适合理论推导后向视角适合工程实现。如果你用的是后向视角加资格迹要特别注意实现顺序资格迹要先更新再计算TD误差最后才是应用更新。顺序乱了资格迹传递的方向就反了训练结果会莫名其妙地崩。我在一次重构代码时把资格迹的更新放在“计算TD误差”之后结果智能体学到的策略完全错乱一开始我还以为是学习率太大排查了一整天才定位到顺序问题。这个细节教科书里提得少但工程上极其重要。5. 把TD放进真实项目时最容易翻车的地方5.1 学习率α奖励尺度不同搜索步长完全不同TD公式里学习率α的选择直接影响收敛。但我实际项目里发现α的值必须和奖励尺度放在一起看不能孤立设定。如果奖励范围是0到1α取0.1到0.3通常没问题。但如果奖励范围是0到100同样α0.1一点的TD误差就会被放大导致V值剧烈震荡。我做过一个奖励范围0到500的任务直接套用α0.1结果是策略怎么都不稳定。后来我把α降到0.01同时把奖励做了归一化才恢复正常。环境奖励尺度我常用的α初始值备注0~10.1~0.3比较稳妥0~100.03~0.1需要配合奖励归一化0~100及以上0.005~0.03强烈建议先归一化5.2 离轨策略与自举的“双重陷阱”TD方法有一个天然的“隐患”它用当前策略产生的数据来更新当前策略的估值。可是如果你的算法是离轨策略的比如用行为策略收集数据、用目标策略更新TD目标里“下一步状态的估值”是基于目标策略的但实际到达的下一步状态是由行为策略决定的。这两者的不一致会导致TD更新出现系统性偏差。我在一个使用经验回放experience replay的项目里踩过这个坑。回放池里存满了各种策略产生的历史数据直接用TD公式更新结果训练到一半估值忽高忽低策略完全失控。后来我限制了回放池里数据的策略时效或者改用带重要性采样的变体才把问题按住。这里也提醒一下如果你只是做同步策略的在线学习TD的“自举”是安全的一旦引入回放、离轨这类机制就要仔细审视“用估计去更新估计”的链条有没有被打断。5.3 TD误差突变一个免费的状态异常指示器TD误差不只是公式里的一个中间量。我在项目里发现它有一个非常实用的额外价值它天然是一个“状态异常指示器”。正常收敛过程中TD误差应该逐渐减小并趋于平稳。但如果某一天环境发生了变化比如地图里突然多了一堵墙或者奖励规则改了TD误差的绝对值会突然猛增。因为智能体的旧估计已经无法解释眼前的新经验一步奖励和下一步估值之间的不一致性被放大了。我用这个特性做过一个小工具在训练循环里监控TD误差的滑动平均值。当它连续多个回合居高不下时就自动触发“环境可能变了”的告警。这比手动盯着奖励曲线高效得多因为奖励曲线可能因为探索随机性而抖动但TD误差的突变通常更具指示性。5.4 奖励归一化TD算法的“隐形前提”我最后想特别强调一个容易被忽略的点TD误差的大小和奖励的绝对尺度是线性相关的。你不归一化奖励TD误差动辄几十上百梯度类方法会直接被冲垮即使非梯度方法也会让价值估计算法变得极其不稳定。最省事的方案是采用“标准归一化”维护一个奖励的滑动平均值和滑动标准差每次更新前把奖励转成标准分。这样做之后TD误差的数值基本就能控制在个位数以内很多超参数α、γ的敏感性会大幅下降。在我自己的项目中归一化前后的对比非常明显归一化前收敛需要上千个回合且中途经常发散归一化后大约400个回合就开始进入稳定区间。代价只是增加了两个滑动变量完全是值的。最后再分享一个小技巧我后来在回头看这个项目的调参过程时发现最值得分享的小技巧其实特别简单别只盯着总奖励曲线去看TD误差和状态价值的传播过程。奖励曲线只能告诉你“最终效果好不好”而TD误差散点图能看到“智能体是不是正在理解这个环境”。如果你的TD误差长期不衰减说明学习率可能太大或太小或者环境信号确实过于稀疏——前者需要调参后者可能需要换一种信息密度更高的表征方式。时序差分方法说到底不是什么高不可攀的理论它就是一个“用自己的未来预测来修正当前判断”的朴素策略。想清楚这一步后面再看DQN、Actor-Critic那些复杂架构你会发现它们的底层都有一个同样的骨架估计、采样、修正循环往复。把这一步吃透你的强化学习之路就稳了一大半。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑