Github下载链接:https://github.com/Unity-Technologies/ml-agents

ML-Agents是游戏引擎Unity3D中的一个插件,也就是说,这个软件的主业是用来开发游戏的,实际上,它也是市面上用得最多的游戏引擎之一。而在几年前随着人工智能的兴起,强化学习算法的不断改进,使得越来越多的强化学习环境被开发出来,例如总所周知的OpenAI的Gym,同时还有许多实验室都采用的星际争霸2环境来进行多智能体强化学习的研究。那么,我们自然想到,可不可以开发属于自己的强化学习环境来实现自己的算法,实际上,作为一款备受欢迎的游戏引擎,Unity3D很早就有了这么一个想法。

详情见论文:Unity: A General Platform for Intelligent Agents

作为一个对游戏开发和强化学习都非常感兴趣的人,自然也了解到了这款插件,使得能够自己创造一个独一无二,与众不同,又充满智慧的游戏AI成为可能。

在Github的官方包中有更为详细的英文指导,如果不想翻译,也可以跟着我下面的步骤走。

文件说明

ML-Agents工具包包含几个部分:

  • Unity包com.unity.ml-agents包含了集成到Unity 项目中的 Unity C# SDK。,可以帮助你使用 ML-Agents 的Demo。
  • Unity包ml-agents.extensions依赖于com.unity.ml-agents,包含的是实验性组件,还未成为com.unity.ml-agents的一部分。
  • 三个Python包:mlagents包含机器学习算法可以让你训练智能体,大多数ML-Agents的用户值需要直接安装这个文件。mlagents_envs包含了Python的API可以让其与Unity场景进行交互,这使得Python机器学习算法和Unity场景间的管理变得便利,mlagents依赖于mlagents_envs。gym_unity提供了Unity场景支持OpenAI Gym接口的封装。
  • Project文件夹包含了几个示例环境,展示了ML-Agents的几个特点,可以帮助你快速上手。

需要的环境

  • 安装高于Unity2019.4的版本
  • 安装高于Python3.6.1的版本
  • 克隆Github仓库(可选)
  • 安装com.unity.ml-agents这个Unity包
  • 安装com.unity.ml-agents.extensions这个Unity包(可选)
  • 安装mlagents这个Python包

环境配置

在正式开始我们的项目之前是比较痛苦的配置环境的环节了。

  • 首先通过上面的链接从Github上下载ML-Agents的官方包。**切记路径中不能有中文!**否则无法正常训练!

  • 安装anaconda。

  • 在Anaconda Prompt中创建一个专门用于ML-Agents的Python环境。

    # 查看所有环境
    conda-env list
    # 安装新环境
    conda create -n ml-agents python=3.6
    # 激活新环境
    activete ml-agent
    
  • 解压从Github上下载的文件,分别cd到ml-agents和ml-agents-envs两个目录,执行以下命令安装两个包:

    pip install .
    
  • 执行以下命令看看安装是否成功

    mlagents-learn --help
    

    如果安装不成功,出现Error,那么可能是因为新配的环境没有装Pytorch,此时要去官网复制需要版本的pip命令进行安装。注意在安装pytorch的时候直接使用官方的命令下载速度极慢(甚至多次中断),因此我们需要配置清华源:

    conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
    conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
    conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
    conda config --set show_channel_urls yes#下载时显示文件来源
    

    并且在使用官方的命令时去掉结尾的-c pytorch,因为这个指令是强制在官网下载,这样下载速度会有大幅提升。

  • 下一步打开Unity编辑器,创建一个3D工程,点击windows菜单下的Package Manager,点击左上角的加号,选择Add package from disk,然后弹出的窗口中打开com.unity.ml-agents中的package.json文件,即可把包添加到Unity中,com.unity.ml-agents.extensions同理。安装完之后,就可以在下方文件中的Packages看到ML-Agents以及ML-Agent Extensions。

小试牛刀

首先把官方包下的Project用Unity编辑器打开,进入到ML-Agents -->Examples目录下,里面的全部都是ML-Agents各种实现的示例,包含了ML-Agents的主要功能展示,我们打开第一个项目3DBall,点击场景Scenes中的第一个:

现在可以看到画面了,这是一个相当简单的初级项目,我们只需要训练一个智能体顶着小球不让它落下即可。

我们打开Anaconda Prompt,切换到我们创建的环境,cd到官方包的目录,执行命令:

mlagents-learn config/ppo/3DBall.yaml --run-id=3DBallTest --force

这条命令的意思是采用的配置文件是3DBall.yaml,以3DBallTest这个名字来进行训练,训练数据也将保存在官方包下results目录下的同名文件夹,–force是强制执行,这会覆盖上一次的数据,如果没有写–force而存在同名文件夹,则训练无法执行。

执行命令后,它会弹出以下界面,然后你可以在Unity中点击运行了:

如果前面的步骤没有问题,就可以看到Unity中的画面是加速运行的,并且控制台逐渐输出以下信息:

[INFO] Connected to Unity environment with package version 2.1.0-exp.1 and communication version 1.5.0
[INFO] Connected new brain: 3DBall?team=0
[INFO] Hyperparameters for behavior name 3DBall:trainer_type:   ppohyperparameters:batch_size:   64buffer_size:  12000learning_rate:        0.0003beta: 0.001epsilon:      0.2lambd:        0.99num_epoch:    3learning_rate_schedule:       linearbeta_schedule:        linearepsilon_schedule:     linearnetwork_settings:normalize:    Truehidden_units: 128num_layers:   2vis_encode_type:      simplememory:       Nonegoal_conditioning_type:       hyperreward_signals:extrinsic:gamma:      0.99strength:   1.0network_settings:normalize:        Falsehidden_units:     128num_layers:       2vis_encode_type:  simplememory:   Nonegoal_conditioning_type:   hyperinit_path:      Nonekeep_checkpoints:       5checkpoint_interval:    500000max_steps:      500000time_horizon:   1000summary_freq:   12000threaded:       Falseself_play:      Nonebehavioral_cloning:     None
[INFO] Listening on port 5004. Start training by pressing the Play button in the Unity Editor.
[INFO] Connected to Unity environment with package version 2.1.0-exp.1 and communication version 1.5.0
[INFO] Connected new brain: 3DBall?team=0
[INFO] 3DBall. Step: 12000. Time Elapsed: 152.628 s. Mean Reward: 1.182. Std of Reward: 0.671. Training.
[INFO] 3DBall. Step: 24000. Time Elapsed: 194.462 s. Mean Reward: 1.430. Std of Reward: 0.893. Training.

当结束Unity的运行时,模型会自动保存到官方包下results下对应的文件夹,找到onnx后缀的文件,这是训练好的神经网络模型,导进项目中后,拖到Behavior Parameters组件的Model参数中,点击运行就可以查看实际的运行效果啦!

具体实现

首先在布置好环境之后,我们需要在智能体下挂载以下脚本:

为了驱动智能体,我们需要在智能体下挂上Behavior Parameters组件来调节各种参数,然后我们可以在里面设置组件参数:

其中我们需要修改的有Space Size,代表输入的维度,通常位置的输入是三维的,旋转涉及四元数所以是四维的,速度和角速度都是三维的。这样我们就可以根据需要观察的智能体的参数来计算输入的维度。Action是输出,其中的Continuous Action是输出的连续动作,Descrete Branch是离散动作,我们根据需求填写数量。

还有一个必要的组件是Decision Requester,这个组件提供了方便快捷的方式触发智能体决策过程。可以调节采取决策的步数,和不采取决策时是否执行动作。

最后一个必要组件就是需要我们自己写的Agent脚本了。这个脚本必须继承Agent类。默认只需要设置MaxStep一个参数,设置为0代表无限。下面详细讲解其中函数的用法。


ML-Agents提供了若干个方法供我们实现。

Initialize方法,初始化环境,获取组件信息,设置参数在这里完成。

CollectObservations方法,这个方法会收集当前游戏的各种环境,包括智能体的位置,速度等信息,ML-Agents会把这些信息自动生成Tensor,进行计算。这里相当于设置神经网络的输入,如果是摄像机输入而不是向量输入的情况下此函数什么都不用做。

然后是OnActionReceived方法,实现的是整个游戏中一个Step中的操作,接收神经网络的输出,使其转换为智能体的动作,设置奖励函数,并且判断游戏是否结束。

OnEpisodeBegin方法,每次游戏结束后,重开一轮需要做的处理,比如重置位置信息等。

如果我们想自己操作智能体,还需要定义一个Heuristic方法,这样游戏就会采集玩家的输出信息,可以学习玩家的思维,大大促进训练教程。

CollectDiscreteActionMasks方法,在特殊情况下屏蔽某些不需要的AI操作(如地图边界阻止)。

接下来看看3D小球游戏的智能体代码:

using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
using Random = UnityEngine.Random;

类的成员变量:

[Header("Specific to Ball3D")]
public GameObject ball;
[Tooltip("Whether to use vector observation. This option should be checked " +"in 3DBall scene, and unchecked in Visual3DBall scene. ")]
public bool useVecObs;
Rigidbody m_BallRb;
EnvironmentParameters m_ResetParams;

Initialize方法:

public override void Initialize()
{m_BallRb = ball.GetComponent<Rigidbody>();m_ResetParams = Academy.Instance.EnvironmentParameters;SetResetParameters();
}

CollectObservations方法:

public override void CollectObservations(VectorSensor sensor)
{if (useVecObs){sensor.AddObservation(gameObject.transform.rotation.z);sensor.AddObservation(gameObject.transform.rotation.x);sensor.AddObservation(ball.transform.position - gameObject.transform.position);sensor.AddObservation(m_BallRb.velocity);}
}

在hard版本的3DBall中,采用了另一种方式代替CollectObservations方法(输入维度为5,忽略小球速度):

// 标记该变量可观察,观察状态的帧数为9
[Observable(numStackedObservations: 9)]
Vector2 Rotation
{get{return new Vector2(gameObject.transform.rotation.z, gameObject.transform.rotation.x);}
}[Observable(numStackedObservations: 9)]
Vector3 PositionDelta
{get{return ball.transform.position - gameObject.transform.position;}
}

第三种替代CollectObservations是加上相机脚本即Camera Sensor脚本,再把相机的预制体拖入其中,设置好参数,相机自己就会获取画面作为输入,但会大大增加训练时间。

OnActionReceived方法:

public override void OnActionReceived(ActionBuffers actionBuffers)
{var actionZ = 2f * Mathf.Clamp(actionBuffers.ContinuousActions[0], -1f, 1f);var actionX = 2f * Mathf.Clamp(actionBuffers.ContinuousActions[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){SetReward(-1f);EndEpisode();}else{SetReward(0.1f);}
}

OnEpisodeBegin方法:

public override void OnEpisodeBegin()
{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));m_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;//Reset the parameters when the Agent is reset.SetResetParameters();
}

Heuristic方法:

public override void Heuristic(in ActionBuffers actionsOut)
{var continuousActionsOut = actionsOut.ContinuousActions;continuousActionsOut[0] = -Input.GetAxis("Horizontal");continuousActionsOut[1] = Input.GetAxis("Vertical");
}

其他方法:

public void SetBall()
{//Set the attributes of the ball by fetching the information from the academym_BallRb.mass = m_ResetParams.GetWithDefault("mass", 1.0f);var scale = m_ResetParams.GetWithDefault("scale", 1.0f);ball.transform.localScale = new Vector3(scale, scale, scale);
}
public void SetResetParameters()
{SetBall();
}

到这里智能体的脚本就写完了。接下来我们需要设置算法和参数。进入到config文件夹下,里面存放着算法的配置,对于单智能体强化学习,Unity官方提供了两种算法,PPO和SAC,这里我们使用PPO算法。进入PPO文件夹中,打开3DBall.yaml,通过修改其中的参数就能改变训练的配置,这需要对相应的强化学习算法有一定的了解。具体可以参考配置文档:https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Training-Configuration-File.md

behaviors:3DBall:trainer_type: ppohyperparameters:batch_size: 64buffer_size: 12000learning_rate: 0.0003beta: 0.001epsilon: 0.2lambd: 0.99num_epoch: 3learning_rate_schedule: linearnetwork_settings:normalize: truehidden_units: 128num_layers: 2vis_encode_type: simplereward_signals:extrinsic:gamma: 0.99strength: 1.0keep_checkpoints: 5max_steps: 500000time_horizon: 1000summary_freq: 12000

其中在Behavior Parameters中,Behavior Name中的名字必须要和第二行的那个名字一致,如果想设置不同的智能体使用不同的配置同时进行训练,只需要在下面加上不同名字的配置,然后再相应的智能体的Behavior Name中使用那个名字即可。

训练时文件路径要写对:

mlagents-learn config/ppo/3DBall.yaml --run-id=3DBallTest --force

如果想继续上次的训练:

mlagents-learn config/ppo/3DBall.yaml --run-id=3DBallTest --rusume

TensorBoard的使用

在上面的控制台环境下输入下列命令(训练过程中可以另外开一个Anaconda Prompt):

tensorboard --logdir .\results\ --port 6006

在浏览器中的网址栏输入localhost:6006,就可以看到tensorboard的界面了。这样就能把数据进行可视化。奖励和Loss的变化一清二楚。

加速训练

在编辑器中的训练是需要消耗非常多性能的,因此我们需要先把它打包成exe文件,具体操作是File–>Build Settings–>Build。

打包好后,把配置文件yaml文件也放入文件夹中。cd到该文件夹中,输入以下命令:

mlagents-learn 配置文件名.yaml --run-id=自己随意起名 --env=执行文件名.exe --num-envs=9 --force

就可以开启9个窗口同时训练。如果不显示图形界面可以快一大截,只需在命令后面加上–no-graphics即可。

总结

本文中介绍了Unity插件ML-Agents的安装和使用方法,并且跑通了ML-Agents的第一个入门级示例。现在算是对ML-Agents的整体框架有了大概的了解,后面还有更加复杂功能的实现,自创环境,自创算法等着我们去探索,我会另外开文章对每个要点进行详细的解读。

目前发表的相关文章:

ML-Agents命令及配置大全

ML-Agents案例之Crawler

ML-Agents案例之推箱子游戏

ML-Agents案例之跳墙游戏

ML-Agents案例之食物收集者

ML-Agents案例之双人足球

Unity人工智能之不断自我进化的五人足球赛

ML-Agents案例之地牢逃脱

ML-Agents案例之金字塔

ML-Agents案例之蠕虫

ML-Agents案例之机器人学走路

ML-Agents案例之看图配对

ML-Agents案例之“排序算法超硬核版”

Unity强化学习之ML-Agents的使用相关推荐

  1. Unity强化学习工具MLAgents

    文章目录 参考资料 一.环境准备 1.下载ml-agents 2.安装Unity Hub 3.安装Unity 3D 二.新建项目 2.1 新建工程 2.2 搭建场景 2.3 设置材质 三.程序 3.1 ...

  2. Unity红球吃绿球强化学习小任务——Ubuntu20.04系统于2022年2月26日实现

    Unity红球吃绿球强化学习小任务--Ubuntu20.04系统于2022年2月26日实现 Unity红球吃绿球强化学习小任务 一.主机环境参数说明 二.具体教程以之前提供的视频介绍为主,需要修改的章 ...

  3. 模仿学习与强化学习的结合(原理讲解与ML-Agents实现)

    简介 模仿学习是强化学习的好伙伴,使用模仿学习可以让智能体在比强化学习短得多的时间内得到与人类操作相近的结果,但是这种做法并不能超越人类,而强化学习能够得到远超人类的智能体,但训练时间往往非常漫长.因 ...

  4. 使用Amazon SageMaker RL 和Unity训练强化学习智能体

    [更新记录] 2022年3月25日 更新原始内容 本文目录结构 1. Overview of solution 2. Building a Docker container 3. Unity envi ...

  5. 在Unity环境中使用强化学习训练Donkey Car(转译)

    在Unity环境中使用强化学习训练Donkey Car 1.Introduction 简介 2. Train Donkey Car with Reinforcement Learning 使用强化学习 ...

  6. 2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势

    来源:网络大数据 1.简介 过去几年一直是人工智能爱好者和机器学习专业人士最幸福的时光.因为这些技术已经发展成为主流,并且正在影响着数百万人的生活.各国现在都有专门的人工智能规划和预算,以确保在这场比 ...

  7. 2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势(下)

    4.工具和库 工具和库是数据科学家的基础.我参与了大量关于哪种工具最好的辩论,哪个框架会取代另一个,哪个库是经济计算的缩影等等. 但有一点共识--我们需要掌握该领域的最新工具,否则就有被淘汰的风险.  ...

  8. 2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势(上)

    1.简介: 过去几年一直是人工智能爱好者和机器学习专业人士最幸福的时光.因为这些技术已经发展成为主流,并且正在影响着数百万人的生活.各国现在都有专门的人工智能规划和预算,以确保在这场比赛中保持优势. ...

  9. 2018年AI和ML(NLP,计算机视觉,强化学习)技术概述和2019年趋势

    前面两篇主要介绍了基于深度学习的自然语言处理,这是去年以前的成果,下面这一篇是总结今年NLP的最新成果,大家可以看看,找到对应论文好好研究,当然这还是外国人写的,没办法,国内很少有人能总结的那么透彻, ...

  10. 【四】多智能体强化学习(MARL)近年研究概览 {Learning cooperation(协作学习)、Agents modeling agents(智能体建模)}

    相关文章: [一]最新多智能体强化学习方法[总结] [二]最新多智能体强化学习文章如何查阅{顶会:AAAI. ICML } [三]多智能体强化学习(MARL)近年研究概览 {Analysis of e ...

最新文章

  1. 7-5 表格输出 (C语言)
  2. python获取当前目录路径和文件
  3. RHCE课程-RH253Linux服务器架设笔记五-DNS服务器配置(2)
  4. js操作frame详细解说,window.opener和window.parent的区别
  5. easyScholar——文献数据库插件
  6. c# WinForm英雄联盟挂机源码及实现原理
  7. java内部类选择题_java内部类详解(附相关面试题)
  8. IAR STM32工程报错Error[Pe020]: identifier “GPIO_Pin_0”is undefined D:\STM32F103_Demo\App\main.c
  9. 本地可以使用oracle吗,Oracle - PLS-00642:SQL语句中不允许使用本地集合类型
  10. 联想台式主机拆机教程_联想r400拆机教程 拆解电脑没那么难
  11. 「驱动安装」HighPoint RocketRAID R2722 磁盘阵列卡 驱动安装教程
  12. 2008年07月《安全天下事之莫须有的敌人与看得到的威胁》、2008年08月《安全天下事之七月流火》
  13. 读书笔记2014第6本:《The Hunger Games》
  14. 学以致用——微博文章内容统计分析之一(Excel+GraphLab)
  15. 为你的Typecho文章页面添加微信公众号二维码-星泽V社
  16. ORACLE 获取配置信息 USERENV函数
  17. 全网最后一个免费版本,永久可用
  18. 高性能,高扩展,高可用架构
  19. 前缀和(C/C++)
  20. 世界著名logo设计文化解读

热门文章

  1. w7怎么更换计算机用户名和密码怎么办,win7怎么修改系统用户名
  2. 中国芝麻市场竞争规模及销售渠道分析报告2022-2028年版
  3. 读取图像教程,生成h5py文件的教程
  4. session 与 coolie 的区别与联系
  5. centos6.6搭建LANP环境(yum)
  6. matlab仿真放入直流电源,用Matlab/Simulink软件包建模电容滤波直流电源
  7. 质因数分解的一些讨论(Pollard-Rho算法)
  8. 运放技术——压摆率和上升时间
  9. coreldraw做生化标志_CorelDRAW标志绘制图文教程,logo设计制作教程
  10. FPGA实现AXI4总线的读写