在Unity中创建自己的A.I.

这篇博客是跟着Create your own A.I. in Unity | ML-Agents Tutorial 2020这个视频(油管视频),一步一步使用ML-Agents在Unity中创建自己的强化学习环境。
项目地址
效果:
小球避开左右墙,从斜坡上跳到目标位置。
在这里插入图片描述
在这里插入图片描述

那我们就开始吧~

配置环境

系统:win10
Unity Version:2019.3.12
ML-Agents Version:Release 4 ,July 15, 2020
tensorflow:1.7.1
python:3.6

环境配置可以参考我的上一个博客~

创建训练环境

新建项目

打开Unity Hub,创建一个3D新项目,命名为BallJump,点击创建。
在这里插入图片描述
得到这样的界面
在这里插入图片描述

下载packages

新建的项目先下载需要的package,ML-Agent(1.0.0)和ProBuilder(4.2.3)
首先,打开Package Manager
在这里插入图片描述
让它显示之前的版本
在这里插入图片描述
搜索ML Agents
(注意:当我使用Unity 2018.3.14版本时,我在Package Manager中找不到ML Agents项目,不确定是否和版本有关,因此我下了和视频中一样的Unity版本 2019.3.12,解决了这一问题)
点击ML左边的小箭头,找到之前的1.0.0版本,点击install安装
0.0
同样的,安装ProBuilder(4.2.3)
在这里插入图片描述

创建场景

创建文件夹

首先在Asserts目录下创建4个新的文件夹,并重命名为Brains(存放训练好的网络),Materials(存放材质),Prefabs(存放整体外观),Scripts(存放代码)在这里插入图片描述

共有五个文件夹

在这里插入图片描述
进入Scenes,将场景重命名为BallJumpScene
在这里插入图片描述
点击reload,得到目前没有添加物体的空的场景。
在这里插入图片描述

加入object

加入一个plane,作为小球滚动的平面

在这里插入图片描述
修改名称为Floor
scale的X改为2
在这里插入图片描述
得到效果如下
在这里插入图片描述
加入两个cube作为左右挡着的墙,两个墙的数据如下
在这里插入图片描述
在这里插入图片描述
得到
在这里插入图片描述
再加入一个sphere作为训练行为的小球
在这里插入图片描述
以及再加入一个cube作为小球的目标位置,它的位置之后会随着程序而改变的。
在这里插入图片描述
最后要加入一个斜坡,我们自定义斜坡的形状,进入
在这里插入图片描述
在这里插入图片描述
点击new shape右边的加号,设定prism的形状,点击build创建。
在这里插入图片描述
设定位置
在这里插入图片描述

设置Material

进入之前创建的Materials目录,新建一个Material
在这里插入图片描述
命名为Black,设置颜色为黑色
在这里插入图片描述
在这里插入图片描述
再新建一个蓝绿色的Material,命名为cyan
在这里插入图片描述
创建好两个材料后,拖动到物体上应用,让左右墙和斜坡应用黑色的材质
在这里插入图片描述
小球应用蓝绿色的材质,最后结果
在这里插入图片描述

设定小球的性质

小球作为训练的目标需要进行设置,首先设定小球为刚体,在BallAgent下点击add component
在这里插入图片描述
找到rigidbody,成功设定为刚体
在这里插入图片描述
接着编程控制小球的行为,在scripts文件夹下新建一个C#文件,命名为BallAgentLogic
在这里插入图片描述
使用VS打开该文件
在这里插入图片描述
是这样的
在这里插入图片描述
把代码换成如下:

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

public class BallAgentLogic : Agent
{

    Rigidbody rBody;

    // Start is called before the first frame update
    void Start()
    {
        rBody = GetComponent<Rigidbody>();
    }

    public Transform target;
    public override void OnEpisodeBegin()
    {
        // Reset agent
        this.rBody.angularVelocity = Vector3.zero;
        this.rBody.velocity = Vector3.zero;
        this.transform.localPosition = new Vector3(-9, 0.5f, 0);

        // Move target to a new spot
        target.localPosition = new Vector3(12 + Random.value * 8, Random.value * 3, Random.value * 10 - 5);
    }

    public override void CollectObservations(VectorSensor sensor)
    {
        // Target and Agent positions & Agent velocity
        sensor.AddObservation(target.localPosition);
        sensor.AddObservation(this.transform.localPosition);
        sensor.AddObservation(rBody.velocity);
    }


    public float speed = 20;
    public override void OnActionReceived(float[] vectorAction)
    {
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = vectorAction[0];

        if (vectorAction[1] == 2)
        {
            controlSignal.z = 1;
        }
        else
        {
            controlSignal.z = -vectorAction[1];
        }

        // Prevent adding forces after jumping
        if (this.transform.localPosition.x < 8.5)
        {
            rBody.AddForce(controlSignal * speed);
        }

        float distanceToTarget = Vector3.Distance(this.transform.localPosition, target.localPosition);
        // Reached target
        if (distanceToTarget < 1.42f)
        {
            SetReward(1.0f);
            EndEpisode();
        }

        // Fell of platform
        if (this.transform.localPosition.y < 0)
        {
            EndEpisode();
        }
    }

    public override void Heuristic(float[] actionsOut)
    {
        actionsOut[0] = Input.GetAxis("Vertical");
        actionsOut[1] = Input.GetAxis("Horizontal");
    }

}


把代码保存后,拖动到BallAgent里
在这里插入图片描述

把Target object拖动到BallAgent的Target里
在这里插入图片描述
设置Behavior Parameter
在这里插入图片描述
加入Decision Requester
在这里插入图片描述
设置为5,每五次做一次决定
在这里插入图片描述
设置相机位置,在Main camera中设置位置和角度
在这里插入图片描述
在这里插入图片描述
此时点击play。就可以用这个视角,按键盘上的上下左右键控制小球动啦
在这里插入图片描述
如果想让视角一直跟随小球的话,我们再新建一个C#文件,命名为BallAgentFollow
代码为:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BallAgentFollow : MonoBehaviour
{
    public Transform BallAgentTransform;

    private Vector3 _cameraOffset;
    // Start is called before the first frame update
    void Start()
    {
        _cameraOffset = transform.position - BallAgentTransform.position;
    }

    void LateUpdate()
    {
        transform.position = BallAgentTransform.position + _cameraOffset;
    }
}



保存后,拖动到Main camera里
在这里插入图片描述
再把小球拖过去
在这里插入图片描述
此时再点击play运行,视角跟随小球
在这里插入图片描述

训练并查看效果

训练前

为了加快训练的速度,我们把整个场景多复制几遍,让它们同时训练。
创建一个empty,命名为TrainingArea,设置位置000
在这里插入图片描述
在这里插入图片描述
把这6项都拖到TrainingArea里
在这里插入图片描述
在这里插入图片描述
把TrainingArea拖到Prefabs里,之后更改Prefab,就可以同步更改Scene,修改很方便。
在这里插入图片描述
接下来复制粘贴很多份TrainingArea,摆放的时候沿着箭头移动位置。
在这里插入图片描述
接下来在ml-agents-release_4\config\ppo文件目录下创建一个trainer_config.yaml文件,文件内容为

behaviors:
  BallAgent:
    trainer_type: ppo
    hyperparameters:
      batch_size: 128
      buffer_size: 5000
      learning_rate: 3.0e-4
      beta: 1.0e-3
      epsilon: 0.15
      lambd: 0.92
      num_epoch: 3
      learning_rate_schedule: linear
    network_settings:
      normalize: true
      hidden_units: 128
      num_layers: 3
      vis_encode_type: simple
      memory: null
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
    keep_checkpoints: 5
    max_steps: 9.00e6
    time_horizon: 128
    summary_freq: 10000
    threaded: true

开始训练

训练过程可以参考上一篇博客
打开命令行窗口,激活环境

activate ml-agents2

进入ml-agents文件夹

G:
cd G:\ghy\program\RL\ml-agents-release_4

训练

mlagents-learn config/ppo/trainer_config.yaml --run-id=balljump --train

点击unity中的play开始训练
在这里插入图片描述
训练到六十多万次的时候,成功率就已经稳定在了百分之九十
在这里插入图片描述
训练一百万次已经有了相当好的结果
在这里插入图片描述
按Ctrl+C停止训练

查看训练效果

ml-agents-release_4\results\balljump下的.nn文件拖到Brains文件夹下
在这里插入图片描述
这个.nn文件再拖到BallAgent里
在这里插入图片描述
这时候在点击Play可以看到训练后的效果(比我玩的好太多了)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值