强化学习教程资源:https://stable-baselines3.readthedocs.io/en/master/guide/rl.html
SB3教程:https://github.com/araffin/rl-tutorial-jnrr19/blob/sb3/1_getting_started.ipynb
与有固定数据集的监督学习相比,强化学习用来训练智能体的数据来自于智能体与环境的交互。由于强化学习每次得到的结果不一致,这就需要我们去取得一个量化的结果。
好的结果依赖于恰当的超参数,像PPO、SAC、TD3 这些最近的算法只需要我们调整很少的参数,但不要指望默认参数适用于任何环境。
所以,非常推荐看看RL zoo 来学习调参(推荐使用其中的自动超参数优化)。
自定义环境时,要标准化到智能体中的输入,并留意其他环境中常见的预处理操作。
目前RL的限制
-
免模型算法的采样效果不是很好,经常需要学习百万次交互的样本,所以目前大多数RL算法只在仿真和游戏中实现。
-
为了在普通的设备上取得更好的性能,应该增加智能体的训练步数
-
为了实现期望的表现,经常使用专家知识(expert knowledge)来设计一个恰当的奖励函数。
(一个关于 reward shaping 的例子:Deep Mimic paper,它结合模仿学习和强化学习来做杂技动作。) -
最后是训练的不稳定性,你可以看到在训练时性能急剧下降,尤其体现在
DDPG
中,这也是TD3
想要去解决这个问题的原因。其他的方法例如TRPO
和PPO
,使用了信任域(trust region) ,通过避免过大的更新来减小这个问题。
如何评价一个RL算法
当评价你的智能体或者对比实验结果时,要注意 environment wrappers,episode rewards 或 lengths 的改变也可能影响评价结果。建议浏览 Evaluation Helper 章节中evaluate_policy
的帮助函数.
由于大多数算法在训练中使用探索噪声(exploration noise),我们需要一个独立的测试环境去评价智能体。为了得到一个好的评价结果,推荐周期性地评价智能体n
个回合 (通常 5<n<20) 和并计算每回合的平均奖励。
SB3 提供
EvalCallback
接口实现这样的 evaluation, 详情查看 Callbacks 章节。对于一些默认使用随机性策略的算法(如 A2C、PPO),在调用
.predict()
方法时可以设置deterministic=True
,通常会有更好的表现。
算法选择
-
根据动作空间是离散还是连续的来选择
例如 DQN 只支持离散动作,SAC 仅限于连续动作
- 单进程离散动作 Discrete Actions
使用扩展的DQN算法(如
QR-DQN
、double DQN, prioritized replay, …)。DQN训练的更慢,但却是最有效的采样方式(because of its replay buffer)。- 多进程离散动作 MultiDiscrete Actions
推荐尝试PPO或A2C
- 单进程连续动作 Continuous Actions
Current State Of The Art (SOTA),即目前的最优算法:SAC、TD3、TQC
为了得到最好的结果,可以使用RL zoo内的超参数
- 多进程连续动作 MultiContinuous Actions
推荐尝试PPO、TRPO、A2C,同样建议使用RL zoo内的超参数
-
根据是否需要并行训练来选择
如果真实的训练时间(wall clock training time)很重要,应该多使用 A2C 和 PPO
Take a look at the Vectorized Environments to learn more about training with multiple workers.
-
Goal Environment
假如你的环境遵循了
GoalEnv
接口(参考 HER),那么应该根据 action space 来选择使用 HER + (SAC/TD3/DDPG/DQN/QR-DQN/TQC)。另外注意batch_size
是 HER 一个重要的超参数。
创建自定义环境
想去学习如何创建一个自定义环境,戳->page
创建自定义gym环境的示例: colab notebook
一些建议:
- 当你知道边界的时候,尽可能规范化你的observation space
- 规范化 action space,当动作连续时让该空间对称,例如缩放动作到[-1, 1]
- start with shaped reward (i.e. informative reward) and simplified version of your problem
- 使用随机动作来检测你的环境是否能正常工作,并且遵循gym接口
注意创建自定义环境时要避免打破马尔科夫假设,并正确处理因超时而导致的Termination(每回合中最大step数目)。例如,如果在action和observation之间存在一些延时(例如wifi通讯),应该给一个历史observations作为输入。
由于 timeout (到达每回合最大步数) 引起的 Termination 需单独处理,你需要手动将 key 添加到 dict: info["TimeLimit.truncated"] = True
. 如果使用 gym 的 TimeLimit
wrapper, 将会自动完成这一操作。
You can read Time Limit in RL or take a look at the RL Tips and Tricks video for more details.
一个用于检查环境是否无误的方法:
from stable_baselines3.common.env_checker import check_env
env = CustomEnv(arg1, ...)
# It will check your custom environment and output additional warnings if needed
check_env(env)
快速在环境中使用随机的智能体,检测你的环境是否能正常工作:
env = YourEnv()
obs = env.reset()
n_steps = 10
for _ in range(n_steps):
# Random action
action = env.action_space.sample()
obs, reward, done, info = env.step(action)
if done:
obs = env.reset()
为什么需要标准化 action space?
对于连续的动作,大多数强化学习算法依赖于一个高斯分布(以0为中心,标准差为1),所以假如你的环境使用了未被标准化的动作空间,会威胁到学习过程,并难以debug。
使用高斯的另一个后果是动作范围不受限制,所以通常使用 clipping 操作使其保持在一个合理范围内。
更好的解决方案是使用 squashing function (cf SAC
) 或 Beta distribution (cf issue #112).
上述对
DDPG
和TD3
无效,因为它们不依赖任何概率分布( probability distribution).
运行一个RL算法的Tips
当你尝试通过运行算法去复现一个 RL paper 时,推荐看一下 the nuts and bolts of RL research by John Schulman (video).
We recommend following those steps to have a working RL algorithm:
- Read the original paper several times
- Read existing implementations (if available)
- Try to have some “sign of life” on toy problems
- 在越来越复杂的环境中运行进一步验证算法的可行性(可以将结果与 RL zoo 进行比较). 在这一步骤通常需要进行超参数优化
You need to be particularly careful on the shape of the different objects you are manipulating (a broadcast mistake will fail silently cf. issue #75) and when to stop the gradient propagation(梯度传播).
逐渐困难的连续动作环境:
- Pendulum (easy to solve)
- HalfCheetahBullet (medium difficulty with local minima and shaped reward)
- BipedalWalkerHardcore (if it works on that one, then you can have a cookie)
逐渐困难的离散动作环境:
- CartPole-v1 (easy to be better than random agent, harder to achieve maximal performance)
- LunarLander
- Pong (one of the easiest Atari game)
- other Atari games (e.g. Breakout)