策略梯度训练cartpole小游戏
我原来已经安装了anaconda,在此基础上进入cmd进行pip install tensorflow和pip install gym就可以了. 在win10的pycharm做的。
policy_gradient.py
# -*- coding: UTF-8 -*- """
Policy Gradient 算法(REINFORCE)。做决策的部分,相当于机器人的大脑
""" import numpy as np
import tensorflow as tf try:
xrange = xrange # Python 2
except:
xrange = range # Python 3 # 策略梯度 类
class PolicyGradient:
def __init__(self,
lr, # 学习速率
s_size, # state/observation 的特征数目
a_size, # action 的数目
h_size, # hidden layer(隐藏层)神经元数目
discount_factor=0.99 # 折扣因子
):
self.gamma = discount_factor # Reward 递减率 # 神经网络的前向传播部分。大脑根据 state 来选 action
self.state_in = tf.placeholder(shape=[None, s_size], dtype=tf.float32) # 第一层全连接层
hidden = tf.layers.dense(self.state_in, h_size, activation=tf.nn.relu) # 第二层全连接层,用 Softmax 来算概率
self.output = tf.layers.dense(hidden, a_size, activation=tf.nn.softmax) # 直接选择概率最大的那个 action
self.chosen_action = tf.argmax(self.output, 1) # 下面主要是负责训练的一些过程
# 我们给神经网络传递 reward 和 action,为了计算 loss
# 再用 loss 来调节神经网络的参数
self.reward_holder = tf.placeholder(shape=[None], dtype=tf.float32)
self.action_holder = tf.placeholder(shape=[None], dtype=tf.int32) self.indexes = tf.range(0, tf.shape(self.output)[0]) * tf.shape(self.output)[1] + self.action_holder
self.outputs = tf.gather(tf.reshape(self.output, [-1]), self.indexes) # 计算 loss(和平时说的 loss 不一样)有一个负号
# 因为 TensorFlow 自带的梯度下降只能 minimize(最小化)loss
# 而 Policy Gradient 里面是要让这个所谓的 loss 最大化
# 因此需要反一下。对负的去让它最小化,就是让它正向最大化
self.loss = -tf.reduce_mean(tf.log(self.outputs) * self.reward_holder) # 得到可被训练的变量
train_vars = tf.trainable_variables() self.gradient_holders = [] for index, var in enumerate(train_vars):
placeholder = tf.placeholder(tf.float32, name=str(index) + '_holder')
self.gradient_holders.append(placeholder) # 对 loss 以 train_vars 来计算梯度
self.gradients = tf.gradients(self.loss, train_vars) optimizer = tf.train.AdamOptimizer(learning_rate=lr)
# apply_gradients 是 minimize 方法的第二部分,应用梯度
self.update_batch = optimizer.apply_gradients(zip(self.gradient_holders, train_vars)) # 计算折扣后的 reward
# 公式: E = r1 + r2 * gamma + r3 * gamma * gamma + r4 * gamma * gamma * gamma ...
def discount_rewards(self, rewards):
discounted_r = np.zeros_like(rewards)
running_add = 0
for t in reversed(xrange(0, rewards.size)):
running_add = running_add * self.gamma + rewards[t]
discounted_r[t] = running_add
return discounted_r
play.py
# -*- coding: UTF-8 -*- """
游戏的主程序,调用机器人的 Policy Gradient 决策大脑
""" import numpy as np
import gym
import tensorflow as tf from policy_gradient import PolicyGradient # 伪随机数。为了能够复现结果
np.random.seed(1) env = gym.make('CartPole-v0')
env = env.unwrapped # 取消限制
env.seed(1) # 普通的 Policy Gradient 方法, 回合的方差比较大, 所以选一个好点的随机种子 print(env.action_space) # 查看这个环境中可用的 action 有多少个
print(env.observation_space) # 查看这个环境中 state/observation 有多少个特征值
print(env.observation_space.high) # 查看 observation 最高取值
print(env.observation_space.low) # 查看 observation 最低取值 update_frequency = 5 # 更新频率,多少回合更新一次
total_episodes = 3000 # 总回合数 # 创建 PolicyGradient 对象
agent = PolicyGradient(lr=0.01,
a_size=env.action_space.n, # 对 CartPole-v0 是 2, 两个 action,向左/向右
s_size=env.observation_space.shape[0], # 对 CartPole-v0 是 4
h_size=8) with tf.Session() as sess:
# 初始化所有全局变量
sess.run(tf.global_variables_initializer()) # 总的奖励
total_reward = [] gradient_buffer = sess.run(tf.trainable_variables())
for index, grad in enumerate(gradient_buffer):
gradient_buffer[index] = grad * 0 i = 0 # 第几回合
while i < total_episodes:
# 初始化 state(状态)
s = env.reset() episode_reward = 0
episode_history = [] while True:
# 更新可视化环境
env.render() # 根据神经网络的输出,随机挑选 action
a_dist = sess.run(agent.output, feed_dict={agent.state_in: [s]})
a = np.random.choice(a_dist[0], p=a_dist[0])
a = np.argmax(a_dist == a) # 实施这个 action, 并得到环境返回的下一个 state, reward 和 done(本回合是否结束)
s_, r, done, _ = env.step(a) # 这里的 r(奖励)不能准确引导学习 x, x_dot, theta, theta_dot = s_ # 把 s_ 细分开, 为了修改原配的 reward # x 是车的水平位移。所以 r1 是车越偏离中心, 分越少
# theta 是棒子离垂直的角度, 角度越大, 越不垂直。所以 r2 是棒越垂直, 分越高
r1 = (env.x_threshold - abs(x)) / env.x_threshold - 0.8
r2 = (env.theta_threshold_radians - abs(theta)) / env.theta_threshold_radians - 0.5
r = r1 + r2 # 总 reward 是 r1 和 r2 的结合, 既考虑位置, 也考虑角度, 这样学习更有效率 episode_history.append([s, a, r, s_]) episode_reward += r
s = s_ # Policy Gradient 是回合更新
if done: # 如果此回合结束
# 更新神经网络
episode_history = np.array(episode_history) episode_history[:, 2] = agent.discount_rewards(episode_history[:, 2]) feed_dict = {
agent.reward_holder: episode_history[:, 2],
agent.action_holder: episode_history[:, 1],
agent.state_in: np.vstack(episode_history[:, 0])
} # 计算梯度
grads = sess.run(agent.gradients, feed_dict=feed_dict) for idx, grad in enumerate(grads):
gradient_buffer[idx] += grad if i % update_frequency == 0 and i != 0:
feed_dict = dictionary = dict(zip(agent.gradient_holders, gradient_buffer)) # 应用梯度下降来更新参数
_ = sess.run(agent.update_batch, feed_dict=feed_dict) for index, grad in enumerate(gradient_buffer):
gradient_buffer[index] = grad * 0 total_reward.append(episode_reward)
break # 每 50 回合打印平均奖励
if i % 50 == 0:
print("回合 {} - {} 的平均奖励: {}".format(i, i + 50, np.mean(total_reward[-50:]))) i += 1
启动训练:
会报一些警告,不用理会,训练到奖励大概有300分的时候,就比较稳定了,能较好的平衡杠子了
还有另外一个游戏Mountain-car小游戏也可以基于策略梯度来做, 这个小游戏的说明见“基于核方法的强化学习算法-----何源,张文生”里面有一段说明了这个小游戏:
这个具体的实现下回继续。。。
策略梯度训练cartpole小游戏的更多相关文章
- 微信小游戏 RES版本控制+缓存策略 (resplugin和ResSplitPlugin插件使用)
参考: RES版本控制 使用 AssetsManager 灵活定制微信小游戏的缓存策略 一.我们的目标 目标就是让玩家快速进入游戏,然后根据游戏的进度加载相应的资源,并可对资源进行版本控制.本地缓存. ...
- lecture6-mini批量梯度训练及三个加速的方法
Hinton的第6课,这一课中最后的那个rmsprop,关于它的资料,相对较少,差不多除了Hinton提出,没论文的样子,各位大大可以在这上面研究研究啊. 一.mini-批量梯度下降概述 这部分将介绍 ...
- 强化学习(十三) 策略梯度(Policy Gradient)
在前面讲到的DQN系列强化学习算法中,我们主要对价值函数进行了近似表示,基于价值来学习.这种Value Based强化学习方法在很多领域都得到比较好的应用,但是Value Based强化学习方法也有很 ...
- 强化学习_PolicyGradient(策略梯度)_代码解析
使用策略梯度解决离散action space问题. 一.导入包,定义hyper parameter import gym import tensorflow as tf import numpy as ...
- 强化学习-学习笔记14 | 策略梯度中的 Baseline
本篇笔记记录学习在 策略学习 中使用 Baseline,这样可以降低方差,让收敛更快. 14. 策略学习中的 Baseline 14.1 Baseline 推导 在策略学习中,我们使用策略网络 \(\ ...
- 软件工程 Android小游戏 猜拳大战
一.前言 最近学校举办的大学生程序设计竞赛,自己利用课余时间写了一个小游戏,最近一直在忙这个写这个小游戏,参加比赛,最终是老师说自己写的简单,可以做的更复杂的点的.加油 二.内容简介 自己玩过Andr ...
- [安卓] 12、开源一个基于SurfaceView的飞行射击类小游戏
前言 这款安卓小游戏是基于SurfaceView的飞行射击类游戏,采用Java来写,没有采用游戏引擎,注释详细,条理比较清晰,适合初学者了解游戏状态转化自动机和一些继承与封装的技巧. 效果展示 ...
- 2048小游戏代码解析 C语言版
2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图: 游 ...
- C语言实现简易2048小游戏
一直很喜欢玩这个小游戏,简单的游戏中包含运气与思考与策略,喜欢这种简约又不失内涵的游戏风格.于是萌生了用C语言实现一下的想法. 具体代码是模仿这个:https://www.cnblogs.com/ju ...
随机推荐
- javascript 对象(四)
一.对象概述 对象中包含一系列的属性,这些属性是无序的.每个属性都有一个字符串key和对应的value. var obj={x:1,y:2}; obj.x; obj.y; 1.为什么属性的key必须是 ...
- C# 之 4个访问修饰符和8个声明修饰符详解
一.4个访问修饰符(是添加到类.结构或成员声明的关键字) [1] Public:公有的,是类型和类型成员的访问修饰符.对其访问没有限制. [2] Internal:内部的,是类型和类型成员的访问修饰符 ...
- xcode svn commit is not under version control 和 git常用指令
使用Xcode提交一个第三方库时,由于包含资源文件,总是提交不了,提示报错:XXX commit is not under version control (1) 网上查了下,得知 xcode对于sv ...
- Python_set集合部分功能介绍
set:无序集合,不能出现重复的元素 set的创建:s1=set() #访问速度快 #解决重复问题 x.add():添加一个新的元素,添加的重复的元素自动过滤掉 x.clear():清空集合 x.di ...
- tomcat-会话绑定
会话保存 1) session sticky source_ip 原地址绑定 nginx: ip_hash haproxy: source lvs: ...
- cactiEZ 配置
CactiEZ 中文版是简单有效的cacti中文解决方案,它基于centos6 整合了cacti的相关软件,重新编译的一个新的操作系统 它基于centos6,启动速度快,支持EXT4文件系统,全中文页 ...
- Codeforces 354B dp Game with Strings dp
Game with Strings 题意并不是在图上走,看了好久才看出来.. dp[ i ][ mask ]表示从 i 层开始走,起点有mask个, a的个数-b的个数的 最大值或者最小值. #in ...
- 最短路(bellman)-hdu1217
Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 这时候,就需要使用其他的算法来求解最 ...
- JAVA项目中常用的异常处理情况
1.数学运算异常( java.lang.arithmeticexception) 程序中出现了除以零这样的运算就会出这样的异常,对这种异常,大家就要好好检查一下自己程序中涉及到数学运算的地方,公式是不 ...
- Linux 系统分级及root权限相关
单用户模式修改用户密码 救援模式 让我们先来了解一下linux的运行步骤 1. Linux系统引导的顺序掌握Linux系统引导的顺序:BIOSMBRKernelinit其中,BIOS的工作是检查计算机 ...