1. Gym介绍 Gym是一个研究和开发强化学习相关算法的仿真平台,无需智能体先验知识,由以下两部分组成
- Gym开源库:测试问题的集合。当你测试强化学习的时候,测试问题就是环境,比如机器人玩游戏,环境的集合就是游戏的画面。这些环境有一个公共的接口,允许用户设计通用的算法。
- OpenAI Gym服务:提供一个站点和API(比如经典控制问题:CartPole-v0),允许用户对他们的测试结果进行比较。
pip install gym
如果需要从源码安装gym,那么可以:
git clone https://github.com/openai/gym
cd gym
pip install -e .
可以运行pip install -e .[all]执行包含所有环境的完整安装。 这需要安装一些依赖包,包括cmake和最新的pip版本。
3. Gym使用demo 简单来说OpenAI Gym提供了许多问题和环境(或游戏)的接口,而用户无需过多了解游戏的内部实现,通过简单地调用就可以用来测试和仿真。接下来以经典控制问题CartPole-v0为例,简单了解一下Gym的特点
# 导入gym环境
import gym
# 声明所使用的环境
env = gym.make('CartPole-v0')
# 环境初始化
env.reset()# 对环境进行迭代执行1000次
for _ in range(1000):
env.render()
observation, reward, done, info = env.step(env.action_space.sample()) # 采取随机动作
if done:
env.reset()
env.close()
运行效果如下
以上代码中可以看出,gym的核心接口是Env。作为统一的环境接口,Env包含下面几个核心方法:
- reset(self):重置环境的状态,返回观察。
- step(self, action):推进一个时间步长,返回observation, reward, done, info。
- render(self, mode=‘human’, close=False):重绘环境的一帧。默认模式一般比较友好,如弹出一个窗口。
- close(self):关闭环境,并清除内存
4、观测(Observations) 在上面代码中使用了env.step()函数来对每一步进行仿真,在Gym中,env.step()会返回 4 个参数:
- 观测 Observation (Object):当前step执行后,环境的观测(类型为对象)。例如,从相机获取的像素点,机器人各个关节的角度或棋盘游戏当前的状态等;
- 奖励 Reward (Float): 执行上一步动作(action)后,智能体( agent)获得的奖励(浮点类型),不同的环境中奖励值变化范围也不相同,但是强化学习的目标就是使得总奖励值最大;
- 完成 Done (Boolen): 表示是否需要将环境重置 env.reset。大多数情况下,当 Done 为True 时,就表明当前回合(episode)或者试验(tial)结束。例如当机器人摔倒或者掉出台面,就应当终止当前回合进行重置(reset);
- 信息 Info (Dict): 针对调试过程的诊断信息。在标准的智体仿真评估当中不会使用到这个info,具体用到的时候再说。
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
env.close()
代码运行结果的片段如下所示:
[ 0.04025062 -0.043126490.001863480.02288173]
[ 0.03938809 -0.238275120.002321110.31615203]
[ 0.03462259 -0.433430050.008644160.60956605]
[ 0.02595398 -0.238430.020835480.31961824]
[ 0.02118538 -0.433842390.027227840.6187984 ]
[ 0.01250854 -0.239111130.039603810.33481376]
[ 0.00772631 -0.434773690.046300080.63971794]
[-0.00096916 -0.630509540.059094440.94661444]
[-0.01357935 -0.436231070.078026730.67306909]
[-0.02230397 -0.242275380.091488110.40593731]
[-0.02714948 -0.438567520.099606860.72600415]
[-0.03592083 -0.244953610.114126940.46625881]
[-0.0408199-0.051613540.123452120.21161588]
[-0.041852170.141546930.12768444 -0.03971694]
[-0.03902123 -0.055152790.12689010.29036807]
[-0.04012429 -0.251834180.132697460.6202239 ]
[-0.04516097 -0.058790650.145101940.37210296]
[-0.046336790.134004010.1525440.12846047]
[-0.04365671 -0.062936690.155113210.46511532]
[-0.04491544 -0.259871150.164415510.80239106]
[-0.05011286 -0.456819920.180463331.14195086]
[-0.05924926 -0.653781520.203302351.48536419]
Episode finished after 22 timesteps
上面的结果可以看到这个迭代中,输出的观测为一个列表。这是CartPole环境特有的状态,其规则是。
其中:
- 表示小车在轨道上的位置(position of the cart on the track)
- 表示杆子与竖直方向的夹角(angle of the pole with the vertical)
- 表示小车速度(cart velocity)
- 表示角度变化率(rate of change of the angle)
import gym
env = gym.make('CartPole-v0')
print(env.action_space)
print(env.observation_space)
Discrete(2)
Box(-3.4028234663852886e+38, 3.4028234663852886e+38, (4,), float32)
从程序运行结果可以看出:
- action_space 是一个离散Discrete类型,从discrete.py源码可知,范围是一个{0,1,…,n-1} 长度为 n 的非负整数集合,在CartPole-v0例子中,动作空间表示为{0,1}。
- observation_space 是一个Box类型,从box.py源码可知,表示一个 n 维的盒子,所以在上一节打印出来的observation是一个长度为 4 的数组。数组中的每个元素都具有上下界。
7. 注册表 Gym是一个包含各种各样强化学习仿真环境的大集合,并且封装成通用的接口暴露给用户,查看所有环境的代码如下
from gym import envs
print(envs.registry.all())
8.注册模拟器 Gym支持将用户制作的环境写入到注册表中,需要执行 gym.make()和在启动时注册register。如果要注册自己的环境,那么假设你在以下结构中定义了自己的环境:
myenv/
__init__.py
myenv.py
i. myenv.py
包含适用于我们自己的环境的类。 在
init.py中,输入以下代码:from gym.envs.registration import register
register(
id='MyEnv-v0',
entry_point='myenv.myenv:MyEnv', # 第一个myenv是文件夹名字,第二个myenv是文件名字,MyEnv是文件内类的名字
)
ii. 要使用我们自己的环境:
import gym
import myenv # 一定记得导入自己的环境,这是很容易忽略的一点
env = gym.make('MyEnv-v0')
iii. 在PYTHONPATH中安装
myenv
目录或从父目录启动python。目录结构:
myenv/
__init__.py
my_hotter_colder.py
-------------------
__init__.py 文件:
-------------------
from gym.envs.registration import register
register(
id='MyHotterColder-v0',
entry_point='myenv.my_hotter_colder:MyHotterColder',
)
-------------------
my_hotter_colder.py文件:
-------------------
import gym
from gym import spaces
from gym.utils import seeding
import numpy as npclass MyHotterColder(gym.Env):
"""Hotter Colder
The goal of hotter colder is to guess closer to a randomly selected numberAfter each step the agent receives an observation of:
0 - No guess yet submitted (only after reset)
1 - Guess is lower than the target
2 - Guess is equal to the target
3 - Guess is higher than the targetThe rewards is calculated as:
(min(action, self.number) + self.range) / (max(action, self.number) + self.range)Ideally an agent will be able to recognise the 'scent' of a higher reward and
increase the rate in which is guesses in that direction until the reward reaches
its maximum
"""
def __init__(self):
self.range = 1000# +/- value the randomly select number can be between
self.bounds = 2000# Action space boundsself.action_space = spaces.Box(low=np.array([-self.bounds]), high=np.array([self.bounds]))
self.observation_space = spaces.Discrete(4)self.number = 0
self.guess_count = 0
self.guess_max = 200
self.observation = 0self.seed()
self.reset()def seed(self, seed=None):
self.np_random, seed = seeding.np_random(seed)
return [seed]def step(self, action):
assert self.action_space.contains(action)if action < self.number:
self.observation = 1elif action == self.number:
self.observation = 2elif action > self.number:
self.observation = 3reward = ((min(action, self.number) + self.bounds) / (max(action, self.number) + self.bounds)) ** 2self.guess_count += 1
done = self.guess_count >= self.guess_maxreturn self.observation, reward[0], done, {"number": self.number, "guesses": self.guess_count}def reset(self):
self.number = self.np_random.uniform(-self.range, self.range)
self.guess_count = 0
self.observation = 0
return self.observation
9. OpenAI Gym评估平台 用户可以记录和上传算法在环境中的表现或者上传自己模型的Gist,生成评估报告,还能录制模型玩游戏的小视频。在每个环境下都有一个排行榜,用来比较大家的模型表现。
上传于录制方法如下所示
import gym
from gym import wrappers
env = gym.make('CartPole-v0')
env = wrappers.Monitor(env, '/tmp/cartpole-experiment-1')
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
使用Monitor Wrapper包装自己的环境,在自己定义的路径下将记录自己模型的性能。支持将一个环境下的不同模型性能写在同一个路径下。
在官网注册账号后,可以在个人页面上看到自己的API_Key,接下来可以将结果上传至OpenAI Gym:
import gym
gym.upload('/tmp/cartpole-experiment-1', api_key='YOUR_API_KEY')
然后得到如下结果:
打开链接会有当前模型在环境下的评估报告,并且还录制了小视频:
每次上传结果,OpenAI Gym都会对其进行评估。
创建一个Github Gist将结果上传,或者直接在upload时传入参数:
import gym
gym.upload('/tmp/cartpole-experiment-1', writeup='https://gist.github.com/gdb/b6365e79be6052e7531e7ba6ea8caf23', api_key='YOUR_API_KEY')
评估将自动计算得分,并生成一个漂亮的页面。
在大多数环境中,我们的目标是尽量减少达到阈值级别的性能所需的步骤数。不同的环境都有不同的阈值,在某些环境下,尚不清楚该阈值是什么,此时目标是使最终的表现最大化。在cartpole这个环境中,阈值就是立杆能够直立的帧数。
【自动驾驶|强化学习基础篇 OpenAI Gym 环境搭建demo】如上述博客有任何错误或者疑问,请加VX:1755337994,及时告知!万分感激!
推荐阅读
- 人工智能|我的天,强化学习还能用在自动驾驶领域()
- 自动驾驶|自动驾驶 java_深入浅出自动驾驶(一)-图像识别
- 前沿技术|深度学习框架中的自动微分及高阶导数
- 深度学习|二、机器学习基础13(熵、信息增益、剪枝处理、SVM)
- 深度学习|二、机器学习基础14(核函数)
- 深度学习|二、机器学习基础15(SVM优缺点、聚类与降维)
- 计算机视觉|计算机视觉(十二)(Tensorflow常用功能模块)
- Python|Python / Pytorch / Tensorflow / Keras / Matlab / 相关库 积累——持更
- 学科竞赛|2021电赛F题数字识别和巡线部分