1. 网格世界问题概述
网格世界(Grid World)是强化学习领域经典的基准测试环境之一,它通过简化的二维网格模拟智能体在受限空间中的决策过程。在这个5动作版本的网格世界中,智能体可以执行上、下、左、右移动以及保持原地不动五种基本动作。每个格子可能包含不同的奖励值或特殊状态(如障碍物、终止状态等),为策略评估和改进算法提供了直观的可视化测试平台。
提示:网格世界虽然结构简单,但完整包含了马尔可夫决策过程(MDP)的所有核心要素,是理解强化学习基础概念的理想沙盒环境。
2. 策略评估方法实现
2.1 动态规划基础
策略评估的核心是计算给定策略π下的状态价值函数Vπ(s)。我们采用迭代策略评估算法,其更新公式为:
code复制V_{k+1}(s) = Σ π(a|s) * Σ p(s',r|s,a)[r + γV_k(s')]
其中γ为折扣因子,p(s',r|s,a)表示状态转移概率。在网格世界中,状态转移通常是确定性的(即执行某个动作后到达的下一个状态是确定的),这可以简化计算过程。
2.2 具体实现步骤
-
初始化价值函数:
- 所有非终止状态初始化为0
- 终止状态保持固定奖励值(如+1表示目标,-1表示陷阱)
-
同步迭代更新:
python复制def policy_evaluation(grid, policy, gamma=0.9, theta=1e-4): V = np.zeros(grid.shape) while True: delta = 0 for s in grid.non_terminal_states(): v = V[s] new_v = 0 for a, action_prob in enumerate(policy[s]): for s_prime, reward in grid.get_transitions(s, a): new_v += action_prob * (reward + gamma * V[s_prime]) V[s] = new_v delta = max(delta, abs(v - new_v)) if delta < theta: break return V -
终止条件:
- 当所有状态的价值函数更新幅度小于阈值θ时停止迭代
- 典型θ值取1e-4到1e-6之间
注意:实际实现时应使用矢量化运算加速计算,特别是对于大规模网格世界。
3. 策略改进技术详解
3.1 策略迭代算法
策略改进基于以下贪心策略更新规则:
code复制π'(s) = argmax_a Σ p(s',r|s,a)[r + γVπ(s')]
具体实现流程:
- 随机初始化策略π
- 重复以下步骤直到策略收敛:
a. 执行策略评估得到Vπ
b. 对每个状态s,选择使动作价值qπ(s,a)最大的动作
c. 如果新策略与旧策略相同则终止
3.2 价值迭代优化
价值迭代将策略评估和改进合并为一步操作:
code复制V_{k+1}(s) = max_a Σ p(s',r|s,a)[r + γV_k(s')]
关键实现差异:
- 直接更新最优价值函数而非当前策略下的价值函数
- 不需要显式维护策略,直到最后一步提取
- 通常比策略迭代收敛更快
python复制def value_iteration(grid, gamma=0.9, theta=1e-4):
V = np.zeros(grid.shape)
while True:
delta = 0
for s in grid.non_terminal_states():
v = V[s]
max_v = -float('inf')
for a in range(5): # 5个动作
total = 0
for s_prime, reward in grid.get_transitions(s, a):
total += (reward + gamma * V[s_prime])
if total > max_v:
max_v = total
V[s] = max_v
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
# 提取最优策略
policy = np.zeros((*grid.shape, 5))
for s in grid.non_terminal_states():
best_a = None
best_value = -float('inf')
for a in range(5):
total = 0
for s_prime, reward in grid.get_transitions(s, a):
total += (reward + gamma * V[s_prime])
if total > best_value:
best_value = total
best_a = a
policy[s][best_a] = 1.0
return V, policy
4. 五动作系统的特殊考量
4.1 保持不动动作的影响
相比传统的4方向移动,增加"保持不动"动作会带来:
- 策略稳定性:在接近目标时减少振荡
- 探索效率:可能延长收敛时间
- 局部最优:更容易陷入原地循环
解决方案:
- 为保持不动动作设置微小负奖励(-0.01)
- 在策略初始化时降低该动作的初始概率
4.2 动作空间扩展的实现技巧
python复制# 动作编码示例
ACTIONS = {
0: (-1, 0), # 上
1: (1, 0), # 下
2: (0, -1), # 左
3: (0, 1), # 右
4: (0, 0) # 保持
}
# 状态转移函数需特殊处理边界情况
def get_next_state(s, a):
if a == 4: # 保持动作
return s
# 其他动作处理...
5. 实际应用中的问题排查
5.1 常见收敛问题
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 价值函数振荡 | 学习率过高 | 降低γ值或减小步长 |
| 策略提前收敛到次优解 | 探索不足 | 增加ε-greedy参数 |
| 某些状态价值不更新 | 状态隔离 | 检查网格连通性 |
5.2 性能优化技巧
- 优先扫描:优先更新那些在上次迭代中变化较大的状态
- 异步更新:放弃同步更新,使用Gauss-Seidel方法
- 稀疏矩阵:对于大型网格,使用稀疏矩阵存储转移概率
python复制# 异步更新示例
for s in sorted(states, key=lambda x: -delta_history[x]):
# 更新逻辑...
delta_history[s] = abs(V_new[s] - V_old[s])
6. 可视化与调试方法
6.1 价值函数热力图
使用matplotlib绘制价值函数分布:
python复制import matplotlib.pyplot as plt
def plot_values(V):
plt.imshow(V, cmap='hot', interpolation='nearest')
for i in range(V.shape[0]):
for j in range(V.shape[1]):
plt.text(j, i, f"{V[i,j]:.1f}", ha='center', va='center')
plt.colorbar()
plt.show()
6.2 策略箭头图
可视化最优策略的动作方向:
python复制def plot_policy(policy):
X, Y = np.meshgrid(np.arange(policy.shape[1]),
np.arange(policy.shape[0]))
U = np.zeros_like(X, dtype=float)
V = np.zeros_like(Y, dtype=float)
for i in range(policy.shape[0]):
for j in range(policy.shape[1]):
best_a = np.argmax(policy[i,j])
if best_a == 4: # 保持不动
continue
U[i,j], V[i,j] = ACTIONS[best_a]
plt.quiver(X, Y, U, V, scale=15)
plt.show()
7. 扩展应用场景
7.1 随机网格世界
引入10-15%的动作执行失败概率,模拟现实环境的不确定性:
python复制def get_stochastic_transition(s, a):
if np.random.rand() < 0.1: # 10%概率执行随机动作
a = np.random.choice(5)
return get_deterministic_transition(s, a)
7.2 多目标优化
设置多个具有不同奖励的终止状态,训练智能体根据初始位置选择最优目标:
python复制rewards = {
(0,0): -1, # 陷阱
(4,4): +1, # 主目标
(0,4): +0.5 # 次级目标
}
我在实际项目中发现,当网格尺寸超过15×15时,建议采用分层强化学习或函数逼近方法替代传统的表格型方法。对于简单的5×5网格,完整的策略迭代通常能在50次迭代内收敛,而价值迭代一般只需要20次左右。一个实用的调试技巧是在价值函数更新时记录最大变化量,当观察到变化量曲线呈现平稳下降趋势时,可以提前终止迭代以节省计算资源。