我原来已经安装了anaconda,在此基础上进入cmd进行pip install tensorflow和pip install gym就可以了. 在win10的pycharm做的。

policy_gradient.py

  1. # -*- coding: UTF-8 -*-
  2.  
  3. """
  4. Policy Gradient 算法(REINFORCE)。做决策的部分,相当于机器人的大脑
  5. """
  6.  
  7. import numpy as np
  8. import tensorflow as tf
  9.  
  10. try:
  11. xrange = xrange # Python 2
  12. except:
  13. xrange = range # Python 3
  14.  
  15. # 策略梯度 类
  16. class PolicyGradient:
  17. def __init__(self,
  18. lr, # 学习速率
  19. s_size, # state/observation 的特征数目
  20. a_size, # action 的数目
  21. h_size, # hidden layer(隐藏层)神经元数目
  22. discount_factor=0.99 # 折扣因子
  23. ):
  24. self.gamma = discount_factor # Reward 递减率
  25.  
  26. # 神经网络的前向传播部分。大脑根据 state 来选 action
  27. self.state_in = tf.placeholder(shape=[None, s_size], dtype=tf.float32)
  28.  
  29. # 第一层全连接层
  30. hidden = tf.layers.dense(self.state_in, h_size, activation=tf.nn.relu)
  31.  
  32. # 第二层全连接层,用 Softmax 来算概率
  33. self.output = tf.layers.dense(hidden, a_size, activation=tf.nn.softmax)
  34.  
  35. # 直接选择概率最大的那个 action
  36. self.chosen_action = tf.argmax(self.output, 1)
  37.  
  38. # 下面主要是负责训练的一些过程
  39. # 我们给神经网络传递 reward 和 action,为了计算 loss
  40. # 再用 loss 来调节神经网络的参数
  41. self.reward_holder = tf.placeholder(shape=[None], dtype=tf.float32)
  42. self.action_holder = tf.placeholder(shape=[None], dtype=tf.int32)
  43.  
  44. self.indexes = tf.range(0, tf.shape(self.output)[0]) * tf.shape(self.output)[1] + self.action_holder
  45. self.outputs = tf.gather(tf.reshape(self.output, [-1]), self.indexes)
  46.  
  47. # 计算 loss(和平时说的 loss 不一样)有一个负号
  48. # 因为 TensorFlow 自带的梯度下降只能 minimize(最小化)loss
  49. # 而 Policy Gradient 里面是要让这个所谓的 loss 最大化
  50. # 因此需要反一下。对负的去让它最小化,就是让它正向最大化
  51. self.loss = -tf.reduce_mean(tf.log(self.outputs) * self.reward_holder)
  52.  
  53. # 得到可被训练的变量
  54. train_vars = tf.trainable_variables()
  55.  
  56. self.gradient_holders = []
  57.  
  58. for index, var in enumerate(train_vars):
  59. placeholder = tf.placeholder(tf.float32, name=str(index) + '_holder')
  60. self.gradient_holders.append(placeholder)
  61.  
  62. # 对 loss 以 train_vars 来计算梯度
  63. self.gradients = tf.gradients(self.loss, train_vars)
  64.  
  65. optimizer = tf.train.AdamOptimizer(learning_rate=lr)
  66. # apply_gradients 是 minimize 方法的第二部分,应用梯度
  67. self.update_batch = optimizer.apply_gradients(zip(self.gradient_holders, train_vars))
  68.  
  69. # 计算折扣后的 reward
  70. # 公式: E = r1 + r2 * gamma + r3 * gamma * gamma + r4 * gamma * gamma * gamma ...
  71. def discount_rewards(self, rewards):
  72. discounted_r = np.zeros_like(rewards)
  73. running_add = 0
  74. for t in reversed(xrange(0, rewards.size)):
  75. running_add = running_add * self.gamma + rewards[t]
  76. discounted_r[t] = running_add
  77. return discounted_r

play.py

  1. # -*- coding: UTF-8 -*-
  2.  
  3. """
  4. 游戏的主程序,调用机器人的 Policy Gradient 决策大脑
  5. """
  6.  
  7. import numpy as np
  8. import gym
  9. import tensorflow as tf
  10.  
  11. from policy_gradient import PolicyGradient
  12.  
  13. # 伪随机数。为了能够复现结果
  14. np.random.seed(1)
  15.  
  16. env = gym.make('CartPole-v0')
  17. env = env.unwrapped # 取消限制
  18. env.seed(1) # 普通的 Policy Gradient 方法, 回合的方差比较大, 所以选一个好点的随机种子
  19.  
  20. print(env.action_space) # 查看这个环境中可用的 action 有多少个
  21. print(env.observation_space) # 查看这个环境中 state/observation 有多少个特征值
  22. print(env.observation_space.high) # 查看 observation 最高取值
  23. print(env.observation_space.low) # 查看 observation 最低取值
  24.  
  25. update_frequency = 5 # 更新频率,多少回合更新一次
  26. total_episodes = 3000 # 总回合数
  27.  
  28. # 创建 PolicyGradient 对象
  29. agent = PolicyGradient(lr=0.01,
  30. a_size=env.action_space.n, # 对 CartPole-v0 是 2, 两个 action,向左/向右
  31. s_size=env.observation_space.shape[0], # 对 CartPole-v0 是 4
  32. h_size=8)
  33.  
  34. with tf.Session() as sess:
  35. # 初始化所有全局变量
  36. sess.run(tf.global_variables_initializer())
  37.  
  38. # 总的奖励
  39. total_reward = []
  40.  
  41. gradient_buffer = sess.run(tf.trainable_variables())
  42. for index, grad in enumerate(gradient_buffer):
  43. gradient_buffer[index] = grad * 0
  44.  
  45. i = 0 # 第几回合
  46. while i < total_episodes:
  47. # 初始化 state(状态)
  48. s = env.reset()
  49.  
  50. episode_reward = 0
  51. episode_history = []
  52.  
  53. while True:
  54. # 更新可视化环境
  55. env.render()
  56.  
  57. # 根据神经网络的输出,随机挑选 action
  58. a_dist = sess.run(agent.output, feed_dict={agent.state_in: [s]})
  59. a = np.random.choice(a_dist[0], p=a_dist[0])
  60. a = np.argmax(a_dist == a)
  61.  
  62. # 实施这个 action, 并得到环境返回的下一个 state, reward 和 done(本回合是否结束)
  63. s_, r, done, _ = env.step(a) # 这里的 r(奖励)不能准确引导学习
  64.  
  65. x, x_dot, theta, theta_dot = s_ # 把 s_ 细分开, 为了修改原配的 reward
  66.  
  67. # x 是车的水平位移。所以 r1 是车越偏离中心, 分越少
  68. # theta 是棒子离垂直的角度, 角度越大, 越不垂直。所以 r2 是棒越垂直, 分越高
  69. r1 = (env.x_threshold - abs(x)) / env.x_threshold - 0.8
  70. r2 = (env.theta_threshold_radians - abs(theta)) / env.theta_threshold_radians - 0.5
  71. r = r1 + r2 # 总 reward 是 r1 和 r2 的结合, 既考虑位置, 也考虑角度, 这样学习更有效率
  72.  
  73. episode_history.append([s, a, r, s_])
  74.  
  75. episode_reward += r
  76. s = s_
  77.  
  78. # Policy Gradient 是回合更新
  79. if done: # 如果此回合结束
  80. # 更新神经网络
  81. episode_history = np.array(episode_history)
  82.  
  83. episode_history[:, 2] = agent.discount_rewards(episode_history[:, 2])
  84.  
  85. feed_dict = {
  86. agent.reward_holder: episode_history[:, 2],
  87. agent.action_holder: episode_history[:, 1],
  88. agent.state_in: np.vstack(episode_history[:, 0])
  89. }
  90.  
  91. # 计算梯度
  92. grads = sess.run(agent.gradients, feed_dict=feed_dict)
  93.  
  94. for idx, grad in enumerate(grads):
  95. gradient_buffer[idx] += grad
  96.  
  97. if i % update_frequency == 0 and i != 0:
  98. feed_dict = dictionary = dict(zip(agent.gradient_holders, gradient_buffer))
  99.  
  100. # 应用梯度下降来更新参数
  101. _ = sess.run(agent.update_batch, feed_dict=feed_dict)
  102.  
  103. for index, grad in enumerate(gradient_buffer):
  104. gradient_buffer[index] = grad * 0
  105.  
  106. total_reward.append(episode_reward)
  107. break
  108.  
  109. # 每 50 回合打印平均奖励
  110. if i % 50 == 0:
  111. print("回合 {} - {} 的平均奖励: {}".format(i, i + 50, np.mean(total_reward[-50:])))
  112.  
  113. i += 1

启动训练:

会报一些警告,不用理会,训练到奖励大概有300分的时候,就比较稳定了,能较好的平衡杠子了

  还有另外一个游戏Mountain-car小游戏也可以基于策略梯度来做, 这个小游戏的说明见“基于核方法的强化学习算法-----何源,张文生”里面有一段说明了这个小游戏:

这个具体的实现下回继续。。。

策略梯度训练cartpole小游戏的更多相关文章

  1. 微信小游戏 RES版本控制+缓存策略 (resplugin和ResSplitPlugin插件使用)

    参考: RES版本控制 使用 AssetsManager 灵活定制微信小游戏的缓存策略 一.我们的目标 目标就是让玩家快速进入游戏,然后根据游戏的进度加载相应的资源,并可对资源进行版本控制.本地缓存. ...

  2. lecture6-mini批量梯度训练及三个加速的方法

    Hinton的第6课,这一课中最后的那个rmsprop,关于它的资料,相对较少,差不多除了Hinton提出,没论文的样子,各位大大可以在这上面研究研究啊. 一.mini-批量梯度下降概述 这部分将介绍 ...

  3. 强化学习(十三) 策略梯度(Policy Gradient)

    在前面讲到的DQN系列强化学习算法中,我们主要对价值函数进行了近似表示,基于价值来学习.这种Value Based强化学习方法在很多领域都得到比较好的应用,但是Value Based强化学习方法也有很 ...

  4. 强化学习_PolicyGradient(策略梯度)_代码解析

    使用策略梯度解决离散action space问题. 一.导入包,定义hyper parameter import gym import tensorflow as tf import numpy as ...

  5. 强化学习-学习笔记14 | 策略梯度中的 Baseline

    本篇笔记记录学习在 策略学习 中使用 Baseline,这样可以降低方差,让收敛更快. 14. 策略学习中的 Baseline 14.1 Baseline 推导 在策略学习中,我们使用策略网络 \(\ ...

  6. 软件工程 Android小游戏 猜拳大战

    一.前言 最近学校举办的大学生程序设计竞赛,自己利用课余时间写了一个小游戏,最近一直在忙这个写这个小游戏,参加比赛,最终是老师说自己写的简单,可以做的更复杂的点的.加油 二.内容简介 自己玩过Andr ...

  7. [安卓] 12、开源一个基于SurfaceView的飞行射击类小游戏

    前言  这款安卓小游戏是基于SurfaceView的飞行射击类游戏,采用Java来写,没有采用游戏引擎,注释详细,条理比较清晰,适合初学者了解游戏状态转化自动机和一些继承与封装的技巧. 效果展示    ...

  8. 2048小游戏代码解析 C语言版

    2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图:  游 ...

  9. C语言实现简易2048小游戏

    一直很喜欢玩这个小游戏,简单的游戏中包含运气与思考与策略,喜欢这种简约又不失内涵的游戏风格.于是萌生了用C语言实现一下的想法. 具体代码是模仿这个:https://www.cnblogs.com/ju ...

随机推荐

  1. Oracle Instant Client(即时客户端) 安装与配置

    一.下载 下载地址:http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html 这是Ora ...

  2. elemnt UI点击事件失效,得到tab的序号

    在用element 的tab的时候发现  事件绑定没有作用 看了官网才知到内置有回掉函数 绑定的地方是 <el-tabs></el-tabs> <template> ...

  3. zabbix实操随笔

    vmware 9.0安装,vmware tools安装 fedora 15.0安装1G内存以上fedora上基本操作指令1.vmtools 共享文件在linux上安装有问题,出现找不到**.so.1之 ...

  4. python函数默认参数为可变对象的理解

    1.代码在执行的过程中,遇到函数定义,初始化函数生成存储函数名,默认参数初识值,函数地址的函数对象. 2.代码执行不在初始化函数,而是直接执行函数体. 代码实例 这要从函数的特性说起,在 Python ...

  5. flink的流处理特性

    flink的流处理特性: 支持高吞吐.低延迟.高性能的流处理 支持带有事件时间的窗口(Window)操作 支持有状态计算的Exactly-once语义 支持高度灵活的窗口(Window)操作,支持基于 ...

  6. NOI2018Day2T1 屠龙勇士 set 扩展欧几里德 中国剩余定理

    原文链接https://www.cnblogs.com/zhouzhendong/p/NOI2018Day2T1.html 题目传送门 - 洛谷P4774 题意 题解 首先我们仔细看一看样例可以发现如 ...

  7. linux系统虚拟机下安装nginx基础

    虽然安装nginx什么的 .以及如何配置等等一系列的资料案例已经很多了 但是作为菜鸟的我还是搞了半天哈 官网上面也有.但是一些细节方面的并没有说明.导致踩了半天坑才搞好 本案例的系统环境     wi ...

  8. js面向对象实例

    JSON方式来编写对象简单 不适合多个对象 var json={a:12, show:function (){ alert(this); }};json.show(); //理所当然弹出的是objec ...

  9. Flume配置文件写法总结

    一.agent 第一步是定义agent(代理)及agent下的sources.channels.sinks的简称,如下: a1.sources = r1 a1.sinks = k1 a1.channe ...

  10. Scala-Unit7-Scala并发编程模型AKKA

    一.Akka简介 Akka时spark的底层通信框架,Hadoop的底层通信框架时rpc. 并发的程序编写很难,但是Akka解决了spark的这个问题. Akka构建在JVM平台上,是一种高并发.分布 ...