0 引言
OpenAI gym是当下非常热门的强化学习库,使用者只需要定义环境就可以测试自己的强化学习算法。
本文主要介绍如何在ubuntu 16.04上配置gym开发环境,gym的建模思想,以及自己动手搭建一个gym环境。
1 gym环境配置
|
|
2 gym建模思想
强化学习主要有两个对象,环境和agent。环境的属性包括环境状态集合、agent的当前状态、agent的观测空间、agent的动作空间,环境的行为包括状态转移、奖励机制,终止状态判断,将当前的状态变换成观测输出;agent的属性包括依附的环境、观察和获得的即时奖励,智能体的行为包括根据已知策略产生一个动作、执行动作改变环境、获得环境的状态和即时奖励。agent不能掌握整个环境,只能通过观测量获得环境的状态信息,同样agent需要与环境进行交互,哪些动作可以执行,哪些动作不能执行,需要agent和环境协商好。因此agent需要确定agent的观测空间和动作空间。
状态分为环境状态和agent状态,要怎么区分呢?环境状态是用来表示自身的,它对agent可能不完全可观,如在移动机器人与行人交互中,不能得知行人的意图;agent状态是强化学习框架中的状态,是agent根据策略执行动作的依据。当环境完全可观时,环境的状态=agent状态=观测;当环境部分可观时,agent状态$\ne$环境状态$^{[3]}$。
在我的理解中,agent更像是一个控制器,而环境是被控对象(包括机器人和所处环境)。控制器输入测量量(观测)和反馈值(即时奖励),输出控制量(动作)。以移动机器人在行人环境中避免障碍为例,agent是移动机器人的控制器,环境是移动机器人和周围行人及固定障碍物的行为关系。agent状态包括移动机器人自身的位置速度目的地等信息和障碍物的位置和速度,环境状态包括移动机器人的位置速度目的地等信息以及障碍物的位置速度和目的地等信息。观测是移动机器人上的激光雷达和摄像头测得的数据,以及小车路径规划和里程计等数据。
按照这样的思路,可以提炼出伪代码$^{[1]}$如下:
gym的建模思想
gym库的核心文件是/gym/gym/core.py,这里定义了两个最基本的类Env和Space。前者是所有环境类的基类,后者是所有空间类的基类。从Space基类衍生出几个常用的空间类,其中最主要的是Discrete类和Box类。通过其init方法的参数以及其它方法的实现可以看出前者对应于一维离散空间,后者对应于多维连续空间。它们既可以应用在行为空间中,也可以用来描述状态空间。例如,Small GridWorld例子中,共有4x4个状态,每个状态只需要用一个数字来描述,这样就可以使用Discrete(16)对象来描述。Box空间可以定义多维空间,每一个维度可以用一个最小值和最大值来约束。Box可以描述连续的状态空间。
下面来分析环境基类Env:
可以看出,agent主要通过环境以下几个方法进行交互:step, reset, render, close, seed,这几个方法都是共有属性,具体每个方法的调用都是其内部方法:_step, _reset, _render, _close, _seed.这几个方法的功能如下:
_step: 物理引擎,最核心的方法,定义环境的动力学;
_reset: 初始化;
_render: 图像引擎,使用gym包装好的pyglet方法来实现,涉及到OpenGL编程思想
_seed: 设置一些随机数的种子
如何使用gym来编写自己的agent代码呢?首先要在agent类中声明一个env变量,指向所依附的环境类,agent自身依据策略产生一个动作,该动作送入env的step方法中,同时得到观测状态、奖励值、终止标志和调试信息四项组成的元组:
state, reward, is_done, info = env.step(a)
state 是一个元组或numpy数组,其提供的信息维度应与观测空间的维度一样、每一个维度的具体指在制定的low与high之间,保证state信息符合这些条件是env类的_step方法负责的事情。
reward 则是根据环境的动力学给出的即时奖励,它就是一个数值。
is_done 是一个布尔变量,True或False,你可以根据具体的值来安排个体的后续动作。
info 提供的数据因环境的不同差异很大,通常它的结构是一个字典:
{"key1":data1,"key2":data2,...}
最后是在代码中建立环境类的对象,方法如下:
import gym
env = gym.make("registered_env_name")
3 倒立摆CartPole-V0
gym中的倒立摆模型如下:
状态空间:$\{x,\dot{x},\theta,\dot{\theta}\}$
动作空间:{1,-1}
奖励函数:
状态转移:由倒立摆的数学模型导出(忽略摩擦系数)
倒立摆的数学模型
$$
mL\ddot{x}cos(\theta)+(mL^2+J)\ddot{\theta}=mgLsin(\theta) \\
(M+m)\ddot{x}+mL\ddot{\theta}cos(\theta)=F+mL\dot{\theta}^2sin(\theta)-b\dot{x}
$$
下面对CartPole-V0的环境文件进行分析,文件位置./gym/gym/envs/classic_control/cartpole.py
4 动手搭建自己的环境
如何将自己搭建的环境放入gym呢?第一步,进行环境类的编写和注册。第二步,测试。简单吧?
环境类的编写和注册
- 按照CartPole-V0环境类的写法,编写自己的环境类文件MyEnv.py
- 将MyEnv.py拷贝到gym的安装目录/gym/gym/envs/classic_control文件夹中。(拷贝到这个文件夹是因为要使用rendering模块,方法不唯一)
打开/gym/gym/envs/classic_control文件夹中的init.py文件,在文件末尾加入语句
from gym.envs.classic_control.MyEnv import MyEnv
进入/gym/gym/envs文件夹,打开文件夹中的init.py文件,添加如下代码:
123456register(id='MyEnv-V0', # 调用gym.make('id')时候的id,名字可以随便取entry_point='gym.envs.classic_control:MyEnv', # 函数路径max_episode_steps=200,reward_threshold=100.0)
测试
|
|
|
|
学习和测试都是在这部分完成
参考文献
[1] 叶强, David Silver强化学习公开课中文讲解及实践, 知乎专栏
[2] 天津包子馅儿, 强化学习实战, 知乎专栏
[3] David Silver, reinforcement learning lecture 1