Spinning up包含下列算法

  • VPG
  • TRPO
  • PPO
  • DDPG
  • TD3
  • SAC

以上算法均应用了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。

On-policy 算法

Vanilla Policy Gradient是最基础 入门级的DRL算法,因为它早于DRL的出现,导致了后来TRPO和PPO的提出。

这一系列算法的特点是 on-policy, 也就是他们不使用旧的数据,这样就会导致他们的样本效率(sample efficiency)较低,但有一个好的方面,就是这些算法可以直接优化你想要的目标,也就是policy的性能表现,从数学角度上讲,这些算法需要on-policy数据来进行更新,因此,这些算法牺牲了样本效率,而具有更好的稳定性,但从VPG到TRPO再到PPO,技术仍在客服样本效率的缺点。

Off-policy 算法

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
这些参数在源文档中有详细说明,后续我们将直接阅读源码

使用pytorch或 tensorflow运行

 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

运行了不同随机数种子的实验,但并不会并行启动。

一些其他的命令行用法 可以参考spinningup.openai.com/e

从脚本文件运行

加入算法

 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

所谓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指的是强制一个参数在实验中的名字

实验输出

算法的输出:

  • pyt_save/: pytorch only,保存训练的agent和值函数

model.pt里保存了agent的参数数据

  • tf1_save/: tensorflow下的保存数据,与pytorch类似
  • config.json:记录了一些超参数
  • progress.txt:记录了训练的metrics
  • vars.pkl :包含算法所有状态的pickle文件

绘制结果

 python -m spinup.run plot [path/to/output_directory ...] [--legend [LEGEND ...]]
     [--xaxis XAXIS] [--value [VALUE ...]] [--count] [--smooth S]
     [--select [SEL ...]] [--exclude [EXC ...]]