OpenAI Gym是开发和比较强化学习算法的工具包。
强化学习关注的是做出好决策,而监督式学习和非监督式学习主要关注的是做出预测。
强化学习有两个基本概念:环境(即外部世界)和智能体(即你正在编写的算法)。智能体向环境发送行为,环境回复观察和奖励(即分数)。
OpenAI Gym由两部分组成:
1.gym开源库:一个测试问题集合—环境(environment),可以用于自己的强化学习算法开发,这些环境有共享的接口,允许用户设计通用的算法
2.OpenAI Gym服务: 一个站点和API,允许用户对他们训练的算法进行性能比较。
运行一个环境来体验一下OpenAI Gym
Cart-Pole世界包括一个沿水平轴移动的车和一个固定在车上的杆子。 在每个时间步,你可以观察它的位置(x),速度(x_dot),角度(theta)和角速度(theta_dot)。 这是这个世界的可观察的状态。 在任何状态下,车只有两种可能的行动:向左移动或向右移动。
换句话说,Cart-Pole的状态空间有四个维度的连续值,行动空间有一个维度的两个离散值。
运行一个CartPole-v0环境的实例1000步,在每一步渲染环境。 你会看到一个弹出的窗口,呈现出经典的倒立摆问题:
import gym env = gym.make('CartPole-v0') env.reset() for _ in range(1000): env.render() env.step(env.action_space.sample()) # take a random action
其中env.reset()重置环境的状态,env.render()重绘环境的一帧。
观察
如果我们想要在每一步中做出比随机更好的行动,那么实际了解我们的行动会对环境有什么样的影响可能会很好。
环境的step函数会返回我们需要的信息。step函数返回四个值,下面是具体信息:
- observation (object):一个与环境相关的对象描述你观察到的环境,如相机的像素信息,机器人的角度和角速度,棋盘游戏中的棋盘状态。
- reward (float):先前行为获得的所有回报之和,不同环境的计算方式不同,但目标一直是增加你的总回报。
- done (boolean): 判断是否到了重新设定(reset)环境的时候,大多数任务分为明确定义的episodes,并且done为True表示episode已终止。
- info (dict):用于调试的诊断信息。有时对学习也很有用(例如,它可能包含在环境最后一个状态改变后的原始概率)。但对智能体的正式评估不允许使用该信息进行学习。
该进程通过调用reset来启动,它返回一个初始observation。 所以编写上面代码的更恰当的方法是遵守done的标志:
import gym env = gym.make('CartPole-v0') for i_episode in range(20): observation = env.reset() for t in range(100): env.render() print(observation) action = env.action_space.sample() observation, reward, done, info = env.step(action) if done: print("Episode finished after {} timesteps".format(t+1)) break当done 为真时,控制失败,此阶段episode 结束。可以计算每 episode 的回报就是其坚持的t+1 时间,坚持的越久回报越大,在上面算法中,agent 的行为选择是随机的,平均回报为20 左右。
空间
在上面的例子中,我们已经从环境的动作空间中采样随机行动。但这些行动究竟是什么呢? 每个环境都带有描述有效动作和观察的一级Space对象:
import gym
env = gym.make('CartPole-v0')
print(env.action_space)
#> Discrete(2)
print(env.observation_space)
#> Box(4,)
Discrete空间允许固定范围的非负数,因此在这个例子中,有效的actions是0或1。Box空间表示一个n维框,所以有效的observations是4个数字的数组。 我们也可以检查Box's的范围:
print(env.observation_space.high)
#> array([ 2.4 , inf, 0.20943951, inf])
print(env.observation_space.low)
#> array([-2.4 , -inf, -0.20943951, -inf])
这种反省对编写适用于许多不同环境的通用代码很有帮助。Box和Discrete是最常用的Spaces,可以从space进行抽样或检查属于它的内容:
from gym import spaces
space = spaces.Discrete(8) # Set with 8 elements {0, 1, 2, ..., 7}
x = space.sample()
assert space.contains(x)
assert space.n == 8
对CartPole-v0,其中一个行动会向左施加力,其中一个向右施加力。
幸运的是,你的学习算法越好,你自己就越不需要尝试去解释这些数字。
环境
gym主要目的是提供一个大的环境集合,暴露一个通用接口,并进行版本控制来比较,你可以查看系统提供环境:
from gym import envs
print(envs.registry.all())
#> [EnvSpec(DoubleDunk-v0), EnvSpec(InvertedDoublePendulum-v0), EnvSpec(BeamRider-v0), EnvSpec(Phoenix-ram-v0), EnvSpec(Asterix-v0), EnvSpec(TimePilot-v0), EnvSpec(Alien-v0), EnvSpec(Robotank-ram-v0), EnvSpec(CartPole-v0), EnvSpec(Berzerk-v0), EnvSpec(Berzerk-ram-v0), EnvSpec(Gopher-ram-v0), ...
找到最佳的策略
在Cart-Pole环境下,只要杆子还是挺直的,车还在边界内,你就可以获得奖励。 一旦杆子超过某个角度,或者车子向左或向右偏离太远,游戏就会结束。 当它连续100次直立超过195个时间步,这个问题被认为解决了,
一个策略就是你在特定状态下所采取的行动。 在这里,你想找到可以最大化你的奖励的策略。 换句话说,你想为每个可能的状态找到最佳政策。
Q-Learning
Q-Learning就是找到这些最优策略的一种方法。本质上,通过试错法,你可以找到每个状态-行动对的Q值。 这个Q值表示在当前状态下一个行动的可取性。 随着时间的推移,如果世界是静态的(即物理或因果不变),则Q值会收敛,给定状态的最优策略将是具有最大Q值的行动。
要使用Q-Learning,您必须将连续维度离散到多个桶。 一般来说,你想要有更少的桶,并保持尽可能小的状态空间。 找到更少的最优政策意味着更快的训练。 然而,将状态空间过于粗糙地离散化可能会阻止收敛,因为重要的信息可能会被离散化。
DQN(Deep Q Network)
参考:
https://gym.openai.com/docs/
https://medium.com/@tuzzer/cart-pole-balancing-with-q-learning-b54c6068d947
http://mnemstudio.org/path-finding-q-learning-tutorial.html
https://zhuanlan.zhihu.com/p/21477488?refer=intelligentunit