ray的强大不仅在于他是分布式计算框架,更是因为有RLLib和tune的加持。tune的使用上一节我们已经讲了,这一节我们来看一下RLLib的使用。虽然后讲的rllib,但是真正训练的时候,还是tune使用的多,因为它调节超参数是很方便的,而rllib不具有自动调节超参数的能力。 在使用rllib之前,需要使用命令
pip install ray[rllib]
安装。 使用rllib训练强化学习智能体有两种方式: 一、直接使用命令行训练,在终端中输入如下命令,就会开始训练过程。
rllib train --run=A2C --env=CartPole-v0
这种方式适合内置的环境和算法,不需要考虑环境和算法是如何实现的,如果想要做更多修改和人性化的训练,那么需要使用第二种方式。
二、 编写程序实现训练
这估计是大多数人会选择的方式,对于命令行的方式,在编写py文件的时候,就应该使用argparse来接受并解析命令,但是我觉着大多数中国人还是喜欢直接修改py源码的方式。 不同的agents是通过ray.rllib.agents导入的,这里面包含了所有可用的agents(算法)。ray(rllib)的优势之一是与深度学习框架无关性,即同样的强化学习算法既可以使用tensorflow框架,也可以使用pytorch框架,只需要在config中指明‘framework’:’torch’即可,默认使用的是tf。 我们来看一个例子:
import ray
from ray.rllib import agents
ray.shutdown()
ray.init(ignore_reinit_error=True) # Skip or set to ignore if already called
config = {'gamma': 0.9,
'lr': 1e-5,
'num_workers': 10,
'framework':'torch',
'num_gpus':1,
'train_batch_size': 1000,
'model': {
'fcnet_hiddens': [128, 128]
}}
trainer = agents.ppo.PPOTrainer(env='CartPole-v0', config=config)
count=0
while True:
count+=1
results = trainer.train()
print()
print('count=',count)
print('episode total=',results['episodes_total'])
print('timesteps total=',results['timesteps_total'])
print('episode_reward_mean=',results['episode_reward_mean'])
if results['episode_reward_mean']>=199:
break
print('='*20)
print('episode total=',results['episodes_total'])
print('timesteps total=',results['timesteps_total'])
print('count=',count)
ray.shutdown()
输出:
...
...
...
count= 36
episode total= 574
timesteps total= 72000
episode_reward_mean= 197.9
count= 37
episode total= 584
timesteps total= 74000
episode_reward_mean= 197.9
count= 38
episode total= 596
timesteps total= 76000
episode_reward_mean= 198.21
count= 39
episode total= 606
timesteps total= 78000
episode_reward_mean= 199.07
====================
episode total= 606
timesteps total= 78000
count= 39
同样的参数设置也是通过config字典来配置,调用trainer.train()来进行训练,相比于tune的训练模式,rllib需要自己编程指定结束条件,在不添加额外的代码的情况下,trainer.train()只进行一次训练。 trainer.train()返回的是一个字典,包含了几乎所有的参数和中间结果,如图
我们就可以根据这里面的参数设置结束条件。 上面包括前一节的tune部分说的都是使用gym提供的标准环境,那么我们自定义的环境如何应用到rllib上呢? 应用自定义环境 对于我们自己的应用,需要编写适合自己业务的环境,比如训练机器人等,虽然Gym有提供Mujoco作为刚体动力学仿真软件,但mujoco收费以及上手难度高等问题一直很困扰,所以很多用户转向了pybullet。我使用pybullet也有一些时间了,总结来说bullet3是一个非常优秀的刚体动力学引擎,pybullet不仅文档齐全,官方example全而细,而且非常易于上手,安装也只是pip install pybullet一个命令这样简单。我有关于pybullet的一个专栏,专注于分享pybullet的技术,戳这里 -> pybullet专栏,欢迎阅读评论转发。 将自己的环境注册到gym中是较为容易的,可以阅读pybullet专栏中的相关文章。这时候你可能会想,在ray中也是直接敲的gym的环境名称,比如上面用的CartPole-v0,所以你觉着将自己的环境注册在gym中,然后在ray中直接输入环境名称就可以了吧?但事实是,不可以。目前ray仅支持gym原生的环境,对于自己封装的环境,有另一套注册机制,我们看一下rllib官方的说明,下图说gym的注册与ray(2.0.0dev版本)的环境注册是不兼容的,所以肯定还有其他的方法。
在将环境注册到ray之前,需要先注册在gym中,可以阅读注册自定义Gym环境按照步骤操作,也可以通过专栏入口Pybullet专栏找到更多gym环境相关的文章。 将环境注册到gym并且通过测试后,我们在ray中进行进一步的封装。假设你在gym中注册的环境名称是MyEnv-v0,在gym中,gym.make('MyEnv-v0')
返回的是一个环境实例,而在ray中,需要直接返回环境类作为环境名,如下面代码中描述的那样。
def env_creator(env_name):
if env_name == 'MyEnv-v0':
from custom_gym.envs.custom_env import CustomEnv0 as env
elif env_name == 'MyEnv-v1':
from custom_gym.envs.custom_env import CustomEnv1 as env
else:
raise NotImplementedError
return env
同时呢,在trainer中也需要做些修改,上面的代码需要修改为这样:
import ray
from ray.rllib import agents
ray.shutdown()
ray.init(ignore_reinit_error=True) # Skip or set to ignore if already called
#添加一个变量表示环境名
env_name='MyEnv-v0'
#添加env_creator函数
def env_creator(env_name):
if env_name == 'MyEnv-v0':
from custom_gym.envs.custom_env import CustomEnv0 as env
elif env_name == 'MyEnv-v1':
from custom_gym.envs.custom_env import CustomEnv1 as env
else:
raise NotImplementedError
return env
config = {'gamma': 0.9,
'lr': 1e-5,
'num_workers': 10,
'framework':'torch',
'num_gpus':1,
'train_batch_size': 1000,
'model': {
'fcnet_hiddens': [128, 128]
}}
#trainer = agents.ppo.PPOTrainer(env='CartPole-v0', config=config)
#trainer需要修改为这样
trainer = agents.ppo.PPOTrainer(env=env_creator(env_name), config=config)
count=0
while True:
count+=1
results = trainer.train()
print()
print('count=',count)
print('episode total=',results['episodes_total'])
print('timesteps total=',results['timesteps_total'])
print('episode_reward_mean=',results['episode_reward_mean'])
if results['episode_reward_mean']>=199:
break
print('='*20)
print('episode total=',results['episodes_total'])
print('timesteps total=',results['timesteps_total'])
print('count=',count)
ray.shutdown()
这样就完成了ray中自定义环境的训练。
猜你想看: Ubuntu助手 — 一键自动安装软件,一键进行系统配置 深度强化学习专栏 —— 1.研究现状 深度强化学习专栏 —— 2.手撕DQN算法实现CartPole控制 深度强化学习专栏 —— 3.实现一阶倒立摆 深度强化学习专栏 —— 4. 使用ray做分布式计算 深度强化学习专栏 —— 5. 使用ray的tune组件优化强化学习算法的超参数