2018.5.27
这个环境是对之前文章的 应用。 环境都安装完了,现在就让这个Demo跑起来。
本教程介绍在 Unity 中打开 ML-Agents 示例环境、 构建 Unity 可执行文件、在其中训练 agent 以及 最终将经过训练的模型嵌入到 Unity 环境中的端到端过程。
ML-Agents 包含大量示例环境, 您可以通过这些环境来了解 ML-Agents 的 不同使用方式。这些环境也可以用作新环境的模板 或用作测试新 ML 算法的方法。阅读本教程后, 您应该能够了解并构建示例环境。
本演练过程将使用 3D Balance Ball 环境。3D Balance Ball 包含 大量平台和球(它们都是彼此的副本)。 每个平台都会试图通过水平或垂直旋转的方式 防止球掉落。在这种环境下,平台是一个 agent, 可以在对球进行平衡的每一步中获得奖励。agent 也会 因为掉球而得到负奖励(惩罚)。训练过程的 目标是让平台学会绝不掉球。
让我们开始吧!
安装
为了安装和设置 ML-Agents、Python 所依赖的库和 Unity 软件, 请参阅安装说明。
了解 Unity 环境 (3D Balance Ball)
agent 是一种观测并与_环境_交互的 自主参与者 (actor)。在 ML-Agent的语境下,环境是一个包含一个 Academy, 一个或多个 Brain, 一个或多个Agent, Agent 与其他实体交互的场景。
**注意:**在 Unity 中,场景内所有元素的基础对象均为 游戏对象(GameObject)。游戏对象本质上是其他任何元素 (包括行为、图形、物理等)的容器。要查看组成游戏对象的组件, 请在 Scene 窗口中选择 GameObject,然后打开 Inspector 窗口。Inspector 会显示游戏对象上的每个组件。
在打开 3D Balance Ball 场景后,您可能会首先注意到它包含的 不是一个平台,而是多个平台。场景中的每个平台都是 独立的 agent,但它们全部共享同一个 brain。3D Balance Ball 通过 这种方式可以加快训练速度,因为所有 12 个 agent 可以并行参与训练任务。
Academy
在这个示例场景中的 Academy 对象是 Ball3DAcademy 游戏对象。 当您在 Inspector 中查看该 Academy 组件时,可以看到若干 用于控制环境工作方式的属性。例如,Inspector中可以看到 Training 和 Inference Configuration 属性, 在其中我们可以设置之后生成的 Unity 可执行文件的 图形和 Time Scale 属性。Academy 在训练期间使用 Training Configuration,而在不训练时使用 Inference Configuration。(Inference 等同于不进行训练的任何时候,此时 agent 可以使用经过训练的模型控制,或用写定的代码控制,或让玩家直接控制。) 通常情况下,您需要为 Training configuration 设置低图形质量 和高Time Scale,而为 Inference Configuration 设置高图形质量和 1.0
的Time Scale。
**注意:**如果您想在训练期间观测环境,则可以调整 Inference Configuration 设置来使用更大的窗口和更接近 1:1 的时间刻度。当你要正式训练时一定要重新设置这些参数; 否则,训练可能需要很长时间。
对于环境,另一个需要关注的方面是 Academy 的实现。 由于 Academy 基类是抽象的,您必须始终定义一个子类。 您可以实现以下三个函数,但这些函数都是可选的:
- Academy.InitializeAcademy() — 启动环境时调用一次。
- Academy.AcademyStep() — 在 Agent.AgentAction() 之前(以及 agent 收集其观测结果之后)的每个模拟步骤调用。
- Academy.AcademyReset() — 在 Academy 开始或重新开始模拟 (包括第一次)时调用。
3D Balance Ball 环境不使用这些函数(每个 agent 在需要时 会自行重置),但许多环境都会使用这些函数来 控制 agent 周围的环境。
Brain
场景中的 Ball3DBrain 游戏对象包含 Brain 组件, 是 Academy 对象的子级。(场景中的所有 Brain 对象都必须是 Academy 的子级。)3D Balance Ball 环境中的所有 agent 使用 同一个 Brain 实例。 Brain 不存储关于 agent 的任何信息, 只是将 agent 收集的观测结果发送到决策过程, 然后将所选的动作返回给 agent。因此,所有 agent 可共享 同一个 brain,但会独立行动。Brain 设置可以提供很多 关于 agent 工作方式的信息。
Brain Type 决定了 agent 如何决策。 External 和 Internal 类型需要协同使用:训练 agent 时使用 External, 而在采用经过训练的模型时使用 Internal。 Heuristic brain 允许您通过扩展 Decision 类来对 agent 的逻辑进行 手动编码。最后,Player brain 可让您将键盘命令 映射到动作,这样在测试 agent 和环境时 会非常有用。如果这些类型的 brain 都不能满足您的需求,您可以 实现自己的 CoreBrain 来创建自有的类型。
在本教程中,进行训练时,需要将 Brain Type 设置为 External; 当您将经过训练的模型嵌入到 Unity 应用程序中时,需要将Brain Type 更改为 Internal。
向量观测空间
在决策之前,agent 会收集有关自己在环境中所处的状态的 观测结果。ML-Agents 将观测分为两类: Continuous 和 Discrete。Continuous 向量观测空间 会收集浮点数向量中的观测结果。Discrete 向量观测空间是一个状态表的索引。大多数示例环境 都使用连续的向量观测空间。
3D Balance Ball 示例中所用的 Brain 实例使用 State Size 为 8 的 Continuous 向量观测空间。这意味着 包含 agent 观测结果的特征向量包含八个元素: 平台旋转的 x
和 z
分量以及球相对位置和 速度的 x
、y
和 z
分量。(观测结果值 在 agent 的 CollectObservations()
函数中进行定义。)
向量运动空间
brain 以动作的形式向 agent 提供指令。与状态 一样,ML-Agents 将动作分为两种类型:Continuous 向量运动空间是一个可以连续变化的数字向量。向量 每个元素的含义都是由 agent 逻辑定义的(PPO 训练过程是一个了解agent的哪种状态更好的过程,这个过程是通过学习不同agent的不同状态会对应多少奖励来实现的)。 例如,一个元素可能表示施加到 agent 某个RigidBody
上的力或扭矩。Discrete 向量运动空间将其动作 定义为一个表。提供给 agent 的具体动作是这个表的 索引。
根据设计,3D Balance Ball 示例会使用这两种类型的向量运动 空间。 您可以尝试使用两种设置进行训练,观测是否有 差异。(使用离散运动空间时将 Vector Action Space Size
设置为 4, 而使用连续运动空间时将其设置为 2。)
Agent
Agent 是在环境中进行观测并采取动作的参与者。 在 3D Balance Ball 环境中,Agent 组件被放置在 12 个 平台游戏对象上。基础 Agent 对象有一些影响其行为的 属性:
- Brain — 每个 Agent 必须有一个 Brain。brain 决定了 agent 如何 决策。3D Balance Ball 场景中的所有 agent 共享同一个 brain。
- Visual Observations — 定义 agent 用来观测其环境的 任何 Camera 对象。3D Balance Ball 不使用摄像机观测。
- Max Step — 定义在 agent 决定自己完成之前可以发生多少个 模拟步骤。在 3D Balance Ball 中,agent 在 5000 步之后重新开始。
- Reset On Done — 定义 agent 是否在完成时重新开始。 3D Balance Ball 将此项设置为 true,因此 agent 在达到 Max Step计数后或在掉球后重新开始。
也许 agent 更有趣的方面在于 Agent 子类的 实现。在创建 agent 时,您必须扩展 Agent 基类。 Ball3DAgent 子类定义了以下方法:
- Agent.AgentReset() — Agent 重置时(包括会话开始时) 调用。Ball3DAgent 类使用重置函数来重置 平台和球。该函数会将重置值随机化,从而使 训练不局限于特定的开始位置和平台 姿态。
- Agent.CollectObservations() — 在每个模拟步骤调用。负责 收集 agent 对环境的观测结果。由于分配给 agent 的 Brain 实例设置为状态大小为 8 的连续向量观测空间, 因此
CollectObservations()
必须调用 8 次AddVectorObs
。 - Agent.AgentAction() — 在每个模拟步骤调用。接收 brain 选择的 动作。Ball3DAgent 示例可以处理连续和离散 运动空间类型。在此环境中,两种状态类型之间实际上 没有太大的差别:这两种向量运动空间在每一步都会 导致平台旋转发生小变化。
AgentAction()
函数 为 agent 分配奖励;在此示例中,agent 在每一步 将球保持在平台上时收到较小的正奖励, 而在掉球时收到更大的负奖励。agent 在掉球时还会被标记为 完成状态,因此会重置一个用于下一模拟步骤的 新球。
构建环境
第一步是打开包含 3D Balance Ball 环境的 Unity 场景:
- 启动 Unity。
- 在 Projects 对话框上,选择窗口顶部的 Open 选项。
- 使用随后打开的文件对话框,找到 ML-Agents 项目内的
unity-environment
文件夹,然后单击 Open。 - 在
Project
窗口中,找到文件夹Assets/ML-Agents/Examples/3DBall/
。 - 双击
Scene
文件以加载包含 Balance Ball 环境的 场景。
由于我们要建立此环境来进行训练,因此我们需要 将 agent 使用的 brain 设置为 External。这样 agent 在 进行决策时能够与外部训练过程进行通信。
- 在 Scene 窗口中,单击 Ball3DAcademy 对象旁边的三角形 图标。
- 选择其子对象
Ball3DBrain
。 - 在 Inspector 窗口中,将 Brain Type 设置为
External
。
接下来,我们希望设置场景以便在训练过程启动我们的环境可执行文件时 正确播放场景。这意味着:
- 环境应用程序在后台运行
- 没有对话需要互动
- 正确的场景会自动加载
- 打开 Player Settings(菜单:Edit > Project Settings > Player)。
- 在 Resolution and Presentation 下方:
- 确保选中 Run in Background。
- 确保 Display Resolution Dialog 设置为 Disabled。
- 打开 Build Settings 窗口(菜单:File > Build Settings)。
- 选择目标平台。 -(可选)选择“Development Build”以便 记录调试消息。
- 如果 Scenes in Build 列表中显示了任何场景,请确保 唯一选中的是 3DBall Scene。(如果该列表为空,则表示 仅当前场景包含在编译中)。
-
单击 Build: a. 在 File 对话框中,导航至 ML-Agents 目录中的
python
文件夹。 b. 指定文件名,然后单击 Save。 比如文件名是 3DBall.exe 这个名称后面要用到的呦~
使用 Reinforcement Learning(强化学习)来训练 Brain
有了一个包含模拟环境的 Unity 可执行文件后,现在我们 可以执行训练。为了首先确保您的环境和 Python API 能正常工作,您可以使用 python/Basics
Jupyter 笔记本。 此笔记本包含了 API 功能的简单演练。 在 Basics
中,务必将 env_name
设置为您先前构建的 环境文件的名称。
使用 PPO 进行训练
为了训练 agent 对球进行正确平衡,我们将使用一种称为 Proximal Policy Optimization (PPO) 的 Reinforcement Learning(强化学习)算法。 与其他许多 RL 算法相比,这种算法经证明是一种安全、 有效且更通用的方法,因此我们选择它作为与 ML-Agents 一起使用的示例算法。有关 PPO 的更多信息, 请参阅 OpenAI 近期发布的博客文章, 其中对 PPO 进行了说明。
为了训练 Balance Ball 环境中的 agent,我们将使用 Python 包。我们提供了一个名为 learn.py
的方便的 Python 包装脚本,此脚本会接受用于配置训练和预测阶段的参数。
我们将向这个脚本传递我们刚才构建的环境可执行文件的路径。(可选)我们可以 使用 run_id
来识别实验并创建用于存储模型和摘要统计信息的文件夹。当使用 TensorBoard 来观测训练统计信息时,将每次训练的此项设置为顺序值 将会很有用。也就是说,第一次训练时为“BalanceBall1”, 第二次训练时为“BalanceBall2”,依此类推。如果不这样做,每次训练的 摘要信息都会保存在同一个目录中,并且全部将包含在 同一个图中。
总之,转到命令行,进入 ml-agents
目录并输入:
python3 python/learn.py <env_file_path> --run-id=<run-identifier> --train
--train
标志告诉 ML-Agents 以训练模式运行。env_file_path
应该是刚才创建的 Unity 可执行文件的路径。
比如,3DBall 是刚刚导出的用于训练的PC包文件名, 而test是我随便写的(训练完成生成的文件名有这个test名称在里面) : C:\Users\Administrator\Downloads\ml-agents-master\python>python learn.py 3DBall --run-id=test --train
观测训练进度
开始使用 learn.py
按照前面部分所述的方式进行训练后,ml-agents
文件夹将 包含一个 summaries
目录。为了更详细地观测训练过程, 您可以使用 TensorBoard。从命令行中运行:
tensorboard --logdir=summaries
然后导航至 localhost:6006
。
从 TensorBoard 中,您将看到摘要统计信息:
- Lesson - 只有在进行 课程训练时才有意义。 3D Balance Ball 环境中不使用此项。
- Cumulative Reward - 所有 agent 的平均累积场景奖励。 在成功训练期间应该增大。
- Entropy - 模型决策的随机程度。在成功训练过程中 应该缓慢减小。如果减小得太快,应增大
beta
超参数。 - Episode Length - 所有 agent 在环境中每个场景的 平均长度。
- Learning Rate - 训练算法搜索最优 policy 时需要多大的 步骤。随着时间推移应该减小。
- Policy Loss - policy 功能更新的平均损失。与 policy (决定动作的过程)的变化程度相关。此项的幅度 在成功训练期间应该减小。
- Value Estimate - agent 访问的所有状态的平均价值估算。 在成功训练期间应该增大。
- Value Loss - 价值功能更新的平均损失。与模型 对每个状态的价值进行预测的能力相关。此项 在成功训练期间应该减小。
将经过训练的 Brain 嵌入到 Unity 环境中(测试功能)
一旦训练过程完成,并且训练过程保存了模型 (通过 Saved Model
消息可看出),您便可以将该模型添加到 Unity 项目中, 然后将其用于 brain 类型为 Internal 的 agent。
设置 TensorFlowSharp 支持
由于 TensorFlowSharp 支持仍处于实验阶段,因此默认情况下会 将其禁用。为了启用这项支持,必须遵循以下步骤。请注意, 只有完成这些步骤后才能使用 Internal
Brain 模式。
- 确保 TensorFlowSharp 插件位于
Assets
文件夹中。 可在 此处下载一个包含 TF# 的 Plugins 文件夹。 下载后,双击并将其导入。您可以在 Project 选项卡中 (位于Assets
>ML-Agents
>Plugins
>Computer
下) 检查 TensorFlow 的相关文件来查看是否安装成功 - 转到
Edit
>Project Settings
>Player
- 对于每个目标平台 (
PC, Mac and Linux Standalone
、iOS
或Android
): 1.转到Other Settings
。 2.选择Scripting Runtime Version
为Experimental (.NET 4.6 Equivalent)
3.在Scripting Defined Symbols
中,添加标志ENABLE_TENSORFLOW
。 输入后,按 Enter。 - 转到
File
>Save Project
- 重新启动 Unity Editor。
将经过训练的模型嵌入到 Unity 中
- 经过训练的模型存储在
ml-agents
文件夹中的models/<run-identifier>
内。训练 完成后,该位置会有一个<env_name>.bytes
文件,其中的<env_name>
是训练期间使用的可执行文件的 名称。 - 将
<env_name>.bytes
从python/models/ppo/
移入unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/
。 - 打开 Unity Editor,然后选择
3DBall
场景(如上所述)。 - 从 Scene 层级视图中选择
Ball3DBrain
对象。 - 将
Type of Brain
更改为Internal
。 - 将
<env_name>.bytes
文件从 Editor 的 Project 窗口拖入3DBallBrain
Inspector 窗口中的Graph Model
占位区域。 - 按 Editor 顶部的 Play 按钮。
如果您正确执行了这些步骤,您现在应该能够 看到 Unity 编辑器中有这个用于控制平衡球行为的 训练模型。从这里开始,您便可以重新构建 Unity 的可执行文件, 并单独运行该可执行文件,在其中内置 agent 新学到的行为。