Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)

 

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第1张图片

 

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)

 

目录

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)

一、简单介绍

二、原理实现

三、原理拆解

四、注意事项

五、效果预览

六、实现步骤

七、训练过程数据的可视化查看(tensorboard.exe 查看可视化数据)

八、关键脚本

九、训练后记


 

一、简单介绍

Unity 中使用人工智能 ML-Agents 的功能,包括环境搭建,ML-Agents 集成到Unity,使用 mlagents 训练,训练结果在 Unity 中使用等。

本节介绍,在 Unity 使用 ML-Agents,编写重写 平衡球案例,然后训练,得到训练模型的方法 Demo。关键是学会,判断设置重写重置的条件,怎么设置奖励(惩罚),怎么模拟操作,观察的变量、控制的变量等,关键是学会每个案例奥妙,便会后期更复杂的铺垫。

 

这里不在讲解环境搭建,相关的环境搭建,可参见

Unity ML-Agents 之 环境配置(Anaconda 下载安装等),简单的搭建场景实现简单训练的Demo(内含详细步骤)

 

二、原理实现

1、继承 Agent ,重写五个函数,Initialize()、OnEpisodeBegin()、 CollectObservations()、 OnActionReceived()、 Heuristic()

1)Initialize ()函数相当于 Start()函数,获取小球的刚体

2)OnEpisodeBegin()新一段开始函数,可以重置小球坠落出界后的重新开始的位置,以及 Cube 重新开始的一定范围的随机旋转

3)CollectObservations()观察变量,包括球相对于Cube 的相对位置、球的速度、Cube X Z 的旋转

4)OnActionReceived ()改变 Cube XZ的两个变量,球出界的判断,以及设置奖励

5)Heuristic ()在 HeuristicOnly 模式操作小球的输入,这里是水平竖直Axis 操纵

2、编写好脚本训练模型

 

三、原理拆解

1、观察的变量

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第2张图片

 

2、球的坠落出界判断

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第3张图片

 

3、坠落出界之后,重置初始化位置

1)球在Cube 上方的一定区域

2)Cube X Z 上的适当任意旋转

 

四、注意事项

1、其实要真正模拟一个平衡球的案例,考虑的东西挺多的,必要的我们需要抽象出来。这个案例没有添加球的太多物理属性,例如球的摩擦、弹力、角速度等,需要的话大家可以自行添加,进行训练

2、训练的时候,可以拷贝多个模型一起训练,可以加快训练速度(但是要考虑自己CPU的性能,过多不一定好)

3、训练的时候,程序中的不必要代码打印最好关闭,不然,可能会影响训练速度

 

五、效果预览

训练后的效果

 

开始训练的效果

 

六、实现步骤

1、打开 Unity,新建工程

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第4张图片

 

2、在菜单 Window - Package Manager ,打开包管理

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第5张图片

 

3、搜索 Barracuda ,下载安装该 Package (不然导入 ML-Agents 包会报错)

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第6张图片

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第7张图片

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第8张图片

 

4、把 ml-agents-master 中的 com.unity.ml.agents 文件夹中的 Editor 、Plugins、Runtime 导入 Unity

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第9张图片

 

5、搭建一个场景,Cube(+Sphere)、Sphere ,对应取名,配色即可

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第10张图片

 

6、在工程中添加脚本 AIAgent_Balance ,继承 Agent,重写五个函数

1)Initialize ()函数相当于 Start()函数,获取小球的刚体

2)OnEpisodeBegin()新一段开始函数,可以重置小球坠落出界后的重新开始的位置,以及 Cube 重新开始的一定范围的随机旋转

3)CollectObservations()观察变量,包括球相对于Cube 的相对位置、球的速度、Cube X Z 的旋转

4)OnActionReceived ()改变 Cube XZ的两个变量,球出界的判断,以及设置奖励

5)Heuristic ()在 HeuristicOnly 模式操作小球的输入,这里是水平竖直Axis 操纵

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第11张图片

 

7、把脚本挂载到 AIAgent_Balance_Cube 上,并把 Balanced_Sphere 球体对应赋值

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第12张图片

 

8、设置 BehaviorParameters 脚本中的 VectorObservation 的 Space Size 为 8 (观察变量),VectorAction 动作变量为 2 (操作的就是 Cube 的 X Z上的旋转值), BehaviorType 设置为 HeuristicOnly ,先自己操作玩一下

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第13张图片

 

9、自己操作,还是挺麻烦的,接下来,训练模型

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第14张图片

 

10、添加一个 Train 文件夹,添加一个训练配置文件,注意Behavior 名称,会用到

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第15张图片

 

11、BehaviorParameters 脚本中的 BehaviorName 为配置文件中的名称 BalanceBall, BehaviorType 设置为 Default ,并根据电脑CPU的性能适当拷贝多的训练模型,加快训练效果

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第16张图片

 

12、打开命令行

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第17张图片

 

13、激活已经配置好 ml-agents 环境,切换到平衡球工程训练文件夹,使用 mlagents-learn BalanceBall.yaml,开始训练

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第18张图片

 

14、出现 Play button,回到 Unity ,Play 运行场景

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第19张图片

 

15、这里训练过程中的效果(从老掉到逐渐稳定)

 

16、训练结束(训练结果还是很不不错的,到252000 次后,基本没有球掉落的情况),会自动保存一个 训练 xxx.nn 文件

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第20张图片

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第21张图片

 

17、把训练好的 xxx.nn 赋值到 BehaviorParameters 脚本中的 Model

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第22张图片

 

18、运行场景,训练效果还是很不错的

 

七、训练过程数据的可视化查看(tensorboard.exe 查看可视化数据)

1、打开 Anacoda 构建的训练环境下的 Scripts(tensorboard.exe 能找到)

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第23张图片

 

2、按住 Shift + 鼠标右键,点击在此处打开 Powershell 窗口

注意:按住 Shift + 鼠标右键时千万别选中任何项目文件,不然右键打不开如图菜单

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第24张图片

 

3、打开 输入 如图命令,即可绑定一个网址,查看可视化数据图

( .\tensorboard.exe --logdir 训练的工程路径文件夹位置绝对路径 --host=127.0.0.1)

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第25张图片

 

4、在网页输入回车,即可看到训练数据过程可视化图: http://127.0.0.1:6006/

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第26张图片

 

八、关键脚本

1、AIAgent_Balance.cs

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

namespace XANStudy_MLAgents
{
    /// 
    /// 平衡球,平衡 AI 代理
    /// 
    [RequireComponent(typeof(DecisionRequester))]
    public class AIAgent_Balance : Agent
    {
        // 平衡球
        public GameObject Balanced_Sphere;
        // 平衡球的刚体
        private Rigidbody rgbodyBalanced_Sphere;

        /// 
        /// 初始化函数
        /// 
        public override void Initialize()
        {
            rgbodyBalanced_Sphere = Balanced_Sphere.GetComponent();
        }

        /// 
        /// 新阶段开始
        /// 
        public override void OnEpisodeBegin()
        {
            // 平衡板每次新阶段开始的初始化随机旋转
            AIAgentBalanceCubeInitRandomRotation();

            // 小球速度归零 小球位置随机生成在Cube 上头(注意位置)
            BalancedSphereInitRandomPosition();
        }

        /// 
        /// 收集观察变量
        /// 
        /// 
        public override void CollectObservations(VectorSensor sensor)
        {
            // 观察总共 3+3+1+1 个值
            {
                // 球相对Cube 的位置 3
                sensor.AddObservation(Balanced_Sphere.transform.position - this.transform.position);
                // 球的速度 3
                sensor.AddObservation(rgbodyBalanced_Sphere.velocity);
                // Cube 旋转 x z 1+1
                sensor.AddObservation(this.transform.eulerAngles.x);
                sensor.AddObservation(this.transform.eulerAngles.z);
            }
        }

        /// 
        /// 接收动作变量
        /// 
        /// 
        public override void OnActionReceived(float[] vectorAction)
        {
            //Debug.Log("vectorAction[0] : " + vectorAction[0]);
            //Debug.Log("vectorAction[1] : " + vectorAction[1]);
           

            // 操作 Cube ,避免小球出界坠落
            float x = 2 * Mathf.Clamp(vectorAction[0], -1, 1);
            float z = 2 * Mathf.Clamp(vectorAction[1], -1, 1);
            // 绕 X 前后旋转
            this.transform.Rotate(Vector3.right, z);
            // 绕 Z 左右旋转
            this.transform.Rotate(Vector3.forward, -x);

            // 判断小球是否出界坠落
            if (JudgeBallIsDropOut()==true) {
                // 设置负值的奖励(惩罚)
                SetReward(-1.0f);
                // 重新开始
                EndEpisode();
            }
            else{

                // 设置的奖励 (这个会差不多美帧调用,太多可能不好,关键是与 上面的 负值惩罚有一定比例)
                SetReward(0.1f);
               
            }
        }

        /// 
        /// 手动输入操作变量
        /// 
        /// 
        public override void Heuristic(float[] actionsOut)
        {
            // 水平垂直操作物体的数据
            actionsOut[0] = Input.GetAxis("Horizontal");
            actionsOut[1] = Input.GetAxis("Vertical");
        }

        /// 
        /// 平衡板每次新阶段开始的初始化随机旋转
        /// 
        private void AIAgentBalanceCubeInitRandomRotation() {
            this.transform.rotation = Quaternion.identity;
            // 平衡Cube 开始在X和Z上有随机 -10,10 的旋转
            this.transform.Rotate(Vector3.right,Random.Range(-10.0f,10.0f));
            this.transform.Rotate(Vector3.forward,Random.Range(-10.0f,10.0f));
        }

        /// 
        /// 小球速度归零
        /// 小球位置随机生成在Cube 上头(注意位置)
        /// 
        private void BalancedSphereInitRandomPosition() {
            this.rgbodyBalanced_Sphere.velocity = Vector3.zero;
            this.Balanced_Sphere.transform.position = new Vector3(Random.Range(-2f,2f),5, Random.Range(-2f, 2f))
                                                        + this.transform.position;
        }

        /// 
        /// 判断球是否出界或坠落
        /// 
        /// 
        private bool JudgeBallIsDropOut() {

            // 后面的值是保险值(前面的值其实可以判定出界,后面保证正真出界而已)
            return ((Balanced_Sphere.transform.position.y - this.transform.position.y) < (0 +(-1.0f))
                        // 球出 Cube 距离
                    || Mathf.Abs(Balanced_Sphere.transform.position.x - this.transform.position.x) > (2.5f+0.5f)
                    || Mathf.Abs(Balanced_Sphere.transform.position.z - this.transform.position.z) > (2.5f + 0.5f)
                );
        }
    }
}

 

2、BalanceBall.yaml

behaviors:
  BalanceBall:
    trainer_type: ppo
    hyperparameters:
      batch_size: 64
      buffer_size: 12000
      learning_rate: 0.0003
      beta: 0.001
      epsilon: 0.2
      lambd: 0.99
      num_epoch: 3
      learning_rate_schedule: linear
    network_settings:
      normalize: true
      hidden_units: 128
      num_layers: 2
      vis_encode_type: simple
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
    keep_checkpoints: 5
    max_steps: 500000
    time_horizon: 1000
    summary_freq: 12000
    threaded: true

 

九、训练后记

1、可以给球体添加物理材质,和修改 角速度,更真实的模拟,看看训练结果会怎么样

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第27张图片

 

2、BalanceBall.physicMaterial 属性如图

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第28张图片

 

 

Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)_第29张图片

你可能感兴趣的:(Unity,Unity,MLAgent,Unity,ML-Agents,机器学习,平衡球)