策略迭代算法实战:FrozenLake-v0环境10轮收敛代码实现
强化学习算法中,策略迭代(Policy Iteration)是一种经典且高效的方法。本文将带您从零开始,在OpenAI Gym的FrozenLake-v0环境中完整实现策略迭代算法,并展示算法如何在10轮迭代内收敛到最优策略。
1. 环境准备与算法原理
FrozenLake-v0是OpenAI Gym提供的一个经典网格世界环境,智能体需要从起点穿越结冰的湖面到达目标位置。环境特点包括:
- 状态空间:4x4网格共16个状态
- 动作空间:4个方向(上、下、左、右)
- 转移概率:由于冰面湿滑,动作执行有33%概率会随机偏移
- 奖励机制:
- 到达目标:+1
- 掉入冰窟:0
- 其他情况:0
策略迭代算法由两个核心步骤交替进行:
- 策略评估(Policy Evaluation):计算当前策略下的状态价值函数
- 策略改进(Policy Improvement):基于当前价值函数改进策略
算法收敛的判断标准是策略不再发生变化。理论上,策略迭代能在有限步内收敛到最优策略。
2. 完整代码实现
以下是完整的Python实现,包含策略评估和策略改进两个核心函数:
import numpy as np import gym from gym.envs.toy_text.frozen_lake import generate_random_map def policy_evaluation(policy, env, gamma=0.9, theta=1e-6): """ 策略评估函数 :param policy: 当前策略矩阵 [nS, nA] :param env: Gym环境对象 :param gamma: 折扣因子 :param theta: 收敛阈值 :return: 状态价值函数V """ V = np.zeros(env.nS) while True: delta = 0 for s in range(env.nS): v = 0 for a, action_prob in enumerate(policy[s]): for prob, next_state, reward, done in env.P[s][a]: v += action_prob * prob * (reward + gamma * V[next_state]) delta = max(delta, abs(v - V[s])) V[s] = v if delta < theta: break return V def policy_improvement(V, env, gamma=0.9): """ 策略改进函数 :param V: 当前状态价值函数 :param env: Gym环境对象 :param gamma: 折扣因子 :return: 改进后的策略 """ policy = np.zeros([env.nS, env.nA]) for s in range(env.nS): q = np.zeros(env.nA) for a in range(env.nA): for prob, next_state, reward, done in env.P[s][a]: q[a] += prob * (reward + gamma * V[next_state]) best_a = np.argmax(q) policy[s, best_a] = 1.0 return policy def policy_iteration(env, max_iterations=10, gamma=0.9): """ 策略迭代主函数 :param env: Gym环境对象 :param max_iterations: 最大迭代次数 :param gamma: 折扣因子 :return: (最优策略, 最优价值函数) """ # 初始化随机策略 policy = np.ones([env.nS, env.nA]) / env.nA for i in range(max_iterations): V = policy_evaluation(policy, env, gamma) new_policy = policy_improvement(V, env, gamma) # 检查策略是否收敛 if np.allclose(new_policy, policy): print(f"策略在{i+1}轮迭代后收敛") break policy = new_policy return policy, V3. 算法执行与结果分析
让我们在FrozenLake-v0环境中运行上述算法:
# 创建环境 env = gym.make('FrozenLake-v0', desc=None, map_name="4x4", is_slippery=True) # 运行策略迭代 optimal_policy, optimal_V = policy_iteration(env) # 打印结果 print("最优价值函数:") print(optimal_V.reshape(4,4)) print("\n最优策略(0:左, 1:下, 2:右, 3:上):") print(np.argmax(optimal_policy, axis=1).reshape(4,4))典型输出结果如下:
策略在6轮迭代后收敛 最优价值函数: [[0.069 0.061 0.074 0.056] [0.092 0. 0.112 0. ] [0.145 0.247 0.3 0. ] [0. 0.38 0.639 0. ]] 最优策略(0:左, 1:下, 2:右, 3:上): [[0 3 3 3] [0 0 0 0] [3 1 0 0] [0 2 1 0]]关键观察:在实际运行中,算法通常在6-8轮迭代内收敛。收敛速度取决于环境参数和初始策略。
4. 收敛性验证与性能优化
为了验证算法的收敛性,我们可以记录每轮迭代后的策略变化:
def visualize_convergence(env, max_iter=10): policy = np.ones([env.nS, env.nA]) / env.nA changes = [] for i in range(max_iter): V = policy_evaluation(policy, env) new_policy = policy_improvement(V, env) changes.append(np.sum(new_policy != policy)) policy = new_policy if changes[-1] == 0: break return changes # 绘制策略变化图 changes = visualize_convergence(env) plt.plot(range(1, len(changes)+1), changes, 'o-') plt.xlabel('迭代轮次') plt.ylabel('策略变化数') plt.title('策略迭代收敛过程') plt.grid(True)性能优化技巧:
- 提前终止策略评估:不必等待价值函数完全收敛
- 异步更新:采用in-place方式更新价值函数
- 值迭代混合:在策略迭代中融入值迭代思想
优化后的策略评估函数示例:
def fast_policy_evaluation(policy, env, gamma=0.9, max_iter=100): V = np.zeros(env.nS) for _ in range(max_iter): prev_V = V.copy() for s in range(env.nS): v = 0 for a, action_prob in enumerate(policy[s]): for prob, next_state, reward, done in env.P[s][a]: v += action_prob * prob * (reward + gamma * prev_V[next_state]) V[s] = v return V5. 实际应用中的注意事项
在实现策略迭代算法时,有几个关键点需要特别注意:
- 环境动力学模型:策略迭代需要完全了解环境的转移概率P(s',r|s,a)
- 收敛条件设置:过严格的收敛条件会导致不必要的计算
- 折扣因子选择:γ值影响智能体的远见程度
与其他算法的对比:
| 特性 | 策略迭代 | 值迭代 | Q-learning |
|---|---|---|---|
| 需要模型 | 是 | 是 | 否 |
| 更新方式 | 策略-价值交替 | 直接更新价值 | 采样更新 |
| 收敛速度 | 较快 | 较慢 | 最慢 |
| 适用场景 | 中小型离散问题 | 中小型离散问题 | 任何规模问题 |
6. 扩展与进阶方向
掌握了基础策略迭代后,可以进一步探索以下方向:
- 广义策略迭代:结合策略评估和改进的通用框架
- 异步动态规划:提高大规模问题的计算效率
- 近似动态规划:应对连续状态空间问题
一个简单的异步策略迭代实现示例:
def async_policy_iteration(env, gamma=0.9): policy = np.ones([env.nS, env.nA]) / env.nA V = np.zeros(env.nS) while True: # 异步策略评估 for s in range(env.nS): v = 0 for a, action_prob in enumerate(policy[s]): for prob, next_state, reward, done in env.P[s][a]: v += action_prob * prob * (reward + gamma * V[next_state]) V[s] = v # 策略改进 policy_stable = True for s in range(env.nS): old_action = np.argmax(policy[s]) q = np.zeros(env.nA) for a in range(env.nA): for prob, next_state, reward, done in env.P[s][a]: q[a] += prob * (reward + gamma * V[next_state]) best_a = np.argmax(q) if old_action != best_a: policy_stable = False policy[s] = np.eye(env.nA)[best_a] if policy_stable: break return policy, V通过本教程,我们不仅实现了策略迭代算法在FrozenLake环境中的应用,还深入分析了算法的收敛特性和优化方法。这种实现方式可以轻松扩展到其他离散环境,是理解强化学习动态规划方法的重要基础。