Spinning up包含下列算法
以上算法均应用了MLP的actor-critics,适用于fully-observed, non-image-based RL环境。
POMDP即部分可观测MDP,non-image指的是非端到端 从图像输入到动作输出的过程。
每个算法有两种实现(pytorch和tensorflow,TRPO只有tensorflow实现)
我们选择了Deep RL近期领域的核心算法,尤其是PPO和SAC,在policy learning算法中实现了可靠性(reliability)和样本效率(sample efficiency),是目前的最佳性能算法(sota),他们也反映了在deep RL中的一些trade-offs。
Vanilla Policy Gradient是最基础 入门级的DRL算法,因为它早于DRL的出现,导致了后来TRPO和PPO的提出。
这一系列算法的特点是 on-policy, 也就是他们不使用旧的数据,这样就会导致他们的样本效率(sample efficiency)较低,但有一个好的方面,就是这些算法可以直接优化你想要的目标,也就是policy的性能表现,从数学角度上讲,这些算法需要on-policy数据来进行更新,因此,这些算法牺牲了样本效率,而具有更好的稳定性,但从VPG到TRPO再到PPO,技术仍在客服样本效率的缺点。
DDPG是一种与VPG类似的基础算法,确定性策略梯度(deterministic policy gradients)的理论,和DDPG 在2014年直到发布才发布,DDPG与Q-learning算法很接近,它学习Q-function的同时学习一个policy,并使他们相互更新改进。
DDPG和Q-learning是off-policy的,他们可以利用旧数据,通过利用贝尔曼方程的最优性获得了这种好处,可以训练 Q 函数来满足使用任何环境交互数据(只要环境中的高回报区域有足够的经验)。
但问题是,并不能保证满足贝尔曼方程就会带来出色的policy表现。 经验上讲,policy可以获得很好的性能生时,样本效率就非常好——但缺乏保证使得此类算法可能变得脆弱和不稳定。 TD3 和 SAC 是 DDPG 的后继发展,进一步缓解了上述问题。
Spinningup中的代码实现遵循一个模板,分为两类文件,一个包含算法的核心逻辑,另一个核心文件包含运行算法的各种utilities。
这些算法文件总是以一个experience buffer类的定义为开始,experience buffer存储了agent与环境交互的数据。接下来的部分是运行算法的单个函数,算法的pytorch和tensorflow的大致相同,最后,每个算法文件都支持从命令行直接在 Gym 环境中运行算法
下面是pytorch和tensorflow的功能实现大致顺序
感受DRL算法的最好方式是运行,看看它在不同任务上的表现,试验运行的两种方法:命令行 或是在scripts中调函数。
使用 spinup/run.py 一个简单的工具,来运行算法,它还可以查看训练策略和绘图的实用程序
运行方式如下:
python -m spinup.run [algo name] [experience 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
这些参数在源文档中有详细说明,后续我们将直接阅读源码
python -m spinup.run [algo]_pytorch
python -m spinup.run [algo]_tf1
算法中的超参数由命令行直接控制,
python -m spinup.run ppo --env Walker2d-v2 --exp_name walker --seed 0 10 20
运行了不同随机数种子的实验,但并不会并行启动。
一些其他的命令行用法 可以参考https://spinningup.openai.com/en/latest/user/running.html#id7
加入算法
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)
所谓experimentGrid就是使用不同的超参数运行多次实验,来挑选出合适的超参数,或者比较不同超参数下算法的性能。
文中给出了使用例子
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) #使用cpu数目
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) #envname
eg.add('seed', [10*i for i in range(args.num_runs)]) #也就是seed 有 0 10 20
eg.add('epochs', 10)
eg.add('steps_per_epoch', 4000) #total step 就是10*4000
eg.add('ac_kwargs:hidden_sizes', [(32,), (64,64)], 'hid') #两种hiddensize
eg.add('ac_kwargs:activation', [torch.nn.Tanh, torch.nn.ReLU], '') #两种激活函数
eg.run(ppo_pytorch, num_cpu=args.cpu)
上面例子说明了experimentGrid的用法
eg.add(param_name, values, shorthand, in_name) #in_name指的是强制一个参数在实验中的名字
算法的输出:
model.pt里保存了agent的参数数据
tf1_save/: tensorflow下的保存数据,与pytorch类似
config.json:记录了一些超参数
python -m spinup.run plot [path/to/output_directory ...] [--legend [LEGEND ...]]
[--xaxis XAXIS] [--value [VALUE ...]] [--count] [--smooth S]
[--select [SEL ...]] [--exclude [EXC ...]]