Unity机器学习 ML-Agents第一个例子

news2024/11/15 13:30:44


上一节我们安装了机器学习mlagents的开发环境,本节我们创建第一个例子,了解什么是机器学习。
我们的例子很简单,就是让机器人自主移动到目标位置,不能移动到地板范围外。

首先我们来简单的了解以下机器学习的过程。

机器学习的过程

MLAgents机器强化学习的过程(reinforcement learning)
observation - 监视,观察
decision - 决策
action - 行动
reward - 奖罚
这4个步骤的翻译可能不是很准确,大概就是先观察,后决策,然后行动,最后奖罚。

脚本开始
我们首先创建一个新脚本,我这里创建了MoveToTarget.cs

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

public class MoveToTarget : Agent
{
    
}

机器学习的类都要要继承Agent基类。

Observation、Action(监视和行动)
我们首先通过覆写CollectObservations函数,它负责观察或者监视数据,本例是让代理(agent)观察目标target的方位。
然后覆写OnActionReceived函数,通过接受到的缓冲区的数据进行行动,这里我们要注意机器学习的算法只适用于数字,这意味着机器不知道什么是对象(object),也不知道什么是左右移动,它只负责处理数字,例如float,int类型数据。

接下来,我们在Unity中创建一个agent(代理-盒子,蓝色),target(目标-球形,黄色),还有地板plane(盒子,灰色)。如下图:


理解重要参数
在agent上添加我们的脚本MoveToTarget,这时会自动添加一个BehaviorParameters的行为参数脚本。

 
 

离散的意义

我们先来理解下离散的意义:
假如我们离散输入1,分支0输入5。
在这里插入图片描述
代码中覆写Action接收。 我们看下log,因为只有一个离散分支,所以是DiscreteActions[0]

public class MoveToTarget : Agent
{
    public override void OnActionReceived(ActionBuffers actions)
    {
        Debug.Log(actions.DiscreteActions[0]);
    }
}

因为我们覆写了行动Action,我们还需要一个请求决策。我们在agent对象上添加DecisionRequester(决策请求),参数DecisonPeriod是请求的周期。
在这里插入图片描述
接下来我们就可以执行,看输出了什么。

调试和查看输出

 首先开打cmd,让我们进入vent虚拟环境中。上一篇文章我们讲过了,就是那个MLApp\venv\Scripts\activate.bat批处理文件,确保正常是这样的。
在这里插入图片描述
然后我们输入

mlagents-learn
然后会出现一个漂亮的Unity Logo,并且告诉我们,可以开始Unity运行了。如下图:
在这里插入图片描述
Unity运行后,我们看到cmd窗口和Unity的输出已经开始了。

在这里插入图片描述

我们可以看到离散的输出,因为设置了5,这里也只有0-4。

连续类型

接下来我们测试连续型
在Unity中我们把SpaceType改为continuous。并且设置Size为1。
在这里插入图片描述
脚本也需要改为接收连续型

public class MoveToTarget : Agent
{
    public override void OnActionReceived(ActionBuffers actions)
    {
        Debug.Log(actions.ContinuousActions[0]);
    }
}

我们继续开始运行,在cmd中输入mlagents-learn
这时我们会得到一个报错:
在这里插入图片描述

是因为我们重试使用了相同的默认ID进行再次训练,这里我们要么使用mlagents-learn --force来强制覆盖学习,要么更换ID,mlagents-learn --run-id=test2。

那么虚拟环境开启后,我们运行Unity。
运行后,我们得到的log如下:
在这里插入图片描述

我们看到了,连续的就是-1到1的浮点数。到这里我们就了解了离散和连续的区别了。

监视和行动代码
下面我们将继续完善脚本,收集监视信息。
我们需要覆写CollectObservations(VectorSensor sensor)函数。这个函数你可以理解成AI,就是人工智能需要哪些数据才能解决你的问题。在本例中,我们希望盒子(agent)对象移动到球(target)对象的位置。我们思考以下,我们需要知道的数据有哪些?


 如果你想agent能够移动到目标,是不是需要知道agent在哪,target在哪,所以要知道两个目标的位置,所以我们通过传感器把坐标传入监视。所以代码里我们把两个物体的坐标位置传递给观察器。

	[SerializeField] Transform targetTfm;	
    public override void CollectObservations(VectorSensor sensor)
    {
        sensor.AddObservation(transform.position);
        sensor.AddObservation(targetTfm.transform.position);
    }

行动里,actions就是(decision - 决策)的结果,我们根据决策数据进行行动。

	//行动
	float moveSpd = 10f;
    public override void OnActionReceived(ActionBuffers actions)
    {
        float moveX = actions.ContinuousActions[0];
        float moveZ = actions.ContinuousActions[1];
        transform.position += new Vector3(moveX, 0f, moveZ) * Time.deltaTime * moveSpd;
    }

 因为我们给观察函数的信息是两个坐标,相当于6个float类型,所以Vector Observations 的 SpaceSize需要填写6。而行动,我们只需要移动agent的x和z轴,所以Vector Action的SpaceSize填写2。
在这里插入图片描述

如何让机器学习
你可以把机器学习看成是训练小狗,如果小狗完成了指定动作,你可以给它骨头。反之,给予惩罚。
在本例中,我们在地板周围围上4面墙体。我们判断如果它移动到墙就扣分,如果移动都目标就加分,我们在Unity里给Plane围上4个wall。我们添加墙体,并勾选墙体和target 的Collider的IsTrigger,方面我们进行一个触发处理。

 

添加奖励模块脚本

	private void OnTriggerEnter(Collider other)
    {
        Debug.Log("OnTriggerEnter:"+other.name);
        if (other.name.Equals("target"))
        { 
            AddReward(+1f); //奖励
            EndEpisode();   //结束经历
            plane.material.color = Color.green;
            Debug.Log("奖励");
        }
        else if (other.name.Equals("wall"))
        {
            AddReward(-1f); //惩罚
            EndEpisode();   //结束
            plane.material.color = Color.grey;
            Debug.Log("惩罚");
        }
    }

上面的代码中,如果碰到了target,我们调用AddReward +1,并结束本段AI,让plane的颜色变为绿色,反之如果碰到了wall,那么就AddReward -1,plane变成灰色。

回合结束处理
每当得到奖励或者惩罚,会调用EndEpisode。当本段落结束后我们希望它继续训练,我们需要把agent对象重新复位,我们要覆写函数OnEpisodeBegin。
 

    //当一段经历开始
    public override void OnEpisodeBegin()
    {
        transform.position = Vector3.zero;
        Debug.Log("经历开始");
    }

运行mlagent虚拟机后我们运行unity,可以看到机器已经开始学习如何跑到target的位置了,刚开始很艰难,常常碰到墙壁,慢慢的碰到target的概率会越来越大。
效果如下:
请添加图片描述

运行过程中,可能开始agent对象很笨,基本原地打转,经过长周期的运行会越来越快的找寻到target。

几个参数

这里有几个点要说明

MaxStep(最大步)

在这里插入图片描述

这里的MaxStep是一段(Episode)最大步数,如果我们不想每次运行尝试步数太长,可以给一个数值,你可以尝试1000,10000这样的数字,到达这个后,会重新进入OnEpisodeBegin。设置的目的是如果代理一直运行都没有碰到过target,只是躲避了wall,那么可能达不到我们训练的目的。

Heuristic (启发)
这个我的理解是通过你的控制来测试你的运行逻辑是否正确。属于一个调试功能。
 

//启发
    public override void Heuristic(in ActionBuffers actionsOut)
    {
        ActionSegment<float> continuousActions = actionsOut.ContinuousActions;
        continuousActions[0] = Input.GetAxisRaw("Horizontal");
        continuousActions[1] = Input.GetAxisRaw("Vertical");
    }

我们可以修改agent的BehaviorParameters的BehaviorType为Heuristic(启发),然后运行Unity就可以控制agent。模拟机器是否遇到target和wall会复位,进行调试。

机器学习加快的办法
还有一个机器学习加速的办法,那就是把当前的训练场景复制很多个,让他们同时运行来达到机器训练加速的目的,我们可以把场景和脚本稍加修改。如下:
 

我们需要修改脚本,把原来的position改为localPosition。因为这样很容易复用我们的代码,并且只用复制几个图中的ground就可以了。

全代码如下:

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

public class MoveToTarget : Agent
{
    [SerializeField] Transform targetTfm;
    [SerializeField] Renderer plane;
    float moveSpd = 30f;
    //通过传感器把坐标传入监视
    public override void CollectObservations(VectorSensor sensor)
    {
        sensor.AddObservation(transform.localPosition);
        sensor.AddObservation(targetTfm.transform.localPosition);
    }

    //行动接收
    public override void OnActionReceived(ActionBuffers actions)
    {
        float moveX = actions.ContinuousActions[0];
        float moveZ = actions.ContinuousActions[1];
        transform.localPosition += new Vector3(moveX, 0f, moveZ) * Time.deltaTime * moveSpd;
    }

    //当一段经历开始
    public override void OnEpisodeBegin()
    {
        transform.localPosition = Vector3.zero;
        Debug.Log("经历开始");
    }

    //启发
    public override void Heuristic(in ActionBuffers actionsOut)
    {
        ActionSegment<float> continuousActions = actionsOut.ContinuousActions;
        continuousActions[0] = Input.GetAxisRaw("Horizontal") * Time.deltaTime * moveSpd;
        continuousActions[1] = Input.GetAxisRaw("Vertical") * Time.deltaTime * moveSpd;
    }

    private void OnTriggerEnter(Collider other)
    {
        //Debug.Log("OnTriggerEnter:"+other.name);
        if (other.name.Equals("target"))
        { 
            AddReward(+1f); //奖励
            EndEpisode();   //结束经历
            plane.material.color = Color.green;
            //Debug.Log("奖励");
        }
        else if (other.name.Equals("wall"))
        {
            AddReward(-1f); //惩罚
            EndEpisode();   //结束
            plane.material.color = Color.grey;
            //Debug.Log("惩罚");
        }
    }
   
}


我们修改完毕后,然后运行mlagents环境并运行Unity,明显批量的速度更快了。如下图:
请添加图片描述
从GIF中能看到,亮起绿色的频率越来越快了。在我的机器上到最后就只有绿色的亮起了。

在这里插入图片描述

等机器运算完毕后会生成MovetoTart1.onnx文件。

然后在
H:\UnityProject\MLApp\venv\Scripts\results\就能看到我们所有的mlagents测试数据,包含我们需要的训练后的MoveToTar.onnx文件,我们把它复制到Unity/Assets中。这个onnx就是经过AI训练的大脑的神经网络。

我们把这个文件拖动到Model里。

 

BehaviorType选择InferenceOnly,点击Unity运行,这样这个agent就拥有找寻target的AI了。

环境设置
机器学习的环境是可以自定义配置的,可以参考这里。
创建一个movetarget.yaml文件,放到Unity/config文件夹(建立一个)
 

behaviors:
  MoveToTar1:
    trainer_type: ppo
    hyperparameters:
      batch_size: 10
      buffer_size: 100
      learning_rate: 3.0e-4
      beta: 5.0e-4
      epsilon: 0.2
      lambd: 0.99
      num_epoch: 3
      learning_rate_schedule: linear
      beta_schedule: constant
      epsilon_schedule: linear
    network_settings:
      normalize: false
      hidden_units: 128
      num_layers: 2
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
    max_steps: 500000
    time_horizon: 64
    summary_freq: 10000

通过下面的指令进行,就是按照自定的参数来执行了。具体参数意义有机会我们后面再聊。

使用这个配置文件开启机器学习,输入下面的指令:

mlagents-learn config/movetarget.yaml --run-id=test5

在这里插入图片描述

进一步优化机器

我们继续上一个测试。当运行的时候,把target的位置改变,我们发现agent可能就找不到目标了,可以思考下为什么?如下面的动画:

请添加图片描述

对的,因为在机器学习的时候我们的target的位置一直没有发生变化,所以AI可能觉得目标是死物,所以我们可以通过修改脚本,让target每段运算完毕后改变位置,发生变化,机器就会变得聪明些。

我们修改代码如下:

    public override void OnEpisodeBegin()
    {
        transform.localPosition = new Vector3(Random.Range(-9f, 0f), 0f, Random.Range(-4f, 4f));
        targetTfm.localPosition = new Vector3(Random.Range(1f, 9f), 0f, Random.Range(-4f, 4f));
        //Debug.Log("经历开始");
    }

我们每次开始都随机以下target和agent的位置,但是不会重合。然后再进行机器学习。

我们输入下面指令,在上一次运行的test5的基础上进行test8运算

mlagents-learn config/movetarget.yaml --initialize-from=test5 --run-id=test8

运算后我们覆盖onnx文件,继续运行,结果如下:
请添加图片描述

Web监控

要在训练期间监控代理性能的统计信息,请使用 TensorBoard指令。

可以开另外一个cmd,进入虚拟环境(venv),输入下面指令:

tensorboard --logdir results

在这里插入图片描述
然后再浏览器输入地址就可以了

http://localhost:6006/


根据图表,你可以看到各种曲线,来修改你的机器训练。

本章内容就到这里了,官方还有很多种机器学习的例子,如果有兴趣可以自行学习。有机会下一篇文章我们进一步扩展,或者做另外一个有意思的Demo。

本章源码

GitHub - thinbug/MLApp

引用:
https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Learning-Environment-Create-New.md
 

Unity机器学习2 ML-Agents第一个例子_ml-agents小狗-CSDN博客

Unity中训练一个ML-Agents项目—解决torch和mlagents配置问题_mlagents训练_LLLQQQismmmmme的博客-CSDN博客

Unity 对接 ML-Agents 初探_艾沃尼斯的博客-CSDN博客

GitHub - thinbug/MLApp

Unity之ml-agents(一):环境配置及初步使用_mlagents-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1243994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EventLog Analyzer:强大的日志管理与分析工具

随着企业网络规模的扩大和信息系统的复杂化&#xff0c;安全日志管理和分析成为了至关重要的一环。在这个背景下&#xff0c;EventLog Analyzer崭露头角&#xff0c;成为一款备受推崇的日志管理与分析工具。本文将介绍EventLog Analyzer的主要特点、功能以及为企业带来的实际价…

github批量仓库克隆,git clone某个用户的所有仓库

利用github的api工具&#xff0c; 首先拿到用户名为kevin的所有仓库的url&#xff1a; curl "https://api.github.com/users/kevin/repos?per_page100&&page1" | grep -w clone_url >clone.txt过滤一下&#xff1a; grep -o https://[^"]* clone…

智慧海岛/海域方案:助力海洋空间智慧化、可视化管理

随着我国海洋经济的快速发展&#xff0c;海域海岛的安防技术也获得了进步。传统的安防监控模式已经满足不了海域海岛的远程监管需求。伴随着人工智能、边缘计算、大数据、通信传输技术、视频技术、物联网等信息化技术的发展&#xff0c;海岛海域在监管手段上&#xff0c;也迎来…

计算机中了halo勒索病毒怎么清除,halo勒索病毒解密数据恢复

科技的进步加快了企业发展的步伐&#xff0c;网络技术的不断应用为企业的生产运营提供了极大帮助&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机服务器遭到了halo勒索病毒攻击&#…

【giszz笔记】产品设计标准流程【8】

&#xff08;续上回&#xff09; 真的没想到写了8个章节&#xff0c;想参考之前文章的&#xff0c;我把链接给到这里。 【giszz笔记】产品设计标准流程【7】-CSDN博客 【giszz笔记】产品设计标准流程【6】-CSDN博客 【giszz笔记】产品设计标准流程【5】-CSDN博客 【giszz笔…

Keil工程打开发现目标芯片无法选择解决方案

买了一个开发板&#xff0c;配套有一些底层驱动的例程&#xff0c;打开后发现目标芯片无法选择&#xff0c;对应的下载Flash FLM文件也无法选择。从提示框中可以知道所提供的例程是Keil4的例程&#xff0c;我电脑上安装的Keil版本是Keil版本&#xff0c;估计是这个原因导致工程…

Rust开发——数据对象的内存布局

枚举与Sized 数据 一般数据类型的布局是其大小&#xff08;size&#xff09;、对齐方式&#xff08;align&#xff09;及其字段的相对偏移量。 1. 枚举&#xff08;Enum&#xff09;的布局&#xff1a; 枚举类型在内存中的布局通常是由编译器来确定的。不同的编译器可能有不…

大模型增量预训练参数说明

在增量预训练过程中通常需要设置三类或四类参数,模型参数,数据参数,训练参数,额外参数。 下面分别针对这四种参数进行说明。 欢迎关注公众号 模型参数 model_type模型类型,例如bloom,llama,baichuan,qwen等。 model_name_or_path模型名称或者路径。 tokenizer_name_or…

2023年最新PyCharm环境搭建教程(含Python下载安装)

文章目录 写在前面PythonPython简介Python生态圈Python下载安装 PyCharmPyCharm简介PyCharm下载安装PyCharm环境搭建 写在后面 写在前面 最近博主收到了好多小伙伴的吐槽称不会下载安装python&#xff0c;博主听到后非常的扎心&#xff0c;经过博主几天的熬夜加班&#xff0c;…

解决Emmy Lua插件在IDEA或 Reder 没有代码提示的问题(设置文件关联 增加对.lua.txt文件的支持)

目录 Reder版本2019.x Reder版本2021.1.5x Reder版本2019.x 解决Emmy Lua插件在IDEA或 Reder 没有代码提示的问题(设置文件关联 增加对.lua.txt文件的支持) Reder版本2021.1.5x 解决Emmy Lua插件在IDEA或 Reder 没有代码提示的问题(设置文件关联 增加对.lua.txt文件的支持)…

什么是LLC电路?

LLC电路是由2个电感和1个电容构成的谐振电路&#xff0c;故称之为LLC&#xff1b; LLC电路主要由三个元件组成&#xff1a;两个电感分别为变压器一次侧漏感(Lr)和励磁电感(Lm)&#xff0c;电容为变压器一次侧谐振电容(Cr)。这些元件构成了一个谐振回路&#xff0c;其中输入电感…

【Spring进阶系列丨第四篇】学习Spring中的Bean管理(基于xml配置)

前言 在之前的学习中我们知道&#xff0c;容器是一个空间的概念&#xff0c;一般理解为可盛放物体的地方。在Spring容器通常理解为BeanFactory或者ApplicationContext。我们知道spring的IOC容器能够帮我们创建对象&#xff0c;对象交给spring管理之后我们就不用手动去new对象。…

为销售赋能:利用 Splashtop 增强远程培训技术

远程销售团队这一概念在当今快节奏的商业环境中日益普遍。各公司正在计划在不同地点灵活开展销售业务&#xff0c;希望利用技术优势缩小地域差距。但是&#xff0c;这种向远程销售的转型面临着重大挑战&#xff0c;尤其在培训和发展领域。培训远程销售团队需要采用创新方法&…

微型计算机原理MOOC题

一、8254 1.掉坑了&#xff0c;AL传到端口不意味着一定传到的是低位&#xff0c;要看控制字D5和D4&#xff0c;10是只写高位&#xff0c;所以是0A00.。。 2. 3. 4.待解决&#xff1a;

免费使用!Figma汉化网页版替代工具震撼登场

Figma作为一种常用的在线设计工具&#xff0c;大多数UI设计师都非常了解这个软件&#xff0c;很多人在设计过程中经常使用Figma。Figma作为一种外国设计软件&#xff0c;没有本地版本&#xff0c;在一些设计中需要在插件的帮助下完成工作。虽然Figma确实比其他软件有很大的优势…

【Vue】核心特性(响应式)

响应式&#xff1a; 数据变化&#xff0c;视图自动更新 接下来使用一个例子来体现一下什么是响应式 案例一&#xff1a; 访问数据&#xff0c;视图自动更新 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><…

2023亚太杯数学建模竞赛C题详细代码解析建模

C题&#xff1a;The Development Trend of New Energy Electric Vehicles in China中国谈新能源电动汽车的发展趋势 第一问部分&#xff1a; import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.prep…

如何用Python爬取全国高校数据?

前言 Python是一门强大的编程语言&#xff0c;它可以用于爬取互联网上的各种数据。在这篇文章中&#xff0c;我们将学习如何使用Python爬取全国高校数据&#xff0c;并使用代理IP进行爬取。 本文主要分为以下几个部分&#xff1a; 数据来源及需求安装依赖包及导入模块爬取全…

VOC数据集和COCO数据集直接的相互转换

VOC数据集格式 get_list.py import os import random import shutil# 设置随机种子 random.seed(1000)# 判断Annotations和JpegImages是否对应 train_precent=0.8 label_path= "../../Annotations" print(os.path.abspath(label_path)) save="../Main" pr…

CCFCSP试题编号:201803-2试题名称:碰撞的小球

一、题目描述 二、思路 1.首先妾身分析这个题目&#xff0c;想要解题&#xff0c;得得解决2个问题。 1&#xff09;判断小球到达端点或碰撞然后改变方向&#xff1b; 2&#xff09;每时刻都要改变位置 两个问题都比较好解决&#xff0c;1&#xff09;只要简单判断坐标&…