之前看过的所有环境都具有离散动作空间:在任何时间步,代理必须从列表中选择一个要执行的动作,例如“什么都不做”,“向左移动”,“向右移动”或“射击”。
这次重点将转移到具有连续动作空间的环境上:在每个时间步,代理必须为动作选择一组浮点数。特别是,将使用Humanoid环境,鼓励一个人类模型学习行走。
将继续使用Ray的RLlib库进行强化学习过程,因为使用连续动作空间会减少可以使用的学习算法数量,可以在功能兼容性矩阵中看到这一点。
这些文章假设对Python 3和安装组件有一定的了解。
将要训练的连续控制环境比之前系列中的环境更具挑战性。即使在拥有强大GPU和足够多CPU核心的强大机器上,这些实验中的一些也需要几天的时间来训练。许多公司愿意按小时租用Linux服务器,这就是在运行这些训练会话时所采取的方法。它与tmux或screen一起使用特别好,使能够断开连接并重新连接到正在运行的会话(如果有足够强大的机器,还可以同时运行多个实验)。
对于这一系列的文章,在租用的Linux服务器上运行了这些训练会话(还有很多没有入选的!)——特别是Ubuntu。发现将所有要求放在一个设置脚本中很方便。
上次没有的主要依赖是PyBullet,它是Bullet物理仿真引擎的Python包装器。
#!/bin/bash
# Get a clean host up to speed for running ML experiments
apt-get update
apt-get upgrade –quiet
apt-get install -y xvfb x11-utils
apt-get install -y git
apt-get install -y ffmpeg
pip install gym==0.17.2
pip install ray
[ rllib ]==0.8.6
pip install PyBullet==2.8.6
pip install pyvirtualdisplay==0.2.* PyOpenGL==3.1.* PyOpenGL-accelerate==3.1.*
pip install pandas==1.1.0
# should be pip install tensorflow_probability, but had to do this:
pip install tfp-nightly==0.11.0.dev20200708
# because of this issue: https://github.com/tensorflow/tensorflow/issues/40584
So my routine for a fresh server was to
apt-get install wget
, then
wget
the script above from the public server I had hosted it on, and then run it to install all my dependencies.
For downloading the results from a remote server, you can use scp (or
PuTTY’s pscp
for downloading to Windows).
如果还记得上一系列文章中的CartPole环境,将其描述为强化学习的“Hello World”。它有一个带轮子的推车,上面平衡着一根杆子,代理可以向左或向右移动推车,以保持杆子平衡的时间越长越好。
CartPole是更简单的强化学习环境之一,仍然具有离散动作空间。PyBullet包含它自己的版本(而不是上次使用的OpenAI的Gym版本),可以尝试运行它以检查PyBullet是否安装正确。
>>> import gym
>>> import pybullet_envs
>>> env = gym.make('CartPoleBulletEnv-v1')
>>> env.observation_space
Box(4,)
>>> env.action_space
Discrete(2)
因此,观测空间是一个四维连续空间,但动作空间只有两个离散选项(左或右)。这就是习惯的。
将从使用深度Q网络(DQN)算法开始,这是在上一系列中遇到的。
这是一个Python脚本,用于在PyBullet的CartPole环境中训练代理。总体结构与在上一系列实验中使用的结构相同:设置一个虚拟显示,以便可以在服务器上无头运行,重新启动Ray,注册环境,然后设置它进行训练,直到达到目标奖励。
注意是
import pybullet_envs
将PyBullet环境名称注册到Gym中。发现需要在
make_env
函数内导入它,而不是在文件顶部,大概是因为这个函数在Ray的远程工作器上被单独调用。
import pyvirtualdisplay
_display = pyvirtualdisplay.Display(visible=False, size=(1400, 900))
_ = _display.start()
import gym
import ray
from ray import tune
from ray.rllib.agents.dqn import DQNTrainer
from ray.tune.registry import register_env
ray.shutdown()
ray.init(include_webui=False, ignore_reinit_error=True)
ENV = 'CartPoleBulletEnv-v1'
def make_env(env_config):
import pybullet_envs
return gym.make(ENV)
register_env(ENV, make_env)
TARGET_REWARD = 190
TRAINER = DQNTrainer
tune.run(
TRAINER,
stop={
"episode_reward_mean": TARGET_REWARD},
config={
"env": ENV,
"num_workers": 7,
"num_gpus": 1,
"monitor": True,
"evaluation_num_episodes": 50,
}
)
可以根据使用的硬件调整
num_gpus
和
num_workers
的值。
num_workers
的值可以是拥有的CPU核心数减一。
通过将
monitor
设置为
True
和
evaluation_num_episodes
设置为
50
,告诉RLlib每50个剧集(默认是每10个)保存进度统计和训练会话的mp4视频。这些将出现在
ray_results
目录中。
对于运行,学习进度(来自
progress.csv
的
episode_reward_mean
)看起来像这样,需要176秒才能达到目标奖励190:
没有改变任何有趣的参数,例如学习率。这个环境足够简单,RLlib的DQN算法的默认参数在不需要任何微调的情况下就做得很好。
训练有素的代理与其环境的互动看起来像这样:
使用PPO算法的Bullet CartPole环境
使用RLlib的一个好处是切换算法很简单。要使用Proximal Policy Optimisation(PPO)而不是DQN进行训练,添加以下导入:
from ray.rllib.agents.ppo import PPOTrainer
并按如下方式更改
TRAINER
的定义:
TRAINER = PPOTrainer
将在稍后的文章中了解到更多关于PPO的细节,届时将使用它来训练Humanoid环境。现在,只是将其视为一个黑匣子,并使用其默认的学习参数。
当运行这个时,训练需要109.6秒,进度看起来像这样:
现在这是一个漂亮的平滑图表!而且它训练得更快。
视频看起来与使用DQN算法的训练会话相似,所以在这里不会重复。
正如之前提到的,传统的CartPole具有离散动作空间:训练一个策略来选择“向左移动”或“向右移动”。
PyBullet还包括一个连续版本的CartPole环境,其中动作指定了一个表示要施加在推车上的力的单个浮点值(正数表示一个方向,负数表示另一个方向)。
>>> import gym
>>> import pybullet_envs
>>> env = gym.make('CartPoleContinuousBulletEnv-v0')
>>> env.observation_space
Box(4,)
>>> env.action_space
Box(1,)
观测空间与之前相同,但这次动作空间是连续的,而不是离散的。
DQN算法不能处理连续动作空间。PPO可以,所以让来做。
按如下方式更改训练代码中的环境声明:
ENV = 'CartPoleContinuousBulletEnv-v0'