了解深度RL的最佳方法之一是运行算法,看看它们在不同任务中的表现。Spinning Up代码库使小规模(本地)实验变得容易,在本节中,我们将讨论两种运行它们的方法:从命令行,或者通过脚本中的函数调用。
Launching from the Command Line
Spinning Up附带spinup/run.py,这是一个方便的工具,可以让您从命令行轻松启动任何算法(可以选择任何超参数)。它还充当了观察经过训练的策略和绘图的实用程序的精简包装器,尽管我们不会在本页上讨论该功能(有关这些详细信息,请参阅关于实验输出和绘图的页面)。
从命令行运行Spinning Up算法的标准方法是
python -m spinup.run [algo name] [experiment flags]
比如
python -m spinup.run ppo --env Walker2d-v2 --exp_name walker
Detailed Quickstart Guide python -m spinup.run ppo --exp_name ppo_ant --env Ant-v2 --clip_ratio 0.1 0.2 --hid[h] [32,32] [64,32] --act torch.nn.Tanh --seed 0 10 20 --dt --data_dir path/to/data
在Ant-v2 Gym环境中运行PPO,各种设置由标志控制。
默认情况下,PyTorch版本将运行(TRPO除外,因为Spinning Up还没有PyTorch TRPO)。将ppo替换为ppo_tf1作为Tensorflow版本。
clip_ratio、hid和act是设置某些算法超参数的标志。可以为超参数提供多个值以运行多个实验。检查文档以查看可以设置的超参数(点击此处查看PPO文档)。
hid和act是为算法训练的神经网络设置隐藏大小和激活函数的特殊快捷标志。
seed标志为随机数生成器设置种子。RL算法具有很高的方差,因此尝试使用多个种子来了解性能的变化。
dt标志确保保存目录名中有时间戳(否则没有时间戳,除非在spinup/user_config.py中设置FORCE_DATESTAMP=True)。
data_dir标志允许您设置结果的保存文件夹。默认值由spinup/user_config.py中的default_DATA_DIR设置,它将是spinningup文件夹中的子文件夹数据(除非您更改它)。
保存目录名称基于exp_name和任何具有多个值的标志。目录名中将显示一个简写,而不是完整标志。Shorthands可以由用户在flag后面的方括号中提供,如--hid[h];否则,shorthands是标志的子字符串(clip_ratio变为cli)。为了说明,clip_ratio=0.1、hid=[32,32]和seed=10的运行的保存目录将是:
path/to/data/YY-MM-DD_ppo_ant_cli0-1_h32-32/YY-MM-DD_HH-MM-SS-ppo_ant_cli0-1_h32-32_seed10
Choosing PyTorch or Tensorflow from the Command Line
要使用PyTorch版本的算法,请使用
python -m spinup.run [algo]_pytorch
要使用Tensorflow版本的算法,请使用
python -m spinup.run [algo]_tf1
如果在没有_pytarch或_tf1的情况下运行python-m spinup.run[algo],运行程序将在spinup/user_config.py中查找该算法的默认版本。
Setting Hyperparameters from the Command Line
每个算法中的每个超参数都可以直接从命令行进行控制。如果kwarg是算法函数调用的有效关键字arg,则可以使用标志--kwarg为其设置值。若要了解可用的关键字args,请参阅算法的文档页面,或者尝试
python -m spinup.run [algo name] --help
以查看文档字符串的读数。
You Should Know
值在使用之前会通过eval(),因此您可以直接从命令行描述一些函数和对象。例如
python -m spinup.run ppo --env Walker2d-v2 --exp_name walker --act torch.nn.ELU
设置torch.nn.ELU作为激活函数。(Tensorflow等效:使用--act tf.nn.elu运行ppo_tf1。)
You Should Know
对于采用dict值的kwargs,有一些不错的处理方式。不是必须提供
--key dict(v1=value_1, v2=value_2)
也可以输入
--key:v1 value_1 --key:v2 value_2
来得到相同的结果
Launching Multiple Experiments at Once
只需为给定的参数提供一个以上的值,就可以启动多个实验,并依次执行。(将针对每个可能的值组合启动一个实验。)
例如,要使用不同的随机种子(0、10和20)启动等效的运行,请执行以下操作:
python -m spinup.run ppo --env Walker2d-v2 --exp_name walker --seed 0 10 20
实验不会并行启动,因为它们占用了足够的资源,同时执行几个实验不会加快速度。
Special Flags
一些标志有特殊情况。
Environment Flag
--env
,
--env_name
string. 它们是OpenAI Gym中环境的名称。所有Spinning Up算法都实现为接受env_fn作为参数的函数,其中env_fn必须是构建RL环境副本的可调用函数。不过,由于最常见的用例是Gym环境,所有这些环境都是通过Gym.make(env_name)构建的,因此我们允许您只在命令行中指定env_name(或简称env),该命令行将转换为lambda函数,用于构建正确的Gym环境。
有些算法参数相对较长,我们为它们启用了快捷方式:
--hid
,
--ac_kwargs
:hidden_sizes
list of ints.设置神经网络中隐藏层的大小(策略和值函数)。
--act,--ac_kwargs:激活
tf op. Actor and critic中神经网络的激活函数。
这些标志对所有当前的Spinning Up算法都有效。
Config Flags
这些标志不是任何算法的超参数,而是以某种方式改变实验配置。
--cpu
,
--num_cpu
int. 如果设置了此标志,则启动实验时会有这么多进程,每个cpu一个,通过MPI连接。有些算法适用于这种并行化,但并非所有算法都适用。如果您尝试为不兼容的算法设置num_cpu>1,将引发错误。您还可以设置--num_cpu auto,它将自动使用机器上可用的cpu数量。
--exp_name
string. 实验名称。这用于命名每个实验的保存目录。默认值为“cmd”+[算法名称]。
--data_dir
path. 设置此实验或一组实验的基本保存目录。如果未给定,则将使用spinup/user_config.py中的DEFAULT_DATA_DIR。
--datestamp
bool. 在实验的保存目录的名称中包括日期和时间。
Where Results are Saved
特定实验的结果(超参数配置的单次运行)存储在
data_dir/[outer_prefix]exp_name[suffix]/[inner_prefix]exp_name[suffix]_s[seed]
其中
data_dir是--data_dir标志的值(如果没有给定--data_dir,则默认为spinup/user_config.py中的DEFAULT_data_dir),
outer_prefix是一个YYY-MM-DD_时间戳,如果--datestamp标志被提升,否则什么都没有,
inner_preix是YYY-MM-DD_HH-MM-SS-时间戳(如果--datestamp标志被提升),
suffix是一个基于实验超参数的特殊字符串。
How is Suffix Determined?
只有同时运行多个实验时才包括suffix(后缀),并且后缀只包括对不同实验的超参数的引用,随机种子除外。目标是确保类似实验(共享除种子以外的所有参数的实验)的结果分组在同一文件夹中。
后缀是通过将超参数的简写与其值相结合来构建的,其中简写是1)根据超参数名称自动构建,或者2)由用户提供。用户可以通过在kwarg标志后面的方括号中书写来提供速记。
比如
python -m spinup.run ddpg_tf1 --env Hopper-v2 --hid[h] [300] [128,128] --act tf.nn.tanh tf.nn.relu
这里,--hid标志提供了一个用户提供的简写形式h。--act标志不是由用户提供的缩写形式,因此将自动为其构建一个缩写形式。
这种情况下产生的后缀是:
_h128-128_ac-actrelu _h128-128_ac-acttanh _h300_ac-actrelu _h300_ac-acttanh
请注意,h是由用户给出的。ac-act简写是根据ackwargs:activation(act标志的真实名称)构建的。
Extra
You Don’t Actually Need to Know This One
每个单独的算法都位于一个文件spinup/algos/BACKEND/ALGO_NAME/ALGO_NAME.py中,这些文件可以通过一组有限的参数(其中一些参数与spinup/run.py可用的参数不同)直接从命令行运行。然而,单个算法文件中的命令行支持基本上是残余的,这不是执行实验的推荐方式。
本文档页将不描述那些命令行调用,只描述通过spinup/run.py的调用。
Launching from Scripts
每个算法都实现为一个python函数,可以直接从spinup包导入,例如
>>> from spinup import ppo_pytorch as ppo
有关可能的参数的完整说明,请参阅每个算法的文档页。这些方法可用于设置专门的自定义实验,例如:
from spinup import ppo_tf1 as ppo import tensorflow as tf import gym env_fn = lambda : gym.make('LunarLander-v2') ac_kwargs = dict(hidden_sizes=[64,64], activation=tf.nn.relu) logger_kwargs = dict(output_dir='path/to/output_dir', exp_name='experiment_name') ppo(env_fn=env_fn, ac_kwargs=ac_kwargs, steps_per_epoch=5000, epochs=250, logger_kwargs=logger_kwargs)
这段代码实现了以下功能:
- 导入了名为
ppo_tf1
的PPO算法模块(假设该模块来自Spinup库),以及TensorFlow和OpenAI Gym库。 - 定义了一个函数
env_fn
,用于创建一个名为'LunarLander-v2'的OpenAI Gym环境。 - 定义了一个名为
ac_kwargs
的字典,其中包含了PPO算法的参数配置,如隐藏层大小(hidden_sizes)和激活函数(activation)。 - 定义了一个名为
logger_kwargs
的字典,用于配置日志记录器的参数,包括输出目录(output_dir)和实验名称(exp_name)。 - 调用了PPO算法函数
ppo
,并传递了环境创建函数env_fn
、PPO算法参数配置ac_kwargs
、每个epoch的步数steps_per_epoch
、训练轮数epochs
以及日志记录器参数配置logger_kwargs.
在机器学习研究中,使用许多可能的超参数运行相同的算法通常是有用的。Spinning Up提供了一个简单的工具,名为ExperimentalGrid。
考虑spinup/examples/pytorch/banch_ppo_cartpole.py中的示例:
from spinup.utils.run_utils import ExperimentGrid from spinup import ppo_pytorch import torch if __name__ == '__main__': import argparse parser = argparse.ArgumentParser() parser.add_argument('--cpu', type=int, default=4) parser.add_argument('--num_runs', type=int, default=3) args = parser.parse_args() eg = ExperimentGrid(name='ppo-pyt-bench') eg.add('env_name', 'CartPole-v0', '', True) eg.add('seed', [10*i for i in range(args.num_runs)]) eg.add('epochs', 10) eg.add('steps_per_epoch', 4000) eg.add('ac_kwargs:hidden_sizes', [(32,), (64,64)], 'hid') eg.add('ac_kwargs:activation', [torch.nn.Tanh, torch.nn.ReLU], '') eg.run(ppo_pytorch, num_cpu=args.cpu)
这段代码执行了以下操作:
-
从Spinup库中导入了实用工具模块
ExperimentGrid
以及PyTorch版本的PPO算法ppo_pytorch
,同时也导入了PyTorch库。 -
在条件
if __name__ == '__main__':
下,首先定义了一个参数解析器argparse.ArgumentParser()
,用于解析命令行参数。然后,添加了两个命令行参数--cpu
和--num_runs
,分别表示CPU核心数和运行次数的数量,默认值分别为4和3。接着,使用parser.parse_args()
解析命令行参数,并将结果存储在args
变量中。 -
创建了一个实验网格对象
eg
,命名为'ppo-pyt-bench',用于定义一系列实验的参数组合。 -
使用
eg.add()
方法添加了各种参数及其取值范围,包括环境名称env_name
为'CartPole-v0',随机种子seed
为根据运行次数生成的一系列数值,训练轮数epochs
为10,每轮步数steps_per_epoch
为4000,隐藏层大小ac_kwargs:hidden_sizes
为[(32,), (64,64)],激活函数ac_kwargs:activation
为[torch.nn.Tanh, torch.nn.ReLU]。 -
最后,调用了实验网格对象的
run()
方法,传递了PyTorch版本的PPO算法函数ppo_pytorch
以及CPU核心数num_cpu
(即args.cpu
),从而运行了一系列实
(An equivalent Tensorflow example is available in spinup/examples/tf1/bench_ppo_cartpole.py
.)
制作ExperimentalGrid对象后,这样向其添加参数:
eg.add(param_name, values, shorthand, in_name)
其中in_name强制参数出现在实验名称中,即使它在所有实验中具有相同的值。
在添加了所有参数之后,
eg.run(thunk, **run_kwargs)
通过将配置作为kwargs提供给函数thunk,在网格中运行所有实验(每个有效配置一个实验)。ExperimentGrid.run使用一个名为call_experiment的函数来启动thunk,并且**run_kwargs指定call_express的行为。有关详细信息,请参阅文档页。the documentation page
除了没有快捷方式kwargs(在ExperimentalGrid中不能对ac_kwargs:hidden_sizes使用hid)之外,Experimental Grid的基本行为与从命令行运行内容相同。(事实上,spinup.run在引擎盖下使用了ExperimentalGrid。)
总结 讲了运行试验的方法和相关函数