您现在的位置是:首页 >技术教程 >Unity下ML-Agents第一个示例网站首页技术教程

Unity下ML-Agents第一个示例

程序员正茂 2026-04-07 00:01:04
简介Unity下ML-Agents第一个示例

本文写于2025年2月12日,需要提前安装好Anaconda

一、准备Python端

1.下载并解压 ML-Agents Release 22

解压路径为 C:UsersAdministrator

 2.conda虚拟环境创建

conda create -n mlagents22 python=3.10.12 && conda activate mlagents22

 3.执行如下命令

python -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple //设置镜像源
cd ml-agents-release_22
cd ml-agents-envs
pip install -e .  //注意后面的点

cd ..     //返回上层目录
cd  ml-agents
pip install -e . //注意后面的点

 4.安装GPU版torch

cd ..
cd .. //回到ml-agents-release_22根目录
pip3 install torch~=2.2.1 --index-url https://download.pytorch.org/whl/cu121

大概率会下载失败,把下载地址复制出来,用迅雷下载 

 下载后再执行下面的命令安装 

pip install C:迅雷下载	orch-2.2.2+cu121-cp310-cp310-win_amd64.whl

 5.在ml-agents-release_22config目录下建rollerball_config.yaml

behaviors:
  RollerBallBrain:
    trainer_type: ppo
    hyperparameters:
      batch_size: 64
      buffer_size: 2048
      learning_rate: 0.0003
      beta: 0.005
      epsilon: 0.2
      lambd: 0.95
      num_epoch: 3
    network_settings:
      normalize: true
      hidden_units: 128
      num_layers: 2
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
    max_steps: 500000
    time_horizon: 64
    summary_freq: 10000

6.执行如下命令开始训练,这时会生成一个RollerBallBrain.onnx

mlagents-learn  config/rollerball_config.yaml --run-id=RollerBall-1

 根据提示 回到Unity点击Play就会开始训练了,但是Unity这边的工作还没开始。

按Ctrl+C终止执行,请接着往下看。

二、准备Unity端

1.下载的 ML-Agents Release 22中有个Unity工程,位于Project文件夹

打开ProjectSettings/ProjectVersion.txt可以看到Unity版本

安装Unity2023.2.13f1,过程略。

打开工程Project,新建一个场景,创建 一个Plane(命名为Floor),一个方块Cube(Target),一个球Sphere(RollerAgent)(Rotation均为0,0,0,Scale均为1,1,1)

Floor位置:0,0,0

Target位置:3,0.5,0

RollerAgent:0,0.5,0

新建一个脚 本RollerAgent

using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
using UnityEngine;
 
public class RollerAgent : Agent
{
    [SerializeField]
    private Transform Target; // 方块目标
 
    public float speed = 10; // 小球移动速度
    private Rigidbody rBody; // 小球刚体
 
    private void Start()
    {
        // 获取刚体组件
        rBody = GetComponent<Rigidbody>();
    }
 
    /// <summary>
    /// Agent重置:每次训练开始时调用
    /// </summary>
    public override void OnEpisodeBegin()
    {
        // 如果小球掉落平台,重置其位置和速度
        if (this.transform.position.y < 0)
        {
            rBody.velocity = Vector3.zero;
            rBody.angularVelocity = Vector3.zero;
            transform.position = new Vector3(0, 0.5f, 0);
        }
 
        // 随机移动目标方块的位置
        Target.position = new Vector3(Random.value * 8 - 4, 0.5f, Random.value * 8 - 4);
    }
 
    /// <summary>
    /// 收集智能体的观察值
    /// </summary>
    /// <param name="sensor"></param>
    public override void CollectObservations(VectorSensor sensor)
    {
        // 添加目标的位置 (3 个值:x, y, z)
        sensor.AddObservation(Target.position);
 
        // 添加小球的位置 (3 个值:x, y, z)
        sensor.AddObservation(transform.position);
 
        // 添加小球的速度 (2 个值:x, z,因为 y 方向不需要)
        sensor.AddObservation(rBody.velocity.x);
        sensor.AddObservation(rBody.velocity.z);
    }
 
    public override void OnActionReceived(ActionBuffers actionBuffers)
    {
        // 获取动作数组:连续动作
        var continuousActions = actionBuffers.ContinuousActions;
 
        // 动作控制小球的移动
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = continuousActions[0]; // x 轴方向的力
        controlSignal.z = continuousActions[1]; // z 轴方向的力
        rBody.AddForce(controlSignal * speed);
 
        // 计算小球与目标的距离
        float distanceToTarget = Vector3.Distance(transform.position, Target.position);
 
        // 不同情况给奖励
        if (distanceToTarget < 1.42f)
        {
            // 到达目标
            SetReward(1.0f);
            EndEpisode();
        }
 
        if (transform.position.y < 0)
        {
            // 小球掉落
            EndEpisode();
        }
    } 
 
    /// <summary>
    /// 手动测试用的动作生成逻辑(启用 Heuristic Only 时调用)
    /// </summary>
    /// <param name="actionsOut"></param>
    public override void Heuristic(in ActionBuffers actionsOut)
    {
        var continuousActions = actionsOut.ContinuousActions;
        continuousActions[0] = Input.GetAxis("Horizontal"); // 左右
        continuousActions[1] = Input.GetAxis("Vertical");   // 前后
 
        // 调试信息
        Debug.Log($"Heuristic Actions: {continuousActions[0]}, {continuousActions[1]}");
    } 
 
}

RollerAgent添加组件Rigidbody、Behavior Parameters、Decision Requester 

将python端生成的RollerBallBrain.onnx复制到Unity工作中,Behavior Parameters中的Model先择RollerBallBrain.onnx

三、开始训练

再次执行训练命令

mlagents-learn  config/rollerball_config.yaml --run-id=RollerBall-1

如果有如下提示

mlagents.trainers.exception.UnityTrainerException: Previous data from this run ID was found.

 说明该命令正在提示,执行如下命令恢复执行

mlagents-learn  config/rollerball_config.yaml --run-id=RollerBall-1  --resume

 当Mean Reward接近1时,就可以按Ctrl+C终止执行。

将RollerBallBrain-90812.onnx复制到Unity,设置到Behavior Parameters的Model中

再次点击Unity的Play,就可以看到小球自动靠近小方块 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。