1. 项目概述
网格世界(Grid World)是强化学习领域最经典的实验环境之一,它通过简化的二维网格模拟智能体与环境的交互过程。这个项目聚焦于5动作网格世界中的策略评估(Policy Evaluation)与策略改进(Policy Improvement)完整实现,我将结合代码实例和可视化分析,拆解贝尔曼方程在离散空间中的具体应用。对于刚接触动态规划的同学,这个5x5的网格案例能帮你直观理解策略迭代(Policy Iteration)如何逐步收敛到最优策略。
2. 核心概念解析
2.1 网格世界建模要点
我们构建的5x5网格具有以下特性:
- 状态空间:25个网格单元(含终止状态)
- 动作空间:上/下/左/右/停留(5个离散动作)
- 转移概率:确定性转移(执行动作a必达预期格子)
- 奖励函数:
- 到达目标格子:+10
- 碰到边界:-1并保持原位
- 其他移动:-0.1
注意:奖励值设计直接影响策略收敛方向,稀疏奖励(如仅终点有奖励)会导致学习效率低下。本案例采用密集奖励设计加速收敛。
2.2 策略评估的数学本质
策略评估通过贝尔曼期望方程计算状态价值函数V(s):
code复制V(s) = Σ π(a|s) * [R(s,a) + γ * Σ P(s'|s,a) * V(s')]
对于确定性策略,方程简化为:
code复制V(s) = R(s,a) + γ * V(s')
在代码实现中,我们采用同步更新(synchronous update)方式:
python复制def policy_evaluation(grid, policy, gamma=0.9, theta=1e-4):
V = np.zeros(grid.size)
while True:
delta = 0
for s in grid.states:
v = V[s]
a = policy[s]
V[s] = grid.reward(s, a) + gamma * V[grid.next_state(s, a)]
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
3. 策略迭代实现细节
3.1 策略改进的贪心策略
在获得价值函数后,策略改进通过以下方式更新策略:
python复制def policy_improvement(grid, V, gamma=0.9):
policy = np.zeros(grid.size, dtype=int)
for s in grid.states:
action_values = []
for a in grid.actions:
action_values.append(grid.reward(s, a) + gamma * V[grid.next_state(s, a)])
policy[s] = np.argmax(action_values)
return policy
3.2 完整策略迭代流程
策略迭代的收敛过程如下图所示(以3x3网格为例):
code复制Iteration 0: Iteration 1: Iteration 2:
[ → → → ] [ → → ↓ ] [ → → ↓ ]
[ → → → ] → [ → → ↓ ] → [ → ↓ ↓ ]
[ → → → ] [ → → ↓ ] [ ↓ ↓ ↓ ]
实际编码时需要处理两个关键问题:
- 边界条件:当动作导致越界时维持原状态
- 收敛判定:策略不再变化或价值变化小于阈值θ
4. 实验结果分析
4.1 不同折扣因子的影响
我们对比γ=0.9与γ=0.5时的策略收敛速度:
| 参数 | 迭代次数 | 最终策略特征 |
|---|---|---|
| γ=0.9 | 7 | 长视距,绕行障碍 |
| γ=0.5 | 4 | 短视距,倾向直线路径 |
4.2 典型问题排查
-
策略震荡:
- 现象:策略在两种动作间来回切换
- 解决方案:降低学习率或增加迭代间隔
-
价值函数发散:
- 常见原因:γ≥1或奖励值范围过大
- 修正方法:检查贝尔曼方程的收敛条件
5. 高级优化技巧
5.1 异步动态规划加速
相比同步更新,异步更新可显著提升速度:
python复制# 随机选择状态更新
def async_update(V):
s = random.choice(grid.states)
V[s] = max([grid.reward(s,a) + gamma*V[grid.next_state(s,a)]
for a in grid.actions])
return V
5.2 价值迭代对比
将策略迭代改为价值迭代只需修改主循环:
python复制while not converged:
V = update_value_function(V)
policy = extract_policy(V)
6. 工程实践建议
-
可视化监控:实时渲染价值函数的热力图(使用matplotlib)
python复制plt.imshow(V.reshape(grid.shape), cmap='hot') plt.colorbar() -
超参数调优:
- γ∈[0.8, 0.99]:平衡即时与远期奖励
- θ∈[1e-6, 1e-3]:控制收敛精度
-
扩展性设计:
- 使用面向对象封装网格环境
- 支持非确定性转移(如80%概率执行预期动作)
我在实际项目中发现的几个关键经验:
- 网格尺寸超过15x15时建议改用优先级扫描(Prioritized Sweeping)
- 对于随机策略,需要存储π(a|s)矩阵而非确定性动作
- 并行化状态更新可提升5-8倍性能(使用multiprocessing)