持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
基于值迭代的强化学习算法
基于值迭代的强化学习算法的核心思想与策略评估非常类似,它也是一种迭代算法。从任意策略值开始,然后根据 Bellman
最优方程迭代更新值,直到它们收敛为止。在每次迭代中,选择达到能够获得最大策略值的动作:
其中, 表示最优值,它是最优策略值; 表示采取动作 从状态 转移到状态 的概率; 是在状态 通过采取动作 所获得的奖励。 一旦计算出最佳值,我们就可以轻松地相应地获得最佳策略:
使用 PyTorch 实现基于值迭代的强化学习算法
本节,我们使用 PyTorch
实现基于值迭代的强化学习算法来解决 FrozenLake
问题。 首先,我们导入所需的库并创建 FrozenLake
环境实例,并定义折扣因子和判断算法收敛的阈值:
import torch
import gym
env = gym.make('FrozenLake-v0')
gamma = 0.99
threshold = 0.0001
复制代码
接下来,定义函数使用基于值迭代的强化学习算法计算最佳策略值。在基于值函数的强化学习算法中,我们通过迭代应用 Bellman
最优方程来获得最优值函数。 以下是 Bellman
最优方程的另一个版本,它可以处理奖励部分取决于新状态的环境:
其中,
是通过采取动作
从状态
转移到状态
而得到的奖励。由于此版本通用性更强,因此我们将基于此式实现 value_function
函数,在函数中执行以下操作:
- 将策略值初始化为全零张量
- 根据
Bellman
最优方程更新策略值 - 计算所有状态下策略值的最大变化
- 如果最大变化大于阈值,继续更新策略值;否则,终止评估过程,并返回最新值作为最佳值
def value_function(env, gamma, threshold):
"""
Solve a given environment with value function based algorithm
env: Gym 环境
gamma: 折扣因子
threshold: 当所有状态的值函数都小于阈值使,评估过程终止
return: 给定环境的最优策略值
"""
n_state = env.observation_space.n
n_action = env.action_space.n
V = torch.zeros(n_state)
while True:
V_temp = torch.zeros(n_state)
for state in range(n_state):
v_actions = torch.zeros(n_action)
for action in range(n_action):
for trans_prob, new_state, reward, _ in env.env.P[state][action]:
v_actions[action] += trans_prob * (reward + gamma * V[new_state])
V_temp[state] = torch.max(v_actions)
max_delta = torch.max(torch.abs(V - V_temp))
V = V_temp.clone()
if max_delta <= threshold:
break
return V
复制代码
以定义的环境、折扣因子和收敛阈值为参数执行 value_function
函数,然后打印最佳值:
V_optimal = value_function(env, gamma, threshold)
print('Optimal values:\n{}'.format(V_optimal))
复制代码
打印出的最优值如下所示:
Optimal values:
tensor([0.5404, 0.4966, 0.4681, 0.4541, 0.5569, 0.0000, 0.3572, 0.0000, 0.5905,
0.6421, 0.6144, 0.0000, 0.0000, 0.7410, 0.8625, 0.0000])
复制代码
得到最优值之后,我们就可以基于最优值实现提取最优策略的函数:
def extract_optimal_policy(env, V_optimal, gamma):
"""
Obtain the optimal policy based on the optimal values
env: Gym 环境
V_optimal: 最优策略值
gamma: 折扣因子
return: 最优策略
"""
n_state = env.observation_space.n
n_action = env.action_space.n
optimal_policy = torch.zeros(n_state)
for state in range(n_state):
v_actions = torch.zeros(n_action)
for action in range(n_action):
for trans_prob, new_state, reward, _ in env.env.P[state][action]:
v_actions[action] += trans_prob * (reward + gamma * V_optimal[new_state])
optimal_policy[state] = torch.argmax(v_actions)
return optimal_policy
复制代码
以环境、折扣因子和最佳值为参数执行 extract_optimal_policy
函数,然后打印最佳策略:
optimal_policy = extract_optimal_policy(env, V_optimal, gamma)
print('Optimal policy:\n{}'.format(optimal_policy))
复制代码
打印出的最优策略如下所示:
Optimal policy:
tensor([0., 3., 3., 3., 0., 0., 0., 0., 3., 1., 0., 0., 0., 2., 1., 0.])
Average total reward under the optimal policy: 0.769
复制代码
最后,我们评估最佳策略的有效性。以最佳策略运行 FrozenLake
环境 1000
回合,并计算平均奖励:
def run_episode(env, policy):
state = env.reset()
total_reward = 0
is_done = False
while not is_done:
action = policy[state].item()
state, reward, is_done, info = env.step(action)
total_reward += reward
if is_done:
break
return total_reward
n_episode = 1000
total_rewards = []
for episode in range(n_episode):
total_reward = run_episode(env, optimal_policy)
total_rewards.append(total_reward)
print('Average total reward under the optimal policy: {}'.format(sum(total_rewards) / n_episode))
复制代码
在最佳策略下,智能体平均有 75%
的概率可以达到目标。由于冰面十分光滑,因此这是我们能够获得的最好的效果:
tensor([0., 3., 3., 3., 0., 0., 0., 0., 3., 1., 0., 0., 0., 2., 1., 0.])
Average total reward under the optimal policy: 0.769
复制代码