65.9K
CodeProject 正在变化。 阅读更多。
Home

使用近端策略优化 (PPO) 训练人形 AI 机器人行走

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2020 年 9 月 29 日

CPOL

4分钟阅读

viewsIcon

10745

在本系列文章中,我们将开始专注于 PyBullet 提供的一个特定的、更复杂的环境:人形,其中我们必须训练一个类人代理在两条腿上行走。

引言

人形环境在强化学习中的历史

人形环境最初由 Tassa 等人在他们 2012 年的论文“通过在线轨迹优化合成和稳定复杂行为。"中创建。

作为该论文的一部分,作者创建了 MuJoCo 物理模拟器。 大多数关于使用强化学习学习人形运动的研究都使用 MuJoCo 环境。

但是,MuJoCo 是商业软件,您需要获得许可证才能使用它。 有免费的学术许可证和 30 天试用许可证,但在这些文章中,我们将使用一个类似的人形环境,该环境已基于开源 Bullet 物理模拟引擎创建。

Bullet 人形环境比 MuJoCo 的环境更具挑战性,因为它基于 Roboschool 所做的一些调整,施加了更实际的能量成本,这些能量成本会从奖励中扣除。 由于这些差异,我们在这些文章中获得的奖励与从 MuJoCo 获得的奖励无法直接比较。

和以前一样,让我们检查一下环境,看看我们将面临什么。

>>> import gym
>>> import pybullet_envs
>>> env = gym.make(HumanoidBulletEnv-v0')
>>> env.observation_space
Box(44,)
>>> env.action_space
Box(17,)

因此,这代表了我们迄今为止所见过的最复杂环境的又一步提升,将观察空间的维度从 Ant 中的 28 增加到 44,更重要的是,将动作空间从 8 增加到 17。

还有一个小小的稳定性问题。 Ant 本质上非常稳定,每个角都有一个腿。 相比之下,人形机器人必须靠两条腿保持平衡。 策略必须做很多工作才能阻止代理倒下,更不用说学习走路了。

近端策略优化 (PPO) 简介

近端策略优化最初由 Schulman 等人在论文 近端策略优化算法 中提出。

PPO 收集某个设定水平长度的轨迹(即,根据策略的当前状态,执行它认为正确的动作),然后在这些轨迹的小批量上执行指定数量的 epoch 的随机梯度下降。

请注意,PPO 是一种 on-policy 算法,这意味着在每个阶段,它都必须使用从当前部分训练的策略获得的结果。 它不像我们在其他算法中看到的那样,通过从旧结果的缓冲区中进行采样来工作。

代码

该代码遵循我在其他地方使用的典型模式。 训练参数基于此调整后的示例的参数,该示例已知与人形环境配合良好。

我们覆盖的特定学习参数如下

  • gamma – 马尔可夫决策过程的折扣因子。
  • lambda – 传递给广义优势估计器 (GAE) 的 lambda 参数。 这代表了偏差和方差之间的权衡。
  • clip_param – PPO 裁剪参数,代理损失函数使用它来防止策略更新过于激进。
  • kl_coeff – KL 散度惩罚的初始系数。 与 clip_param 类似,它用于防止策略变化太快。 它与 kl_target 参数一起使用,尽管我们将其保留为其默认值 0.01。
  • num_sgd_iter – 每个训练批次要执行的 epoch 数。 SGD 指的是随机梯度下降。
  • lr – 学习率。 在这种情况下,执行随机梯度下降时步长应该有多大。
  • sgd_minibatch_size – 每个 epoch 中的小批量大小。
  • train_batch_size – 传递给随机梯度下降的每个批次中的样本数。
  • model/free_log_std – RLlib 文档中对该参数的描述是“对于 DiagGaussian 动作分布,使模型输出的后半部分成为浮动偏差变量,而不是与状态相关。 这仅在使用默认的完全连接网络时才有效。” 我不声称理解这意味着什么!
  • batch_mode – 是否从 worker 中推出截断的或完整的 episode。
  • observation_filter – 我们应用 MeanStdFilter,它根据它已经看到的状态来规范化观察。
import pyvirtualdisplay

_display = pyvirtualdisplay.Display(visible=False, size=(1400, 900))
_ = _display.start()

import ray
from ray import tune
from ray.rllib.agents.ppo import PPOTrainer
import pybullet_envs

ray.shutdown()
ray.init(include_webui=False, ignore_reinit_error=True)

ENV = 'HumanoidBulletEnv-v0'
import gym
from ray.tune.registry import register_env
def make_env(env_config):
    import pybullet_envs
    return gym.make('HumanoidBulletEnv-v0')
register_env('HumanoidBulletEnv-v0', make_env)
TARGET_REWARD = 6000
TRAINER = PPOTrainer

tune.run(
    TRAINER,
    stop={"episode_reward_mean": TARGET_REWARD},
    config={
        "env": ENV,
        "num_workers": 21,
        "num_gpus": 1,
        "monitor": True,
        "evaluation_num_episodes": 50,
        "gamma": 0.995,
        "lambda": 0.95,
        "clip_param": 0.2,
        "kl_coeff": 1.0,
        "num_sgd_iter": 20,
        "lr": .0001,
        "sgd_minibatch_size": 32768,
        "train_batch_size": 320_000,
        "model": {
            "free_log_std": True,
        },
        "batch_mode": "complete_episodes",
        "observation_filter": "MeanStdFilter",
    }
)

我让它运行了很长时间:使用 22 个 CPU 核心运行了 67 个小时。 您可能更喜欢将 TARGET_REWARD 限制为 2000。

视频

正如您所看到的,代理已经学会了向后倾斜并小跑前进。

下次

下一篇文章中,我们将调整我们的代码以使用不同的算法:Soft Actor-Critic (SAC) 来训练人形环境。

© . All rights reserved.