当前位置: 首页 > 工具软件 > ml-in-action > 使用案例 >

unity ML-Agent 使用干货教程 每日更新中

漆雕修德
2023-12-01

ML-Agent 简介

1, ml agent和 tensorflow的关系
mlagent 是unity专用ai组件,依赖tenslorflow (python环境)和 tensorflowsharp(unity插件,使unity程序可以包含一个tensorflow内核。该内核可跨平台,但不支持keras api。git 上又一个keras sharp的组件30+星,但问题很多)
https://blog.csdn.net/linxinfa/article/details/79712513
https://www.jianshu.com/p/31844f586b04
https://blog.csdn.net/lengyoumo/article/details/90485127
https://blog.csdn.net/u010019717/article/details/80382933
这是一片不错的教程

加入ML-Agent打包后,build出c端程序,可以使用专用训练指令,借c端程序训练模型。训练出的模型扩展名为.nn, 正常启动游戏并指定.nn模型,即可借由内部的tensorflowsharp 运行。

如果使用mlagent处理ai,那么程序打包出来后,你无法再对训练脚本进行修改。如果你希望可以使用python即时调整训练元素,或是即时使用模型影响游戏,那么使用socket之类的通信方法就可以解决这个问题。实际上,如果程序有“用户训练”的需求,那么最好使用这种方式。如果没有。那么直接使用mlaget 训练得到模型后再打包,是最好的方法。

ML-Agent 有自己的api。在程序中,设定关注的参数并设置奖励,即可使用。不像tensorflow,还需要构建训练过程。

如果要使用tensorflow的api功能,直接调用tensorflow sharp 即可。 但,不支持keras api ! 也不支持keras 模型格式。

安装

在我的另一篇教程里有详细的安装教程
https://mp.csdn.net/mdeditor/90413429#

ml-agent 概念

这个哥们写的概念介绍文章狠不错
https://blog.csdn.net/u010019717/article/details/80382933

使用

首先为目标物体添加agent(Agent组件用于收集 目标信息,或驱动目标)
创建一个脚本,继承agent 并重写agent的生命周期方法。

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

public class Ball3DAgent : Agent
{
    [Header("Specific to Ball3D")]
    public GameObject ball;
    private Rigidbody ballRb;
	//目标是一个叫ball的gameobject,该ball 有Rigidbody组件。在agent初始化的时候我们需要获取这些对象。
	//周期:初始化agent
    public override void InitializeAgent()
    {
        ballRb = ball.GetComponent<Rigidbody>();
    }
    //周期:收集信息
    public override void CollectObservations()
    {
        //增加收集数据,gameobject指的是球下面的平板,此处收集平板的旋转x,z以及目标球与木板的位置差,和目标球的速度。
        AddVectorObs(gameObject.transform.rotation.z);
        AddVectorObs(gameObject.transform.rotation.x);
        AddVectorObs(ball.transform.position - gameObject.transform.position);
        AddVectorObs(ballRb.velocity);
    }

 //周期:agent驱动,每帧都会运行,一个breain可以对应多个agent,但一个agent只能对应一个breain
 //该周期接收来自breain的驱动指令,获得float数组和string数据.其中数组数据根据CollectObservations周期中的数据顺序排序。
    public override void AgentAction(float[] vectorAction, string textAction)
    {
        if (brain.brainParameters.vectorActionSpaceType == SpaceType.continuous)
        {
            var actionZ = 2f * Mathf.Clamp(vectorAction[0], -1f, 1f);
            var actionX = 2f * Mathf.Clamp(vectorAction[1], -1f, 1f);

            if ((gameObject.transform.rotation.z < 0.25f && actionZ > 0f) ||
                (gameObject.transform.rotation.z > -0.25f && actionZ < 0f))
            {
                gameObject.transform.Rotate(new Vector3(0, 0, 1), actionZ);
            }

            if ((gameObject.transform.rotation.x < 0.25f && actionX > 0f) ||
                (gameObject.transform.rotation.x > -0.25f && actionX < 0f))
            {
                gameObject.transform.Rotate(new Vector3(1, 0, 0), actionX);
            }
        }
        if ((ball.transform.position.y - gameObject.transform.position.y) < -2f ||
            Mathf.Abs(ball.transform.position.x - gameObject.transform.position.x) > 3f ||
            Mathf.Abs(ball.transform.position.z - gameObject.transform.position.z) > 3f)
        {
            Done();
            //设置奖励 -1
            SetReward(-1f);
        }
        else
        {
          //设置奖励+0.1
            SetReward(0.1f);
        }
    }
//重置代理   (新一轮训练,各个物体的初始状态)
    public override void AgentReset()
    {
        //平面角度
        gameObject.transform.rotation = new Quaternion(0f, 0f, 0f, 0f);
        gameObject.transform.Rotate(new Vector3(1, 0, 0), Random.Range(-10f, 10f));
        gameObject.transform.Rotate(new Vector3(0, 0, 1), Random.Range(-10f, 10f));
        //初始化球
        ballRb.velocity = new Vector3(0f, 0f, 0f);
        ball.transform.position = new Vector3(Random.Range(-1.5f, 1.5f), 4f, Random.Range(-1.5f, 1.5f))  + gameObject.transform.position;
    }
}
 类似资料: