深度强化学习实战: Step by Step创建训练环境(亲测可运行)

目录

  • 前言
  • 游戏简介
    • 1. 游戏对象
    • 2. 游戏逻辑
  • 创建场景
    • 1. 新建对象
    • 2. 更改属性Transform
    • 3. 添加材质Meterial
    • 4. 添加组件Component
    • 5. 整合训练元素
  • 创建训练环境
    • 1. 安装ml-agents
    • 2. 游戏初始化
    • 3. 设置Observation
    • 4. 接收Action&指定Reward
    • 5. 配置游戏
  • 测试游戏
  • 训练网络
    • 1. 配置文件
    • 2. 执行训练
    • 3. 可能的报错信息


前言

本文作为学习ml-agents的开篇,主要是参考ml-agents的官方文档,结合Unity和ml-agents创建一个简单的游戏作为强化学习算法的训练环境。本文中用的是官方最新发布的稳定版ml-agents release_1(Version 1.0.0)。整个DIY过程亲测可运行, 并且经过大约半小时的训练小球就足够“智能”,可以很快地找到Target, 最终效果如下:
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第1张图片

游戏简介

1. 游戏对象

  • Floor:游戏运行的场地, 是一个Plane对象
  • Ball:游戏的玩家(Player), 是一个Sphere对象
  • Target: 玩家(Player)的目标,是一个Cube对象

2. 游戏逻辑

游戏场景如下:
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第2张图片

  • 开始:Ball位于Floor中央,Target初始化到Floor上的一个随机位置
  • 操作:玩家可以操作Ball在Floor平面上进行滚动。
  • 结束:Ball碰到Target or Ball掉落Floor,则该轮游戏结束(即完成一个Episode)。

创建场景

1. 新建对象

在Hierarchy窗口中单击鼠标右键-> 3D Object->分别创建Plane、Sphere和Cube对象。分别在三个对象的Inspector中Reset Transform,如下图

深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第3张图片

2. 更改属性Transform

  1. 在Inspector窗口中把Plane的name改为Floor
  2. 把Sphere的name改为Ball,Position设置为(0,0.5,0)
  3. 把Cube的name改为Target,Position设置为(2,0.5,4)

3. 添加材质Meterial

  1. 在Project窗口选中Assets文件夹后单击鼠标右键 -> Create -> Material
  2. 创建两个Material, 分别命名为Ball Material和Target Material
  3. Ball Material中的Albedo设置为蓝色,Metallic=0.5,Smoothness=0.8; Target Material中的Albedo设置为黄色,Metallic=0,Smoothness=0.5。设置结果如下:
    深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第4张图片
  4. 分别把Ball Material和Target Material拖到对应的对象Ball和Target上。

4. 添加组件Component

单击选中Ball->在Inspector窗口的最下面单击Add Component按钮->搜索Rigidbody并添加
PS: 添加Rigidbody使Object具备物理特性,例如重力、作用力等。

5. 整合训练元素

  1. 新建空Object(Create Empty),重命名为TrainArea, 并Reset。
  2. 把Floor,Ball,Target拖动到TrainArea中进行分组(这一步操作是为了后面方便创建多个环境并行训练)

创建训练环境

1. 安装ml-agents

  1. 下载最新发布的稳定版ml-agents到本地:
git clone --branch release_1 https://github.com/Unity-Technologies/ml-agents.git
  1. 在unity中安装ml-agents包:
    在unity->Window菜单->Package Manager->点击"+", Add package from disk…->定位到下载的ml-agents/com.unity.ml-agents目录,选择package.json打开。安装完成后在Project窗口的Packages目录下出现ML Agents包
    深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第5张图片
  2. 通过PyPi安装Python包mlagents:
pip3 install mlagents

运行完成后可以通过运行"mlagents-learn --help"命令验证是否成功安装。

2. 游戏初始化

  1. 在Ball上增加script

单击选中Ball->在Inspector窗口的最下面单击Add Component按钮->搜索script, 选择New script, 命名为"BallAgent"-> 点击Create and Add按钮

创建完成后可以在Project窗口的Assets目录下找到新建的BallAgent脚本

  1. 导入需要的包

双击BallAgent脚本, 在编辑器中打开, 在首行添加

using Unity.MLAgents; 
using Unity.MLAgents.Sensors;

把基类MonoBehaviour改为Agent。删除Update()方法,保留Start()方法。更新后结果如下:
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第6张图片

  1. 编写初始化方法

初始化方法主要是两个:Start(), OnEpisodeBegin()

  • Start: 在整个程序运行前被调用,用来初始化整个游戏程序
  • OnEpisodeBegin: 在一轮游戏运行时被调用,用来初始化本轮的游戏场景

初始化代码如下:

using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;

public class BallAgent : Agent
{
    Rigidbody rBody;
    void Start () {
        // 获取Object中的Rigidbody组件,本例中即Ball的Rigidbody组件
        rBody = GetComponent<Rigidbody>();
    }

    // 获取Target对象
    // Script中的public属性会显示在Object的该Script组件中,可以通过拖拽来指定要关联的对象
    public Transform Target;
    public override void OnEpisodeBegin()
    {
        // this指代Ball Object,if语句用于判断Ball的y坐标是否为负(即Ball是否掉落Floor)
        if (this.transform.localPosition.y < 0)
        {
            // 如果Ball掉落,则在新一轮游戏开始时重置Ball到Floor中央
            this.rBody.angularVelocity = Vector3.zero;
            this.rBody.velocity = Vector3.zero;
            this.transform.localPosition = new Vector3(0, 0.5f, 0);
        }

        // 在新一轮游戏开始时,把Target放置在Floor上的一个随机位置
        Target.localPosition = new Vector3(Random.value * 8 - 4,
                                           0.5f,
                                           Random.value * 8 - 4);
    }
}

3. 设置Observation

通过CollectObservations()方法来指定Observation中所包含的信息。在本例中Observation中包含8个值,分别是Ball的位置坐标(x, y, z), Target的位置坐标(x, y, z), Ball的速度(x, z)。
注意: Unity中的坐标轴和一般用法有些不同。在Unity中X和Z坐标定义的平面是水平面,Y坐标是垂直坐标轴,如下图。所以标识速度是用(x, z)坐标。
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第7张图片
Observation代码实现如下:

public override void CollectObservations(VectorSensor sensor)
{
    // Target和Agent的位置信息
    sensor.AddObservation(Target.localPosition);
    sensor.AddObservation(this.transform.localPosition);

    // Agent的速度信息
    sensor.AddObservation(rBody.velocity.x);
    sensor.AddObservation(rBody.velocity.z);
}

4. 接收Action&指定Reward

通过OnActionReceived()方法来接收Action, 并根据执行Action后的状态变化指定获得的Reward。实现代码如下:

// speed默认为10,可以在script组件中设置
public float speed = 10;
public override void OnActionReceived(float[] vectorAction)
{
    // Actions的size = 2, 指示Ball在X轴和Z轴方向(即水平面)上的移动信号
    Vector3 controlSignal = Vector3.zero;
    controlSignal.x = vectorAction[0];
    controlSignal.z = vectorAction[1];
    // 通过在Rigidbody上作用力来使Ball移动
    rBody.AddForce(controlSignal * speed);

    // 获取Ball移动后与Target的距离
    float distanceToTarget = Vector3.Distance(this.transform.localPosition, Target.localPosition);

    // 通过Ball和Target之间的距离来判断Ball是否碰触了Target
    if (distanceToTarget < 1.42f)
    {
        // 如果Ball碰触了Target, 获得1.0的奖励,并结束本次Episode
        SetReward(1.0f);
        EndEpisode();
    }

    // 判断Ball是否掉落Floor,如果掉落则之间结束本次Episode
    if (this.transform.localPosition.y < 0)
    {
        EndEpisode();
    }
}

5. 配置游戏

强化学习的几个要素Observation, Action, Reward都在代码中设置好了,接下来需要在Unity Editor中进行配置,把这些要素都联系起来。
回到Unity窗口选中Ball对象,在Inspector中通过Add Component分别添加"Decision Requester"和"Behavior Parameters", 这两个其实是新版ML Agents包中已经封装好的脚本,我们只需要在Inspector配置就可以。

  • Decision Requester:把Decision Period设置为10,从而限制Agent在做出新的决定(Action)之前最多只可以重复10次之前的Action。通过限制Decision Period来防止Agent迟迟无所作为而拖慢了本次Episode的进度。
  • Behavior Parameters:
    1. Behavior Name改为Ball
    2. Vector Observation -> Space Size改为8
    3. Vector Action -> Space Type改为Continuous
    4. Vector Action -> Space Size改为2
  • 指定Target: 把Target对象拖动Ball Agent(Script)的Target属性处。(注意: 这里的Target和Speed属性就是我们在BallAgent脚本中定义的public属性)

整体配置如下:
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第8张图片

测试游戏

在正式训练之前我们都需要先对游戏进行一下测试,主要方法是手动玩一下游戏,以保证游戏的运行符合预期。可以通过在BallAgent中实现Heuristic()方法来实现这一功能,代码实现如下:

// 用于测试游戏,可以实现手动控制Ball的滚动
public override void Heuristic(float[] actionsOut)
{
    actionsOut[0] = Input.GetAxis("Horizontal");
    actionsOut[1] = Input.GetAxis("Vertical");
}

在BallAgent中添加完代码后,还需要在Inspector中把Behavior Parameters->Behavior Type改为"Heuristic Only",然后在Unity主窗口中点击Play按钮,进入Game窗口就可以通过键盘方向键来控制小球的滚动,从而测试游戏效果是否符合预期。

训练网络

1. 配置文件

在ml-agents/config目录下新建配置文件rollingball_config.yaml内容如下。其中首行的“Ball”就是设置的Behavior Name

Ball:
    trainer: ppo
    batch_size: 10
    beta: 5.0e-3
    buffer_size: 100
    epsilon: 0.2
    hidden_units: 128
    lambd: 0.95
    learning_rate: 3.0e-4
    learning_rate_schedule: linear
    max_steps: 5.0e5
    memory_size: 128
    normalize: false
    num_epoch: 3
    num_layers: 2
    time_horizon: 64
    sequence_length: 64
    summary_freq: 10000
    use_recurrent: false
    reward_signals:
        extrinsic:
            strength: 1.0
            gamma: 0.99

2. 执行训练

  1. 选中Ball, 在Inspector中把Behavior Parameters->Behavior Type改为"Default", 用程序控制滚动。并保存整个Scene。
  2. 在命令行中进入ml-agents目录执行如下命令。其中rollingball_config.yaml就是上一步新建的配置文件
mlagents-learn config/rollingball_config.yaml --run-id=RollingBall

执行完成后结果如下:
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第9张图片

  1. 在Unity Editor中点击Play, 就会看到Ball开始训练,如下。
    深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第10张图片
  2. 训练完成或取消Play(再点击一次Play按钮)后,可以在ml-agents/models/RollingBall(执行命令时指定的run-id)中找到训练好的模型以及训练过程中的checkpoint。
深度强化学习实战: Step by Step创建训练环境(亲测可运行)_第11张图片

3. 可能的报错信息

  • 在Unity Console中: Couldn’t connect to trainer on port 5004 using API version 1.0.0. Will perform inference instead.

  • 本机的命令行中:“The Unity environment took too long to respond. Make sure that :\n”
    mlagents_envs.exception.UnityTimeOutException: The Unity environment took too long to respond. Make sure that :
    The environment does not need user interaction to launch
    The Agents are linked to the appropriate Brains
    The environment and the Python interface have compatible versions.

如果在点击Play后出现上述报错信息可能是如下原因:
(1) ml-agents安装不完全。重新用git clone命令下载 ml-agents到本地进行安装,切记不要通过在github中用“Clone or download”按钮下载ml-agents到本地的形式安装!!!
(2) 防火墙阻止了5004端口的通信。关闭防火墙再重试。

你可能感兴趣的:(深度强化学习,强化学习,unity,机器学习,深度学习,3d游戏)