前言
网上找了很多自定义gym环境的教程,感觉都说的不够清楚,所以自己写一个,每天补充一点
一、编写自定义gym环境
1.myenv.py
下面是一个创建自定义环境的模板,可以直接拿去用
import gym
from gym import spaces
import numpy as np
class myEnv(gym.Env):
metadata = {
'render.modes': ['human', 'rgb_array'],
'video.frames_per_second': 50
}
def __init__(self):
self.action_space = None # 动作空间
self.observation_space = None # 状态空间
dt=0.05 # 每个时间步间隔时间
pass
def step(self, action):
return self.state, reward, done,False, {} #这里对不同版本的gym包可能格式不一样,调试时注意报错信息修改即可
def reset(self):
return self.state,{}
def render(self, mode='human'):
return None
def close(self):
return None
train.py
这个文件在创建gym环境时不是必要的,但有助于我们理解创建gym环境时所定义的方法何时会被用到。
env = gym.make('myEnv-v0', render_mode="human")
max_episodes = 20
cum_reward = 0
for _ in range(max_episodes): #训练max_episodes个回合
obs=env.reset() # 初始化环境状态
done=False # 回合结束标志,当达到最大步数或目标状态或其他自定义状态时变为True
while not done:
# env.render() #渲染,一般在训练时会注释掉
action =agent.get_action(obs) # 智能体根据传入状态obs选择动作action
next_obs, reward, done, info, _ = env.step(action) # 环境根据智能体动作返回下一状态,奖励,回合结束标志和其他信息
agent.learn(obs,action,next_obs, reward) # 智能体根据数据学习
cum_reward += reward #计算累计奖励
env.close() # 全部回合训练结束,关闭环境中占用的资源
接下来逐一说明一下myenv.py文件中每个方法的作用:
metadata
与render()方法相关,稍后会说明。
__init__
方法:初始化环境参数,action_space
、observation_space
、dt
是必须定义的内容。其次,环境中的一些固定参数,渲染窗口等也需要在该函数中定义。
step(self,action)
方法在每个时间步被调用(也就是train.py中的env.step(action)语句),功能是基于传入的action和当前的obs生成新的obs,reward,done(回合结束标志)和其他信息info,所以该方法需要实现状态转移函数,奖励函数,以及回合结束判定,必要的话还可以添加自定义信息info
reset()
方法在每个回合(episode)起始被调用,用于对环境状态初始化
render()
方法顾名思义用于渲染,在metadata中定义了两种模式,human模式会显示图形界面,rgb_array用于得到rgb的图像数据进行进一步的图像处理。
close()
方法在训练结束后销毁环境数据,避免占用内存资源。
二、将自定义环境注册到gym中
(1).当我们写完自定义的环境后,需要将该环境注册到gym中才能使用,目录结构如下:
>>project
>>my_gym
>>envs
__init__.py
myenv.py
__init__.py
setup.py
train.py
(2). 在my_gym目录下的__init__.py
文件中添加如下代码:
from gym.envs.registration import register
register(
id='myEnv-v0',
entry_point='my_gym.envs:myEnv',
max_episode_steps=200,
)
其中id为环境名,可以使用gym.make('myEnv-v0')
创建该环境,entry_point即入口,也就是路径,即my_gym包的envs模块内的myEnv类,最大步数不是必须定义的,但在这里定义gym会直接帮你实现最大200步停止(也就是让回合结束表示置1),否则需要自己在step函数中实现。
(3). 在envs目录下的__init__.py
文件中添加如下代码:
from my_gym.envs.myenv import myEnv
(4).在工程目录下的setup.py中添加如下代码:
from setuptools import setup
setup(name='my_gym',
version='0.0.1',
install_requires=['gym', 'pygame']
)
在setup.py所在路径下右键点击打开终端,在终端中输入如下指令将自定义的环境打包:
python setup.py bdist_wheel
(5). 在python环境中安装该包
找到工程目录下生成的xxx.whl文件,在当前python环境下安装该包
pip install xxx.whl
(6). 在train.py中导入包并生成环境
import gym
import my_env
env = gym.make('myEnv-v0', render_mode="human")