要用强化学习(Reinforcement Learning)算法解决问题,需要百千万次的训练,真实环境一般不允许这么多次训练(时间太长、试错代价太大),需要开发仿真环境。OpenAI的gym环境是目前的标准,遵守其API写一个自定义的环境可以被各种强化学习算法无码调用。
gym API要求分析gym的代码和文档,可以看出,一个环境至少应该包含动作空间(action space)、状态空间(observation space)定义,以及reset()、step()、render()、close()方法,代码结构如下:
from typing import Optional
import gym
from gym import spaces
class MyEnv(gym.Env):
def __init__(self):
self.observation_space = spaces.Box(
-np.inf, np.inf, shape=(5,), dtype=np.float32
)#5个浮点数状态空间
self.action_space = spaces.Discrete(3)#0,1,2三个动作空间
def step(self, action):
pass
def reset(self,
*,
seed: Optional[int] = None,
return_info: bool = False,
options: Optional[dict] = None):
pass
def render(self, mode="human"):
return None
def close(self):
pass
环境的测试
自定义环境写好后,首先应该用预设数据进行测试,看结果是否符合预期,排出完bug之后,再交给RL算法去训练。
修改最多的地方就是奖励机制(reward)了,与领域问题密切相关,比如我的环境是仿真加热过程,温度每增加1℃得1分对么?实际温升的成本与温度之间不是线性关系,是指数函数,我感觉环境的学问90%都在奖励机制的设计上了。
注册为gym环境我照着知乎这篇文章做的,分三步:
第一步:将我们自己的环境文件(我创建的文件名为myenv.py)拷贝到你的gym安装目录/gym/gym/envs/classic_control文件夹中。(拷贝在这个文件夹中因为要使用rendering模块。当然,也有其他办法。该方法不唯一)
第二步:打开该文件夹(第一步中的文件夹)下的__init__.py文件,在文件末尾加入语句:
from gym.envs.classic_control.myenv import MyEnv
第三步:进入文件夹你的gym安装目录/gym/gym/envs,打开该文件夹下的__init__.py文件,添加代码:
register(
id='MyEnv-v0',
entry_point='gym.envs.classic_control:GridEnv',
max_episode_steps=200,
reward_threshold=100.0,
)
在RL算法上训练
RL算法很多,实现就更五花八门了,推荐github上面星比较多的,我用的cleanrl,理念是一个算法一个独立文件搞定,B站上有作者介绍PPO的视频。把ppo.py文件中的env-name参数替换为MyEnv后就可以跑起来了,默认env-nums是4个,我改成了20个。
跑了4个小时,训练基本收敛了,满分应该是72.33分左右
仿真速度当你的仿真算法复杂时,速度恐怕不乐观,要训练1M次十天半个月的等不起,这时候就要优化仿真代码的速度,并考虑多环境并发训练了。
在我的仿真逻辑中,大计算量在蒸汽的物性参数计算上,而这个计算是在一定温度范围内才需要做的,加一些判断避免不必要的计算可以提高计算速度。
cleanrl默认用的是SyncVectorEnv(单进程内顺序调用环境),可以修改为AsyncVectorEnv,然后每个环境都会在独立的子进程中运行,再以通讯的方式与智能体进行交互。我试了20报错,spawn页面太小无法完成 *** 作,修改D盘虚拟内存后,试10时似乎错误少了,改为8不报错了,可能是系统资源受限了吧,这回速度快了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)