OpenAI Gym 源码阅读:创建自定义强化学习环境

Gym 介绍

Gym 是一套开发强化学习算法的工具箱,包含了一系列内置的环境,结合强化学习算法就可以对内置的环境进行求解。

例如,调用 CartPole-v0 环境的示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
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()

Gym 仿真主要包括

  • 导入环境 gym.make('CartPole-v0')
  • 初始化环境 env.reset(),将强化学习环境设置为初始状态
  • 一步仿真 env.step(action),输入动作,获得环境反馈
  • 渲染可视化当前状态 env.render()

虽然 Gym 内置了大量强化学习环境,如果想训练自定义的强化学习问题,就必须要创建自定义的强化学习环境。

源码解析

根据上一节的 Gym 主要函数调用接口,CartPoleEnv 继承了基类 gym.Env,里面定义了主要的 API 方法

  • step
  • reset
  • render
  • close
  • seed

创建了自定义的环境,需要由 gym/envs/init.py 进行注册,注册 id 名,指定路径 gym.envs.classic_control:CartPoleEnv 和其他参数。

1
2
3
4
5
6
7
8
from gym.envs.registration import registry, register, make, spec

register(
id='CartPole-v0',
entry_point='gym.envs.classic_control:CartPoleEnv',
max_episode_steps=200,
reward_threshold=195.0,
)

gym/envs/registration.py 实例化了 1 个全局的 registry = EnvRegistry()

1
2
# Have a global registry
registry = EnvRegistry()

gym/envs/registration.py 中根据 entry_point 实例化环境 env

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def make(self, **kwargs):
"""Instantiates an instance of the environment with appropriate kwargs"""
if self.entry_point is None:
raise error.Error('Attempting to make deprecated env {}. (HINT: is there a newer registered version of this env?)'.format(self.id))
_kwargs = self._kwargs.copy()
_kwargs.update(kwargs)
if callable(self.entry_point):
env = self.entry_point(**_kwargs)
else:
cls = load(self.entry_point)
env = cls(**_kwargs)

# Make the enviroment aware of which spec it came from.
env.unwrapped.spec = self

return env

所以,总结一下,如果希望导入自定义环境的话,只需要在自定义的 package 中注册 id,并指定自定义 Env 类的路径

1
2
3
4
5
6
from gym.envs.registration import register

register(
id='custom-env-name',
entry_point='path.to:CusEnvClassName',
)

然后调用 gym.make('custom-env-name') 就能导入自定义的环境

创建自定义环境

根据上面注册环境的流程分析,可知,要引入自定义环境,不必改动 Gym 的源码,只需创建一个 Python 模块 即可。目录结构解释如下

为了方便调试调用,以 pip install -e . 安装自定义模块。测试代码中,引入模块时,即可将自定义环境注册到 Gym 环境中。

1
2
3
import gym
import gym_foo
env = gym.make('foo-v0')

自定义环境模块参考代码

参考