ML-Agents(二)创建一个学习环境
煦阳 人气:4
---
# ML-Agents(二)创建一个学习环境
## 一、前言
上一节我们讲了如何配置ML-Agents环境,这一节我们创建一个示例,主要利用Reinforcement Learning(强化学习)。
![image-20200315221346488](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_2003161448571111.gif)
如上图,本示例将训练一个球滚动找到随机放置的立方体,而且要避免从平台上掉下去。
本示例是基于ML-Agents官方的示例,官方有中文版和英文版两个文档,英文版的是最新的,中文版中大部分内容和英文版的一致,但也有不同,本文是基于最新版所做(v0.15.0,master分支),需要参考官方文档的也可参照如下地址食用。
英文:https://github.com/Unity-Technologies/ml-agents/tree/masterhttps://img.qb5200.com/download-x/docs
中文:https://github.com/Unity-Technologies/ml-agents/blob/masterhttps://img.qb5200.com/download-x/docs/localized/zh-CNhttps://img.qb5200.com/download-x/docs/Learning-Environment-Create-New.md
## 二、概述
在Unity项目中使用ML-Agents涉及以下基本步骤:
1. 创建一个容纳agent的环境。该环境可以从包含少量对象的简单物理模拟环境到整个游戏或生态系统,环境的样式可以多种多样;
2. 实现Agent子类。Agent子类定义了必要的代码以供agent用于观测自身环境、执行指定动作以及计算用于强化训练的奖励。你同样可以实现可选方法,从而在agent完成任务或任务失败时重置agent;
3. 将实现Agent子类的脚本加到适当的GameObject上,当该对象在场景中,即代表对应agent在模拟环境中了。
(**PS.**在官方中文文档中,第2,3步需要实现Academy子类和Brain,但在新版中,这两个东西已经不需要在场景里定义了,所以比较重要的就是这个Agent子类,基本学习逻辑都在这里)
## 三、设置Unity项目
第一步,我们先新建一个Unity项目,并且将ML-Agents包导入到里面:
1. 打开Unity,新建一个项目随意叫个名字,例如“RollerBall”;
![image-20200315223810312](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316143736image-20200315223810312.png)
2. 在Unity菜单“Edit”->“Project Settings”,在弹出的窗口中,找到“Player”,将“Api Compathbility Level”改为“.NET 4.x”,如下图;
![image-20200315224402045](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316143819image-20200315224402045.png)
![image-20200315224522187](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316143909image-20200315224522187.png)
3. 在上一节中,我们已经将ml-agents代码库克隆到了本地,如果没有克隆,请参考上一篇“Unity ML-Agents v0.15.0(一)环境部署与试运行”中的**五、1**,这里我们默认大家都是已经克隆了库,则在Unity中需要将ML-Agents插件导入Unity中。我这里的版本是Unity2019.2,方法如下:
- 在项目根目录中找到Packages文件夹;
![image-20200315224936858](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316143953image-20200315224936858.png)
- 文件夹中有一个“manifest.json”的文件,编辑它,这个就是工程中的Packages包集合,在最后加入"com.unity.ml-agents" : "file:D:/Unity Projects/ml-agents/com.unity.ml-agents",这里**file:**后是你自己克隆的ml-agents源码路径,别照抄我的哦,除非你也是这个路径- -,如下图;
![image-20200315225658933](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316144030image-20200315225658933.png)
修改后保存,在切到Unity中,如果路径正确,则会出现导入package包的画面,在工程的Packages文件夹下也会成功出现“ML Agents”文件夹,如下图:
![image-20200315230214543](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316144103image-20200315230214543.png)
4. 创建环境
下面,我们创建一个简单的ML-Agent环境。该环境的“physical”组件包括一个Plane(充当agent移动的地板)、一个Cube(充当agent寻找的目标)和一个Sphere(表示agent本身)。
- 创建地板
- 在 Hierarchy 窗口中右键单击,选择 3D Object > Plane。
- 将游戏对象命名为“Floor”。
- 选择 Plane 以便在 Inspector 窗口中查看其属性。
- 将 Transform 设置为 Position = (0,0,0)、Rotation = (0,0,0)、Scale = (1,1,1)。
- 修改Plane材质,变的好看点。
以上过程我都是复制的,其实就是创建一个Plane,然后换个好看的材质就行,随意定义一个都OK。
![image-20200315231103610](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316144131image-20200315231103610.png)
- 创建目标立方体
- 在 Hierarchy 窗口中右键单击,选择 3D Object > Cube。
- 将游戏对象命名为“Target”
- 选择 Target 以便在 Inspector 窗口中查看其属性。
- 将 Transform 设置为 Position = (3,0.5,3)、Rotation = (0,0,0)、Scale = (1,1,1)。
- 修改Cube材质。
![image-20200315231522024](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316144207image-20200315231522024.png)
- 添加Agent球体
- 在 Hierarchy 窗口中右键单击,选择 3D Object > Sphere。
- 将游戏对象命名为“RollerAgent”
- 选择 Target 以便在 Inspector 窗口中查看其属性。
- 将 Transform 设置为 Position = (0,0.5,0)、Rotation = (0,0,0)、Scale = (1,1,1)。
- 在 Sphere 的 Mesh Renderer 上,展开 Materials 属性并将默认材质更改为 *checker 1*。
- 单击 **Add Component**。
- 向 Sphere 添加 Physics/Rigidbody 组件。(添加 Rigidbody)
![image-20200315231748255](https://images.cnblogs.com/cnblogs_com/gentlesunshine/1665373/o_200316144234image-20200315231748255.png)
OK,以上过程就将Unity中的三维环境创建好了,下面我们来实现Agent。
## 四、实现Agent
在官方中文文档中还有“实现Academy”及“添加Brain”,最新版里已经不需要了!直接设置Agent就行。
要创建Agent:
1. 选择 RollerAgent 游戏对象以便在 Inspector 窗口中查看该对象。
2. 单击 **Add Component**。
3. 在组件列表中单击 **New Script**(位于底部)。
4. 将该脚本命名为“RollerAgent”。
5. 单击 **Create and Add**。
然后,编辑新的`RollerAgent`脚本:
1. 打开`RollerAgent`脚本;
2. 令`RollerAgent`继承`Agent`类,同时引用`using MLAgents`和`using MLAgents.Sensors`命名空间;
3. 删除`Update()`方法,先保留`Start()`方法之后要用。
到目前为止,以上的步骤都是为了将ML-Agents添加到任何Unity项目中而需要的基本步骤。接下来,我们将添加逻辑,使我们的agent能够利用reinforcement learning(强化学习)技术学习找到立方体。
### 初始化和重置Agent
当agent(球体)到达目标位置(方块)后,会将自己标记为完成状态,而agent的重置函数(Reset)会将方块再重新移动到新的位置。另外,如果agent从平台上掉落,也会触发重置函数,使得agent初始化,目标位置也将随机刷新。
为了重置agent的速度(以及之后给它施加力移动),我们需要引用到球体的`Rigidbody`组件。这个组件的引用就可以写到`Start()`方法中,以以上的逻辑,我们的`RollerAgent`脚本如下:
```c#
using MLAgents;
using MLAgents.Sensors;
using UnityEngine;
public class RollerAgent : Agent
{
public Transform Target;//方块
public float speed = 10;//小球移动速度
private Rigidbody rBody;//球刚体
private void Start()
{
rBody = GetComponent
加载全部内容