首页 > TensorFlow教程 > 深度强化学习
阅读数:17
Actor-Critic算法实现“MountainCar-v0”游戏
在这一节将使用 Actor-Critic 算法解决 Gym 的过山车(MountainCar)问题。如图 1 的左图所示,小车位于两座山之间,其目标是抵达右侧山峰插着黄色小旗的位置。小车的动力无法让其一次性到达目标位置,需要通过来回行驶增加动力。

图 1:“MountainCar-v0”游戏示意图
游戏的环境信息如图 的右 1 侧表格所示,主要由小车的位置信息和速度信息两部分组成,黄色小旗在 0.5 的位置。在这个游戏中,我们的智能体(即小车)可以执行三个动作:施加一个向左的力、不施加力,以及施加一个向右的力,可以通过数值“0、1 和 2”来控制这三个力。
首先导入需要的包:
接着实现策略函数部分:
这里使用函数 y= [ex - e-x ] / [ex + e-x] 作为策略函数,第 2 行代码将参数 θ 与环境参数的点积作为策略函数的参数。我们使用了 ε 贪心搜索对环境进行探索,以 0.8 的概率根据当前的策略来选取动作,以 0.2 的概率随机选取动作。在第 13 行至第 18 行代码中,由于策略函数的值域为 (-1, 1),所以将其划分为三块,当“s”的值落在不同部分时执行不同的动作。
接下来实现 Actor 部分:
Actor 和 Critic 部分的代码完全依照 Actor-Critic 算法实现。第 6 行代码根据策略选取待执行的动作,第 9 行代码通过执行动作获取环境的反馈信息。第 12 行代码调用 critic 函数,这里返回的 delta 值反映了当前动作的好坏,我们用该值来优化策略函数。第 14 行代码中的“(1- s * s) * (-pre_observation)”是策略函数 πθ(s, a) 对 θ 求导的结果。
接着定义一个 actor_critic 函数:
最后让智能体开始学习:

图 1:“MountainCar-v0”游戏示意图
游戏的环境信息如图 的右 1 侧表格所示,主要由小车的位置信息和速度信息两部分组成,黄色小旗在 0.5 的位置。在这个游戏中,我们的智能体(即小车)可以执行三个动作:施加一个向左的力、不施加力,以及施加一个向右的力,可以通过数值“0、1 和 2”来控制这三个力。
首先导入需要的包:
import gym import numpy as np import random
接着实现策略函数部分:
def policy_function(observation, theta): weight = np.dot(theta, observation) #采用ε贪心搜索对环境进行探索 rand_num = random.random() epsilon = 0.8 if rand_num > epsilon: #随机选择一个动作 s = 0 action = random.randint(0, 2) else : #策略函数:y= [e^x-e^(-x) ] / [e^x +e^(-x)] s = (np.exp(weight) - np.exp(-weight)) / (np.exp(-weight)+ np.exp(-weight)) if s < -0.3: action = 0 #施加一个向左的力 elif s > 0.3: action = 1 #不施加力 else : action = 2 #施加一个向右的力 return s, action
这里使用函数 y= [ex - e-x ] / [ex + e-x] 作为策略函数,第 2 行代码将参数 θ 与环境参数的点积作为策略函数的参数。我们使用了 ε 贪心搜索对环境进行探索,以 0.8 的概率根据当前的策略来选取动作,以 0.2 的概率随机选取动作。在第 13 行至第 18 行代码中,由于策略函数的值域为 (-1, 1),所以将其划分为三块,当“s”的值落在不同部分时执行不同的动作。
接下来实现 Actor 部分:
def actor(env, observation, theta, pre_phi, phi, df_gamma, df_lambda): #学习率 alpha = 0.001 while True: #根据当前策略选择动作 s, action = policy_function(observation, theta) pre_observation = observation #执行选择的动作并得到反馈信息(新的环境状态、奖励等) observation, reward, done, info = env.step(action) #可视化游戏画面(重绘一帧画面) env.render() delta, pre_phi, phi = critic(pre_phi, phi, pre_observation, observation, reward, df_gamma, df_lambda) #更新策略函数的参数theta theta += alpha * df_lambda * delta * (1 - s * s) * (-pre_ observation) df_lambda *= df_gamma #游戏结束后重置环境 if done: observation = env.reset()
Actor 和 Critic 部分的代码完全依照 Actor-Critic 算法实现。第 6 行代码根据策略选取待执行的动作,第 9 行代码通过执行动作获取环境的反馈信息。第 12 行代码调用 critic 函数,这里返回的 delta 值反映了当前动作的好坏,我们用该值来优化策略函数。第 14 行代码中的“(1- s * s) * (-pre_observation)”是策略函数 πθ(s, a) 对 θ 求导的结果。
def critic(pre_phi, phi, pre_observation, observation, reward, df_gamma, df_lambda): #学习率 beta = 0.001 #计算当前状态的价值 v = np.dot(phi, observation) v = 1 / (1 + np.exp(-v)) #计算上一状态的价值 pre_v = np.dot(pre_phi, pre_observation) pre_v = 1 / (1 + np.exp(-pre_v)) delta = reward + df_gamma * v - pre_v pre_phi = phi #更新价值函数的参数 phi phi += beta * df_lambda * delta * pre_v * (1 - pre_v) * (-pre_observation) return delta, pre_phi, phi第 5 行至第 9 行代码计算了当前状态的价值和执行动作 a 之前的状态的价值。以 1/(1+e-x) 作为状态价值函数。第 10 行代码用 Qπ(s, a)-Vπ(s) 来评判动作 a 的好坏,并用其来优化价值函数。第 13 行代码中的“pre_v * (1- pre_v) * (-pre_observation)”是价值函数对参数 φ 的导数。
接着定义一个 actor_critic 函数:
def actor_critic(env): observation = env.reset() #随机初始化策略函数和状态价值函数的参数 theta = np.random.rand(2) phi = np.random.rand(2) pre_phi = phi #折扣因子 df_gamma = 0.9 df_lambda = 1 actor(env, observation, theta, pre_phi, phi, df_gamma, df_lambda)第 4 行和第 5 行代码随机初始化了策略函数和状态价值函数的参数,因为游戏的环境由两个因素构成,因此这里参数定义为长度为 2 的数组。
最后让智能体开始学习:
if __name __== "__main__": #注册游戏环境MountainCar-v0 game_env = gym.make('MountainCar-v0') #取消限制 game_env = game_env.unwrapped #开始学习玩"MountainCar-v0”游戏 actor_critic(game_env)