创建自定义 OpenAI Gym 强化学习环境的方法

已关闭留言

最近几天在写论文的实验,由于用到了强化学习,所以想写成 OpenAI Gym 那样的环境,或者至少是类似的。这样之后调用强化学习算法的时候也简单一些,不需要做太多的修改。当然,核心的网络部分以及输入输出等还是需要自己来写或者修改的。目前老唐是按照 OpenAI Gym 的风格来写的,包括了有哪些类、函数等,感觉这样写起来思路比较清晰。但是具体操作的时候并没有注册到 OpenAI Gym,这还是看各自具体需求。

本文基本是转载,原文参考《在openai/gym中使用自己的环境》。下面的代码只是给了一个框架,大家根据自己的需求进行修改。

文章目录
隐藏
一、构建自己的 OpenAI Gym 环境
二、注册强化学习环境
三、简化的 OpenAI Gym 风格代码

一、构建自己的 OpenAI Gym 环境

Gym 是 OpenAI 推出的强化学习框架,它提供了丰富的接口给开发者使用,再结合其开源的常见算法实现 openai/baselines,能够使开发者方便地将各种强化学习算法应用到自己的需求中。

环境是强化学习算法中的重要一环,环境如何对 Agent 的动作进行反馈,即 State 和 Reward 的更新,直接影响了 Agent 后续的动作。因此,针对不同的需求,我们需要定义自己的环境。下面就主要介绍如何在 OpenAI Gym 中使用自己的环境。其实这也是老唐这么多年感觉最繁琐的一部分,就是构建环境。

首先需要定义自己的环境 myenv.py,其代码框架如下:

from gym import spaces, core

 # core.Env 是 gym 的环境基类,自定义的环境就是根据自己的需要重写其中的方法;
 # 必须要重写的方法有: 
 # __init__():构造函数
 # reset():初始化环境
 # step():环境动作,即环境对agent的反馈
 # render():如果要进行可视化则实现

class MyEnv(core.Env):
	def __init__(self):
		self.action_space = spaces.Box(low=-1, high=1, shape=(1, )) # 动作空间
		self.observation_space =  spaces.Box(low=-1, high=1, shape=(1, )) # 状态空间
		# 其他成员
	
	def reset(self):
		...
		obs = self._get_observation()
		return obs
	
	def step(self, action):
		...
		reward = self._get_reward()
		done = self._get_done()
		obs = self._get_observation(action)
		info = {} # 用于记录训练过程中的环境信息,便于观察训练状态
		return obs, reward, done, info
	
	# 根据需要设计相关辅助函数
	def _get_observation(self, action):
		...
		return obs
	
	def _get_reward(self):
		...
		return reward

	def _get_done(self):
		...
		return done

二、注册强化学习环境

定义好自己的环境后,必须将其注册到 Gym 中去,才能使用。下面介绍如何注册环境。

首先建立一个文件夹 env,将定义好的环境 myenv.py 放入其中,并在该目录下再新建一个文件 __init__.py,文件内容如下:

from gym.envs.registration import register

register(
	id = 'env_name-v0' # 环境名,版本号v0必须有
	entry_point = 'env.myenv:MyEnv' # 文件夹名.文件名:类名
	# 根据需要定义其他参数
)

注意,entry_point 的路径一定要在 sys.path 中,以便你在注册环境时,gym 能够找到,如果该路径不在系统路径中,则会报错。

上一步完成后,有两种方法完成环境的注册:

方法一:(较为方便,推荐)

在定义环境的 py 文件中加上:

import env # 上一步的文件夹名

例如:

import gym
import env

env = gym.make('env_name-v0') # 参数为环境的 id

obs = env.reset()

for i in range(1000):
	action = agent(obs)
	obs, reward, done, info = env.step(action)
	if done:
		break

若使用 openai/baselines,即在 baselines/common/cmd_util.py 文件中加上这一句。

若这一步之后,在添加环境时找不到相应的包,那就是因为 gym 找不到 entry_point 的路径,则需要在添加环境的 py 文件中:

import sys
sys.path.append('./')  # 此时假设此 py 文件和 env 文件夹在同一目录下

import env  # 一定要在 sys.path.append() 之后

方法二:

进入 gym/envs 在本地的安装目录,比如我的是 /usr/local/miniconda3/lib/python3.6/site-packages/gym/gym/envs,在该目录下找一个与你的环境比较相似的环境类型(其实随便选一个就可以),比如 classic_control,将 myenv.py 放在该目录下,并在该目录中的 __init__.py 中加上一句:

from gym.envs.classic_control.myenv import MyEnv

完成后,返回 gym/envs 目录,在该目录的 __init__.py 中注册环境:

register(
	id = 'env_name-v0' # 环境名,版本号 v0 必须有
	entry_point = 'env.myenv:MyEnv' # 文件夹名.文件名:类名
	# 根据需要定义其他参数
)

至此,就完成了环境的注册,就可以使用自定义的环境了!

三、简化的 OpenAI Gym 风格代码

如果不想注册到 OpenAI Gym,而只是想按照这个风格写代码,快速实现一下自己的环境并验证几个简单的算法,我们只需写出一个 OpenAI Gym 风格的环境即可,比如:

class MyEnv:
	def __init__(self):
		...
	
	def reset(self):
		...
		obs = self.get_observation()
		return obs
	
	def step(self, action):
		...
		reward = self._get_reward()
		done = self._get_done()
		obs = self._get_observation(action)
		info = {} # 用于记录训练过程中的环境信息,便于观察训练状态
		return obs, reward, done, info
	
	# 根据需要设计相关辅助函数
	def _get_observation(self, action):
		...
		return obs
	
	def _get_reward(self):
		...
		return reward

	def _get_done(self):
		...
		return done

当然,这个建议只是参考,大家还是老老实实注册到 OpenAI Gym 好了。