怎样理解Unity的ml-agent

0. 预备知识

虽然名字叫做机器学习ML,但是主要内容还是增强学习RL(或者叫强化学习)。其实并没有错,ML中主要包括监督学习、非监督学习和增强学习三种范式,只是这里并没有监督学习和非监督学习的内容。
这还是要从强化学习说起,但是为了避免篇幅太长,这里不做介绍了。网上有很多的学习资料,可以自行补课。Richard S. Sutton and Andrew G. Barto 的书 Reinforcement Learning: An Introduction 可以说是该领域的圣经。这里有第二版的pdf(http://incompleteideas.net/book/the-book-2nd.html)。
视频推荐大神David Silver的课程(https://www.bilibili.com/video/av8912293),他的重点在于传统的增强学习原理。另外一个课程是UC Berkeley的深度增强学习课程(https://www.bilibili.com/video/av20957290),该讲师被评为“MIT Tech Review Top 35 Innovators Under 35 (TR35), 2016”,结合最新的深度学习讲增强学习算法,很赞!
当然,既然是Unity的ml-agent,还必须知道Unity到底怎么玩。玩Unity需要使用C#语言,玩深度学习需要使用Python语言。
嗯。。。要学的东西很多啊,是时候继续了!

1. 直观感受Hello World

官方给出3D平衡小球的示例做出Hello World示例。这个hello world可不简单,第一次做还是需要比较多的时间。但是没有办法,这本来就是多个学科、多个领域的交叉,当你一步一步做下来并看到最终结果的时候,才能体会到作为一名程序员的成就感。所以不要犹豫,官方文档讲解清晰明了,如果具备了Unity、增强学习、python、TensorFlow的一点基础知识,那就赶快开始吧。毕竟这里还不需要自己去写代码。直观感受一下能激发你的求知欲和好奇心。下面上个截图:

3DBalanceBall

稍作讲解,小球在倾斜的地板上会往下滑,最终坠落。该地板就是训练出来智能体(Agent),它通过改变自己的倾斜角度,使得小球在3D空间中保持平衡。

2. 从头动手

2.1 环境构建

参考这里(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Learning-Environment-Create-New.md),不再赘述。

2.2 训练

参考这里(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Training-ML-Agents.md),不再赘述。

有几点事情要注意:

  1. 得不到收敛的策略。默认的训练次数是max_steps: 5.0e4,是在trainer_config.yaml这个文件中设定的。这个次数我在训练的时候得不到收敛的policy,因此需要加大一些;还有一种方案,就是学习3DBall 的那种方式,在场景中复制多份的环境,并行训练。
  2. tensorboard 打开之后不显示内容。好几次都遇到这个问题,参考这里(https://stackoverflow.com/questions/44175037/cant-open-tensorboard-0-0-0-06006-or-localhost6006)的解决方法就是:执行命令的时候指定host的IP地址,类似以下命令:
    tensorboard --logdir=training:your_log_dir --host=127.0.0.1
    然后访问http://127.0.0.1:6006即可。
  3. 只有在所有的steps都跑完之后,才会生成bytes文件,如果按下ctrl+c强行停止,不会生成。

2.3 Play

把训练完成得到的bytes文件拷贝到Unity的工程中,这里需要修改Brain类型为Internal,然后指定Graph Model文件。点击Play,即可看到训练的效果。我设定了训练step是2.0e5,使用TensorFlow GPU版本,GTX 1060 3GB的显卡,训练时间也很短,RollerBall就能妥妥的找到Target!

RollerBall

3. 原理

3.1 与OpenAI Gym的对比

这里不再解释增强学习的概念,网上有太多的资料可用,比我讲解强多了。这里想和OpenAI Gym做一个对比。再使用Gym做增强学习时主要的代码框架是这样的:

env = gym.make('CartPole-v0')
env.reset()  
while True: 
    env.render()  
    state, reward, done, _ = env.step(env.action_space.sample()) # take a random action  
    if done:  
        break  
env.close()

Gym已经做好了很多个环境供我们调用,只需要关注自己的增强学习算法即可(当然,也可以进行扩展,实现自己的env)。但是再Unity中并没有这么便利的工具,我想这也是ml-agents这个项目的出发点之一。Gym毕竟只是一个算法实验平台,并不能直接用于游戏开发或者生产实践。
从上面一段代码可以看出,制作环境需要重点实现的几个关键函数:

  • 环境需要初始化和关闭,如make函数、close函数
  • 增强学习需要多次反复的训练,环境需要重置自身状态,如reset函数
  • 环境需要定义自身的状态空间和动作空间,如action_space,observation_space
  • 环境需要一步一步的执行,并返回该步执行后环境的状态、回报、结束标记等,如step函数

3.2 整体架构

对于制作环境来讲,Unity肯定具有天然的优势,而且是三维的。但是困难又来了,目前的深度学习框架大多数是基于Python语言,Unity基于C#语言开发,环境和智能体怎么结合起来呢?该项目给了我们答案。下面这幅图是我根据自己对源码的理解画出来,非官方。

Unity ML-Agents整体架构

该项目在训练阶段使用了Socket进行进程间的通信,Python端做Socket Server,Unity Environment(C#实现)来做Socket Client。TensorFlow训练的模型保存为自己的格式(就是训练完成之后生成的bytes文件)。在Inference阶段,使用TensorFlowSharp来读取训练好的模型,用于在Unity Environment中的Brain,来具体指导Agent与环境交互。

3.2 关键部件

还是有必要介绍一下该项目中各个主要的部件,及其相互之间的关系。本部分主要参考自这个页面(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/localized/zh-CN/docs/ML-Agents-Overview.md)。该项目目前的中文文档质量一般,数量也不多,所以还是重点阅读研究英文文档。

ML-Agents 是一个 Unity 插件,它包含三个高级组件:

  • 学习环境(Learning Environment) - 其中包含Unity场景和所有游戏角色。

  • Python API - 其中包含用于训练(学习某个行为或 policy)的所有机器学习算法。请注意, 与学习环境不同,Python API不是Unity的一部分,而是位于外部并通过External Communicator与Unity进行通信。

  • External Communicator - 它将Unity环境与Python API连接起来。它位于Unity环境中。

ML-Agents 的简化框图

Learning Environment包含三个附加组件,它们可帮助组织Unity场景。

  • Agent - 它可以被附加到一个Unity GameObject上(可以是场景中的任何角色),负责生成它的观测结果、执行它接收的动作 并适时分配奖励(正/负)。每个Agent只与一个Brain相关联。这里可以把Agent理解成一个“傀儡”,它是环境与大脑之间的中间层,负责观察环境的状态、并执行大脑的意图。

  • Brain - 它封装了Agent的决策逻辑。实质上,Brain中保存着每个Agent的policy,决定了Agent 在每种情况下应采取的动作。更具体地说,它是从Agent接收观测结果和奖励并返回动作的组件。

  • Academy - 它指挥agent的观测和决策过程。在Academy内,可以指定若干环境参数,例如渲染质量和环境运行速度参数。External Communicator位于Academy内。从代码来看,Academy的实现其实就类似与Gym中ENV。

每个学习环境都会有一个全局的Academy,与每一个游戏角色一一对应的多个Agent。虽然每个Agent必须与一个Brain相连,但具有相似观测和动作的多个Agent可关联到同一个Brain。举例来说,在示例游戏中,我们有两个各自拥有自己军医的军队。因此,在我们的学习环境中将有两个Agent, 每名军医对应一个Agent,但这两个军医都可以关联到同一个Brain。请注意,这两个军医与同一个Brain相连的原因是,他们的观测和动作空间是相似的。这并不意味着在每种情况下,他们都会有相同的观测和动作值。换句话说,Brain定义了所有可能的观测和动作的空间,而与之相连的Agent(在本示例中是指军医)可以各自拥有自己独特的观测和动作值。如果我们将游戏扩展到包含坦克驾驶员NPC,那么附加到这些角色的Agent不能与连接到军医的Agent共享一个Brain(军医和驾驶员有不同的动作)。

ML-Agents 的示例框图

我们尚未讨论ML-Agents如何训练行为以及Python API和External Communicator的作用。在我们深入了解这些细节之前,让我们总结一下先前的组件。每个游戏角色上附有一个Agent,而每个Agent都连接到一个Brain。Brain从Agent处接收观测结果和奖励并返回动作。Academy除了能够控制环境参数之外,还可确保所有Agent和Brain都处于同步状态。那么,Brain如何控制Agent的动作呢?

实际上,我们有四种不同类型的Brain,它们可以实现广泛的训练和预测情形:

  • External - 使用Python API进行决策。这种情况下,Brain收集的观测结果和奖励通过External Communicator转发给Python API。Python API随后返回 Agent 需要采取的相应动作。

  • Internal - 使用TensorFlow训练的模型进行决策。TensorFlow训练的模型包含了学到的policy,Brain直接使用 此模型来确定每个 Agent 的动作。

  • Player - 使用键盘或控制器的实际输入进行决策。这种情况下,人类玩家负责控制Agent,由Brain 收集的观测结果和奖励不用于控制Agent。

  • Heuristic - 使用写死(硬编码 hard-coded)的逻辑行为进行决策,目前市面上大多数游戏角色行为都是这么定义的。这种类型有助于调试具有硬编码逻辑行为的Agent。也有助于把这种由硬编码逻辑指挥的Agent与训练好的Agent 进行比较。在我们的示例中,一旦我们为军医训练了Brain,我们便可以为一个军队的军医分配经过训练的 Brain,而为另一个军队的军医分配具有写死逻辑行为的Heuristic Brain。然后,我们可以评估哪个军医的效率更高。

根据目前所述,External Communicator 和 Python API 似乎 只能由 External Brain 所用。实际并非如此。 我们可以配置 Internal、Player 和 Heuristic 类型的 Brain, 使它们也能通过 External Communicator(一种称为 broadcasting 的功能) 将观测结果、奖励和动作发送给 Python API。我们很快就会 看到,这样可以实现其他的训练模式。

包含多个Agent和Brain的场景配置示例

4. 其他一些想法

PyTorch发展势头非常迅速,Tensorflow是基于静态计算图模型(Static Computational Graph, SCG),而PyTorch基于动态图模型(Dynamic Computational Graph, DCG)。他们都有各自的优势和劣势,关于两者的对比网上有很多总结的帖子,例如这个(https://www.quora.com/Should-I-go-for-TensorFlow-or-PyTorch),这个(https://www.forbes.com/sites/quora/2017/07/10/is-pytorch-better-than-tensorflow/#1dd3199173b7)。两者都是很成功的深度学习框架,拥有很多用户。具体如何选择,还要根据自己的需求来决定。在Unity Ml-Agent这里,目前也只能选择Tensorflow......
不知道什么时候Unity官方能支持PyTorch。但仔细想想,难度应该很大。首先,Tensorflow更加成熟,生态系统发展更加完善。像WebGL上用的Tensorflow.js(https://js.tensorflow.org/),移动设备上用的tensorflow lite(https://www.tensorflow.org/mobile/tflite/),有强大的google在背后做支撑,产品线一应俱全。PyTorch还在发展过程中,这些东西几乎没有。其次,但是非常重要的一点是,Unity一直使用CSharp作为首要开发语言(以前的Unity Script已被抛弃),TensorflowSharp(https://github.com/migueldeicaza/TensorFlowSharp)正好提供了这样一个中间层, 对TensorFlow C API 进行.NET封装,使得在Unity中使用Tensorflow变成了现实。而PyTroch呢?是从Lua(虽然游戏界比较常用,但总体来说非常小众的脚本语言)移植过来的,是完全面向Python的语言,想与CSharp结合?除非有人专门去做,目前来看,这个需求实在是小众。
尽管如此,并不是说完全不能使用PyTorch来训练模型,通过曲线救国的方法,目前或许可以尝试一下下面几个思路:
1)使用PyTorch训练模型,使用开源的模型转换器,把训练好的模型转成Tensorflow的格式,这个github(https://github.com/ysh329/deep-learning-model-convertor)中集合了现有的一些主流的深度学习框架模型转换器,值得尝试。
2) 使用ONNX(Open Neural Network Exchange)。ONNX(https://onnx.ai/)是一个深度学习模型开放格式,它相当于制定了一个标准格式,让各个框架训练出来的模型具备互操作能力。开发者使用它可以非常轻松的在深度学习框架、工具之间来回切换,能有效提高训练结果的复用能力。PyTorch 1.0 版本也有望支持更多的平台(https://www.forbes.com/sites/janakirammsv/2018/05/04/facebook-announces-pytorch-1-0-and-expanded-onnx-ecosystem/#4b4bfb843fc0)。
纯属这么一说,我没有做任何实验。;)

看到这里很容易,但要做到这里肯定需要花费不少时间,“时间是世界上一切成就的土壤”,相信付出就会有收获。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容