http://chenrudan.github.io/blog/2016/09/04/cartpole.html

  • 首页
  • 分类
  • 关于
  • 归档
  • 标签

基于Policy Gradient实现CartPole

 发表于 2016-09-04 |  分类于 code |  |  2700

8月的时候把David silver的强化学习课上了,但是一直对其中概念如何映射到现实问题中不理解,半个月前突然发现OpenAI提供了一个python库Gym,它创造了强化学习的environment,可以很方便的启动一个强化学习任务来自己实现算法,并且提供了不少可以解决的问题来练手。本文针对如何解决入门问题CartPole,来解释一下怎么将之前课上的算法转化成实现代码。

【转载请注明出处】chenrudan.github.io

8月的时候把David silver的强化学习课上了,但是一直对其中概念如何映射到现实问题中不理解,半个月前突然发现OpenAI提供了一个python库Gym,它创造了强化学习的environment,可以很方便的启动一个强化学习任务来自己实现算法(新智元OpenAI简介[1]),并且提供了不少可以解决的问题来练手https://openai.com/requests-for-research/。本文针对如何解决入门问题CartPole,来解释一下怎么将之前课上的算法转化成实现代码。这里强烈推荐一下官网的教程http://kvfrans.com/simple-algoritms-for-solving-cartpole/,因为这个作者只是个高中生T^T…

建了一个强化学习讨论qq群,有兴趣的可以加一下群号595176373或者扫描下面的二维码。

1. Gym库

它提供了一些函数接口,模拟了强化学习问题中environment,当向它传递一个动作,它相应会返回执行这个动作后的状态、奖赏等。

1
2
3
4
#启动某种环境
env = gym.make('CartPole-v0')
#针对传进来的动作返回状态observation等
observation, reward, done, info = env.step(action)

执行pip install gym即可安装,https://gym.openai.com/docs中有实例,复制代码运行即可检查是否安装成功。此外提供了env.monitor来记录下算法执行过程,它会保存为.mp4文件,然后上传到OpenAI网站上可以检查执行效率,上传可以通过执行代码中加入api_key(鉴别用户),我是直接把api_key写入了~/.bashrc文件中即”export OPENAI_GYM_API_KEY=”。

2. CartPole问题

CartPole的玩法如下动图所示,目标就是保持一根杆一直竖直朝上,杆由于重力原因会一直倾斜,当杆倾斜到一定程度就会倒下,此时需要朝左或者右移动杆保证它不会倒下来。我们执行一个动作,动作取值为0或1,代表向左或向右移动,返回的observation是一个四维向量,reward值一直是1,当杆倒下时done的取值为False,其他为True,info是调试信息打印为空具体使用暂时不清楚。如果杆竖直向上的时间越长,得到reward的次数就越多。

1
2
3
4
#从动作空间中采样一个动作
action = env.action_space.sample()
observation, reward, done, info = env.step(action)
print observation

结果是[-0.061586 -0.75893141 0.05793238 1.15547541]。

图1 CartPole示意图

3. 三种解法

目的是在不同状态下执行出合适的action,代码中要做的就是替换掉采样这一行,用policy来决定执行什么动作。也就是说此处需要决定policy的形式,官网给出了两种思路,已知policy的输入是当前所处的状态observation,输出是action的取值即0 or 1,observation是一个四维向量,如果对这个向量求它的加权和,就可以得到一个值,那么就可以根据加权和的符号来决定action,同样可以用sigmoid函数当成二分类问题。基于这两种policy可以得到下面三种解法,核心就在于通过改变加权的权重值就能改变policy。

3.1 Random Guessing Algorithm & Hill Climbing Algorithm

由于policy中权重也是一个四维向量,如果随机给四维向量赋值,有机会得到比较好的policy。首先先实现一个函数用来衡量给定的某组权重效果如何,函数返回值是这组权重下得到的奖赏,意义是杆维持了多长时间未倒下,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def evaluate_given_parameter_by_sign(env, weight):
#启动初始状态
observation = env.reset()
#这组参数返回的总reward
total_reward = 0.
for t in range(1000):
#这个渲染函数就是实时展示图1,如果隐藏,代码正常执行,但是不会显示图1了
env.render()
weighted_sum = np.dot(weight, observation)
#根据符号policy选出action
if weighted_sum >= 0:
action = 1
else:
action = 0
observation, reward, done, info = env.step(action)
total_reward += reward
if done:
break
return total_reward

然后要改变权重,这里试验了两种方法,一种是random guess,即随机给四维权重weight赋值,一种是hill climbing,即给当前最好的权重加上一组随机值,如果加上这组值持续时间变长了那么就更新最好的权重,如果没有变的更好就不更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def random_guess():
env = gym.make('CartPole-v0')
np.random.seed(10)
best_reward = -100.0
for iiter in xrange(1000):
#####random guess随机初始化权重weight####
weight = np.random.rand(4)
#####
####hill climbing给best weight加随机值
weight = best_weight + np.random.normal(0, 0.01, 4)
#####
cur_reward = evaluate_given_parameter_by_sign(env, weight)
if cur_reward > best_reward:
best_reward = cur_reward
best_weight = weight
if best_reward == 1000:
break
print("XXX algorithm best reward", best_reward)
print("XXX algorithm best weight", best_weight)
3.2 Policy Gradient

上面的两种方法都是在随机的改变权重,针对这种参数非常少的情况确实能得到不错的效果,但是一旦参数数目增多,这种方式耗时非常大,一点也不实用。而第七课[2]讲解了两种Policy Gradient的方法,分别是Monte-Carlo Policy Gradient和Actor-Critic Policy Gradient。我们知道衡量policy好坏有三种方法,一是在某个状态下和该policy作用下能获得的值函数值,一是该policy作用下能获得的所有状态的期望值函数,一是在该policy作用下能获得的所有状态的期望immdiate reward,并且推导出了这三种方法的统一导数形式,即衡量policy的目标函数导数为▽θJ(θ)=Eπθ[▽θlogπθ(s,a)Qπθ(s,a)]▽θJ(θ)=Eπθ[▽θlogπθ(s,a)Qπθ(s,a)],这个式子也就是policy gradient。

根据题目的意思,此处的policy换成逻辑回归,即πθ(s,a)=11+e−wxπθ(s,a)=11+e−wx那么式子中▽θlogπθ(s,a)=(1−pi)∗(−x)▽θlogπθ(s,a)=(1−pi)∗(−x)。在第一种方法中用直接用immdiate reward代替Qπθ(s,a)Qπθ(s,a),所以在本例中就是直接取1。

首先定义一下选择action的函数,也就是利用sigmoid函数进行二分类。

1
2
3
4
5
6
7
8
def choose_action(weight, observation):
weighted_sum = np.dot(weight, observation)
pi = 1 / (1 + np.exp(-weighted_sum))
if pi > 0.5:
action = 1
else:
action = 0
return pi, action

由于Monte-Carlo方法中需要先基于某组参数算出一个episode,再基于这个episode来更新policy的参数,所以需要实现一个函数产生一个episode。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def generate_episode(env, weight):
episode = []
pre_observation = env.reset()
t = 0
#generate 1 episodes for training.
while 1:
#env.render()
pi, action = choose_action(weight, pre_observation)
observation, reward, done, info = env.step(action)
#将这个episode的每一步产生的数据保存下来
episode.append([pre_observation, action, pi, reward])
pre_observation = observation
t += 1
if done or t > 1000:
break
return episode

从而可以实现第七课中Monte-Carlo的更新方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def monte_carlo_policy_gradient(env):
learning_rate = -0.0001
best_reward = -100.0
weight = np.random.rand(4)
for iiter in xrange(1000):
cur_episode = generate_episode(env, weight)
for t in range(len(cur_episode)):
observation, action, pi, reward = cur_episode[t]
#根据第七课的更新公式
weight += learning_rate*(1-pi)*np.transpose(-observation)*reward
#衡量算出来的weight表现如何
cur_reward = evaluate_given_parameter_sigmoid(env, weight)
print 'Monte-Carlo policy gradient get reward', cur_reward

而针对Actor critic的方法,则是把值函数Qπθ(s,a)Qπθ(s,a)也当成observation的含参函数,且直接把observation的加权和当成值函数的取值,那么也就能由第七课的更新公式来同时更新值函数和policy的参数。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def actor_critic_policy_gradient(env):
gamma = 1
p_weight = np.random.rand(4)
#值函数的权重
v_weight = np.random.rand(4)
p_learning_rate = -0.0001
v_learning_rate = -0.0001
done = True
for iiter in xrange(1000):
t = 0
while 1:
if done:
print 'start new training...'
print 'p_weight', p_weight
print 'v_weight', v_weight
pre_observation = env.reset()
pre_pi, pre_action = choose_action(p_weight, pre_observation)
pre_phi = pre_observation
pre_q = np.dot(v_weight, pre_phi)
#env.render()
observation, reward, done, info = env.step(pre_action)
pi, action = choose_action(p_weight, observation)
phi = observation
q = np.dot(v_weight, phi)
delta = reward + gamma*q - pre_q
p_weight += p_learning_rate*(1-pre_pi)*np.transpose(-pre_observation)*pre_q
v_weight += v_learning_rate*delta*np.transpose(pre_phi)
pre_pi = pi
pre_observation = observation
pre_q = q
pre_phi = phi
pre_action = action
t += 1
if done:
break
cur_reward = evaluate_given_parameter_sigmoid(env, p_weight)
print 'Actor critic policy gradient get reward', cur_reward

4.提交到OpenAI

上面的代码实现以后,就能够提交到OpenAI的网站上去评估效果如何,首先加上两行代码,变成下面的样子。

1
2
3
4
env = gym.make('CartPole-v0')
env.monitor.start('cartpole-hill/', force=True)
actor_critic_policy_gradient(env)
env.monitor.close()

这会将训练过程记录下来生成.mp4文件,如果像我这样将api_key写入~/.bashrc,就可以直接执行下面代码提交给OpenAI。

1
gym.upload('cartpole-hill')

最后在网站上就能看到如下的结果。

图2 结果提交成功图

5.小结

我的policy gradient是完全按照第七课的内容实现的,但是实际上效果还不够好,并且非常依赖初始值,初始值好就很快收敛,不好就会一直恶性循环。总之感觉这个网站还是很有意思的,值得去玩一玩,文中的代码在这里。

[1] 【重磅】马斯克的AI野心——OpenAI Gym系统深度解析

[2] 【David Silver强化学习公开课之七】Policy Gradient

转载于:https://www.cnblogs.com/jukan/p/7772231.html

基于Policy Gradient实现CartPole相关推荐

  1. 策略梯度模型 (Policy Gradient)原理与实现

    作者:陆平 1. 智能体与环境 策略梯度(Policy Gradient)模型是强化学习中的一个经典基础模型.它用来在某种环境下训练智能体.对于一些简单场景,我们可以把智能体与环境及关系抽象为: 智能 ...

  2. pytorch笔记:policy gradient

    本文参考了 策略梯度PG( Policy Gradient) 的pytorch代码实现示例 cart-pole游戏_李莹斌XJTU的博客-CSDN博客_策略梯度pytorch 在其基础上添加了注释和自 ...

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

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

  4. Policy-based RL小结(Policy Gradient ; Natural policy gradient ;TRPO;ACKTR;PPO )

    文章目录 Policy-based RL 前言 1. 预备知识 1.1 策略类型 1.2 策略优化的目标函数 1.2.1 可结束的环境的目标函数 1.2.3 连续动作环境的目标函数 1.2.4 实际的 ...

  5. 强化学习6——Policy-based RL(MC policy gradient)

    文章目录 Policy-based RL 思路 特点 解决噪声问题 use temporal causality include a baseline 方法 MC policy gradient Po ...

  6. 强化学习-Vanilla Policy Gradient(VPG)

    文章目录 Background Quick Facts Key Equations Exploration vs. Exploitation Pseudocode Documentation Refe ...

  7. 【强化学习】Policy Gradient原理

    1.Policy Gradient和DQN系列强化算法最大的区别在于: DQN系列基于Value,也就是说执行完所有的动作并保存所得到的价值,根据这些价值计算出最优价值函数,并以此选择动作,最终获得一 ...

  8. 深度强化学习-Policy Gradient基本实现

    全文共2543个字,2张图,预计阅读时间15分钟. 基于值的强化学习算法的基本思想是根据当前的状态,计算采取每个动作的价值,然后根据价值贪心的选择动作.如果我们省略中间的步骤,即直接根据当前的状态来选 ...

  9. 系统学习深度学习(三十五)--策略梯度(Policy Gradient)

    转自:https://www.cnblogs.com/pinard/p/10137696.html 在前面讲到的DQN系列强化学习算法中,我们主要对价值函数进行了近似表示,基于价值来学习.这种Valu ...

最新文章

  1. Linux下用iptables做端口映射
  2. 树莓派:一个关于教育的故事
  3. chart 模板 - 每天5分钟玩转 Docker 容器技术(165)
  4. 大战设计模式【13】—— 组合模式
  5. Git 内部原理图解——对象、分支以及如何从零开始建仓库
  6. 少儿编程100讲轻松学python(十七)-pycharm如何配置python环境
  7. 云漫圈 | 什么是字符串匹配算法?
  8. Linux+c+线程的属性,C ++中的多线程
  9. JDBC的第一个版本,不使用配置文件。使用jar文件一个
  10. 520特辑丨码神VS爱神:盘点程序员的四大男友力,你偏爱哪一种?
  11. 数据库ACID、脏读、不可重复读和幻读
  12. python兔子编程_少儿编程分享:手把手教你用Python编写兔獾大作战(完)
  13. 表带可作为显示操作装置
  14. [SQL优化工具]Quest.Central.For.Databases——SQL Tuning for SQL Server
  15. Windows 11 LTSC 数字激活方法/HEU KMS Activator 数字激活/LTSC公key激活
  16. 什么是fat jar?
  17. 氨氮吹脱法脱与php有关系吗,吹脱法处理氨氮废水
  18. 清华大学计算机系上机考试,清华大学计算机系图形学考试习题.docx
  19. 中标麒麟网络配置详解
  20. WhatsApp发布安卓手表客户端 手表聊天时代来了

热门文章

  1. OpenCV 加载图像、转换图像和保存图像
  2. C++ 判断两个立方体是否相等
  3. Python调用PyAutoGUI模块
  4. tp设置打印机虚拟服务器,tp打印机服务器设置
  5. IDEA配置自定义maven库
  6. POJ 1661 Help Jimmy DP
  7. 4-1 复数类的运算符重载
  8. 软件测试学习笔记:找代码中的fault,并设计特定的测试用例
  9. 「洛谷P1343」地震逃生 解题报告
  10. Springboot-添加对jsp支持