
1. 时序差分方法概述时序差分Temporal Difference, TD方法是强化学习中的核心算法之一它巧妙结合了蒙特卡洛方法和动态规划的优点。与需要等待整个回合结束才能更新的蒙特卡洛方法不同TD方法能够在每一步交互后立即进行更新这使得它在实际应用中更加高效。我在实际项目中经常遇到这样的情况当环境模型未知时传统的动态规划方法无法直接应用而蒙特卡洛方法又因为更新延迟导致学习效率低下。这时候TD方法就显示出其独特优势——它只需要下一个时刻的状态和奖励就能完成当前状态的更新。2. 时序差分原理详解2.1 TD误差与更新规则TD方法的核心是TD误差TD Error的概念。假设在状态s_t采取动作a_t后转移到状态s_{t1}并获得奖励r_t那么TD误差δ_t可以表示为δ_t r_t γV(s_{t1}) - V(s_t)其中γ是折扣因子。这个误差反映了当前价值估计与更准确的一步前瞻估计之间的差异。基于这个误差价值函数的更新规则为V(s_t) ← V(s_t) αδ_t这里α是学习率控制着更新的幅度。我在实践中发现这个简单的更新规则却能产生惊人的效果。2.2 与蒙特卡洛和动态规划的比较为了更直观理解TD方法的优势我整理了这个对比表格特性动态规划蒙特卡洛时序差分需要环境模型是否否在线更新否否是方差低高中等偏差无无有收敛速度快慢中等提示在实际应用中TD方法通常在偏差和方差之间取得了很好的平衡这也是它如此受欢迎的原因。3. Sarsa算法实现3.1 Sarsa算法流程Sarsa是一种经典的on-policy TD控制算法其名称来源于它使用的五元组(s_t, a_t, r_t, s_{t1}, a_{t1})。算法流程如下初始化Q(s,a)对每个回合 a. 初始化状态s b. 根据Q选择动作a如ε-greedy c. 对每一步 i. 执行a观察r和s ii. 根据Q选择a iii. 更新Q(s,a) ← Q(s,a) α[r γQ(s,a) - Q(s,a)] iv. s ← s, a ← a v. 直到s是终止状态3.2 Cliff Walking示例实现我在Cliff Walking环境中实现了Sarsa算法这是一个典型的网格世界问题class Sarsa: def __init__(self, ncol, nrow, epsilon, alpha, gamma, n_action4): self.Q_table np.zeros([nrow*ncol, n_action]) self.n_action n_action self.alpha alpha self.gamma gamma self.epsilon epsilon def take_action(self, state): if np.random.random() self.epsilon: return np.random.randint(self.n_action) return np.argmax(self.Q_table[state]) def update(self, s0, a0, r, s1, a1): td_error r self.gamma*self.Q_table[s1,a1] - self.Q_table[s0,a0] self.Q_table[s0,a0] self.alpha * td_error经过500回合训练后算法学习到了沿着悬崖边缘安全行走的策略平均回报从最初的-120提升到了-20左右。4. Q-learning算法解析4.1 Off-policy学习Q-learning是最著名的off-policy TD控制算法。与Sarsa不同它更新时使用最大Q值而不是下一个实际采取的动作Q(s,a) ← Q(s,a) α[r γmax_a Q(s,a) - Q(s,a)]这种差异带来了几个重要影响可以重用历史经验数据学习过程更加激进最终策略通常更优但训练过程更不稳定4.2 实现对比在同样的Cliff Walking环境中Q-learning的实现差异主要在update方法def update(self, s0, a0, r, s1): td_error r self.gamma*np.max(self.Q_table[s1]) - self.Q_table[s0,a0] self.Q_table[s0,a0] self.alpha * td_error有趣的是Q-learning最终学习到的策略会沿着悬崖边缘最近路径行走虽然理论上是最优路径但在训练过程中偶尔会掉下悬崖。5. 多步TD方法5.1 n步Sarsa为了平衡TD和蒙特卡洛的优点我们可以使用n步TD方法。n步Sarsa的回报估计为G_t r_t γr_{t1} ... γ^{n-1}r_{tn-1} γ^n Q(s_{tn}, a_{tn})实现时需要维护最近n个状态、动作和奖励class NStepSarsa: def __init__(self, n, ncol, nrow, epsilon, alpha, gamma): self.n n self.state_list [] self.action_list [] self.reward_list [] # 其他初始化同Sarsa def update(self, s0, a0, r, s1, a1, done): self.state_list.append(s0) self.action_list.append(a0) self.reward_list.append(r) if len(self.state_list) self.n: G self.Q_table[s1,a1] for i in reversed(range(self.n)): G self.gamma*G self.reward_list[i] if done and i0: s self.state_list[i] a self.action_list[i] self.Q_table[s,a] self.alpha*(G-self.Q_table[s,a]) s self.state_list.pop(0) a self.action_list.pop(0) self.reward_list.pop(0) self.Q_table[s,a] self.alpha*(G-self.Q_table[s,a]) if done: self.state_list [] self.action_list [] self.reward_list []实验表明5步Sarsa比单步Sarsa收敛更快平均回报提升更明显。6. 实践建议与常见问题6.1 参数选择经验基于我的项目经验以下参数设置通常效果不错学习率α从0.1开始随着训练逐渐减小折扣因子γ0.9-0.99之间ε-greedy的ε从1.0线性衰减到0.16.2 常见问题排查算法不收敛检查学习率是否过大确认折扣因子设置合理尝试减小探索率ε策略过于保守可能是Sarsa算法特性导致尝试改用Q-learning调整奖励函数设计训练波动大减小学习率尝试使用n-step方法增加经验回放缓冲区7. 扩展应用时序差分方法在现代强化学习中有着广泛应用与神经网络结合形成DQN用于策略梯度方法的Critic网络多智能体系统中的独立学习机器人控制任务我在自动驾驶项目中就成功应用了Q-learning算法进行路径规划。通过精心设计状态表示和奖励函数智能体能够在复杂环境中学习到安全的驾驶策略。