0. 預(yù)備知識
雖然名字叫做機器學(xué)習(xí)ML江咳,但是主要內(nèi)容還是增強學(xué)習(xí)RL(或者叫強化學(xué)習(xí))购啄。其實并沒有錯巨柒,ML中主要包括監(jiān)督學(xué)習(xí)、非監(jiān)督學(xué)習(xí)和增強學(xué)習(xí)三種范式馍悟,只是這里并沒有監(jiān)督學(xué)習(xí)和非監(jiān)督學(xué)習(xí)的內(nèi)容畔濒。
這還是要從強化學(xué)習(xí)說起,但是為了避免篇幅太長锣咒,這里不做介紹了侵状。網(wǎng)上有很多的學(xué)習(xí)資料,可以自行補課毅整。Richard S. Sutton and Andrew G. Barto 的書 Reinforcement Learning: An Introduction 可以說是該領(lǐng)域的圣經(jīng)趣兄。這里有第二版的pdf(http://incompleteideas.net/book/the-book-2nd.html)。
視頻推薦大神David Silver的課程(https://www.bilibili.com/video/av8912293)悼嫉,他的重點在于傳統(tǒng)的增強學(xué)習(xí)原理艇潭。另外一個課程是UC Berkeley的深度增強學(xué)習(xí)課程(https://www.bilibili.com/video/av20957290),該講師被評為“MIT Tech Review Top 35 Innovators Under 35 (TR35), 2016”戏蔑,結(jié)合最新的深度學(xué)習(xí)講增強學(xué)習(xí)算法蹋凝,很贊!
當(dāng)然总棵,既然是Unity的ml-agent鳍寂,還必須知道Unity到底怎么玩。玩Unity需要使用C#語言彻舰,玩深度學(xué)習(xí)需要使用Python語言。
嗯候味。刃唤。。要學(xué)的東西很多啊白群,是時候繼續(xù)了尚胞!
1. 直觀感受Hello World
官方給出3D平衡小球的示例做出Hello World示例。這個hello world可不簡單帜慢,第一次做還是需要比較多的時間笼裳。但是沒有辦法,這本來就是多個學(xué)科粱玲、多個領(lǐng)域的交叉躬柬,當(dāng)你一步一步做下來并看到最終結(jié)果的時候,才能體會到作為一名程序員的成就感抽减。所以不要猶豫允青,官方文檔講解清晰明了,如果具備了Unity卵沉、增強學(xué)習(xí)颠锉、python法牲、TensorFlow的一點基礎(chǔ)知識,那就趕快開始吧琼掠。畢竟這里還不需要自己去寫代碼拒垃。直觀感受一下能激發(fā)你的求知欲和好奇心。下面上個截圖:
稍作講解瓷蛙,小球在傾斜的地板上會往下滑悼瓮,最終墜落。該地板就是訓(xùn)練出來智能體(Agent)速挑,它通過改變自己的傾斜角度谤牡,使得小球在3D空間中保持平衡。
2. 從頭動手
2.1 環(huán)境構(gòu)建
參考這里(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Learning-Environment-Create-New.md)姥宝,不再贅述翅萤。
2.2 訓(xùn)練
參考這里(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Training-ML-Agents.md),不再贅述腊满。
有幾點事情要注意:
- 得不到收斂的策略套么。默認的訓(xùn)練次數(shù)是max_steps: 5.0e4,是在trainer_config.yaml這個文件中設(shè)定的碳蛋。這個次數(shù)我在訓(xùn)練的時候得不到收斂的policy胚泌,因此需要加大一些;還有一種方案肃弟,就是學(xué)習(xí)3DBall 的那種方式玷室,在場景中復(fù)制多份的環(huán)境,并行訓(xùn)練笤受。
- tensorboard 打開之后不顯示內(nèi)容穷缤。好幾次都遇到這個問題,參考這里(https://stackoverflow.com/questions/44175037/cant-open-tensorboard-0-0-0-06006-or-localhost6006)的解決方法就是:執(zhí)行命令的時候指定host的IP地址箩兽,類似以下命令:
tensorboard --logdir=training:your_log_dir --host=127.0.0.1
然后訪問http://127.0.0.1:6006即可津肛。 - 只有在所有的steps都跑完之后,才會生成bytes文件汗贫,如果按下ctrl+c強行停止身坐,不會生成。
2.3 Play
把訓(xùn)練完成得到的bytes文件拷貝到Unity的工程中落包,這里需要修改Brain類型為Internal部蛇,然后指定Graph Model文件。點擊Play咐蝇,即可看到訓(xùn)練的效果搪花。我設(shè)定了訓(xùn)練step是2.0e5,使用TensorFlow GPU版本,GTX 1060 3GB的顯卡撮竿,訓(xùn)練時間也很短吮便,RollerBall就能妥妥的找到Target!
3. 原理
3.1 與OpenAI Gym的對比
這里不再解釋增強學(xué)習(xí)的概念幢踏,網(wǎng)上有太多的資料可用髓需,比我講解強多了。這里想和OpenAI Gym做一個對比房蝉。再使用Gym做增強學(xué)習(xí)時主要的代碼框架是這樣的:
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已經(jīng)做好了很多個環(huán)境供我們調(diào)用僚匆,只需要關(guān)注自己的增強學(xué)習(xí)算法即可(當(dāng)然,也可以進行擴展搭幻,實現(xiàn)自己的env)咧擂。但是再Unity中并沒有這么便利的工具,我想這也是ml-agents這個項目的出發(fā)點之一檀蹋。Gym畢竟只是一個算法實驗平臺松申,并不能直接用于游戲開發(fā)或者生產(chǎn)實踐。
從上面一段代碼可以看出俯逾,制作環(huán)境需要重點實現(xiàn)的幾個關(guān)鍵函數(shù):
- 環(huán)境需要初始化和關(guān)閉贸桶,如make函數(shù)、close函數(shù)
- 增強學(xué)習(xí)需要多次反復(fù)的訓(xùn)練桌肴,環(huán)境需要重置自身狀態(tài)皇筛,如reset函數(shù)
- 環(huán)境需要定義自身的狀態(tài)空間和動作空間,如action_space,observation_space
- 環(huán)境需要一步一步的執(zhí)行坠七,并返回該步執(zhí)行后環(huán)境的狀態(tài)水醋、回報、結(jié)束標(biāo)記等彪置,如step函數(shù)
3.2 整體架構(gòu)
對于制作環(huán)境來講拄踪,Unity肯定具有天然的優(yōu)勢,而且是三維的悉稠。但是困難又來了宫蛆,目前的深度學(xué)習(xí)框架大多數(shù)是基于Python語言艘包,Unity基于C#語言開發(fā)的猛,環(huán)境和智能體怎么結(jié)合起來呢?該項目給了我們答案想虎。下面這幅圖是我根據(jù)自己對源碼的理解畫出來卦尊,非官方。
該項目在訓(xùn)練階段使用了Socket進行進程間的通信舌厨,Python端做Socket Server岂却,Unity Environment(C#實現(xiàn))來做Socket Client。TensorFlow訓(xùn)練的模型保存為自己的格式(就是訓(xùn)練完成之后生成的bytes文件)。在Inference階段躏哩,使用TensorFlowSharp來讀取訓(xùn)練好的模型署浩,用于在Unity Environment中的Brain,來具體指導(dǎo)Agent與環(huán)境交互扫尺。
3.2 關(guān)鍵部件
還是有必要介紹一下該項目中各個主要的部件筋栋,及其相互之間的關(guān)系。本部分主要參考自這個頁面(https://github.com/Unity-Technologies/ml-agents/blob/master/docs/localized/zh-CN/docs/ML-Agents-Overview.md)正驻。該項目目前的中文文檔質(zhì)量一般弊攘,數(shù)量也不多,所以還是重點閱讀研究英文文檔姑曙。
ML-Agents 是一個 Unity 插件襟交,它包含三個高級組件:
學(xué)習(xí)環(huán)境(Learning Environment) - 其中包含Unity場景和所有游戲角色。
Python API - 其中包含用于訓(xùn)練(學(xué)習(xí)某個行為或 policy)的所有機器學(xué)習(xí)算法伤靠。請注意捣域, 與學(xué)習(xí)環(huán)境不同,Python API不是Unity的一部分醋界,而是位于外部并通過External Communicator與Unity進行通信竟宋。
External Communicator - 它將Unity環(huán)境與Python API連接起來。它位于Unity環(huán)境中形纺。
Learning Environment包含三個附加組件丘侠,它們可幫助組織Unity場景。
Agent - 它可以被附加到一個Unity GameObject上(可以是場景中的任何角色)逐样,負責(zé)生成它的觀測結(jié)果蜗字、執(zhí)行它接收的動作 并適時分配獎勵(正/負)。每個Agent只與一個Brain相關(guān)聯(lián)脂新。這里可以把Agent理解成一個“傀儡”挪捕,它是環(huán)境與大腦之間的中間層,負責(zé)觀察環(huán)境的狀態(tài)争便、并執(zhí)行大腦的意圖级零。
Brain - 它封裝了Agent的決策邏輯。實質(zhì)上滞乙,Brain中保存著每個Agent的policy奏纪,決定了Agent 在每種情況下應(yīng)采取的動作。更具體地說斩启,它是從Agent接收觀測結(jié)果和獎勵并返回動作的組件序调。
Academy - 它指揮agent的觀測和決策過程。在Academy內(nèi)兔簇,可以指定若干環(huán)境參數(shù)发绢,例如渲染質(zhì)量和環(huán)境運行速度參數(shù)硬耍。External Communicator位于Academy內(nèi)。從代碼來看边酒,Academy的實現(xiàn)其實就類似與Gym中ENV经柴。
每個學(xué)習(xí)環(huán)境都會有一個全局的Academy,與每一個游戲角色一一對應(yīng)的多個Agent墩朦。雖然每個Agent必須與一個Brain相連口锭,但具有相似觀測和動作的多個Agent可關(guān)聯(lián)到同一個Brain。舉例來說介杆,在示例游戲中鹃操,我們有兩個各自擁有自己軍醫(yī)的軍隊。因此春哨,在我們的學(xué)習(xí)環(huán)境中將有兩個Agent荆隘, 每名軍醫(yī)對應(yīng)一個Agent,但這兩個軍醫(yī)都可以關(guān)聯(lián)到同一個Brain赴背。請注意椰拒,這兩個軍醫(yī)與同一個Brain相連的原因是,他們的觀測和動作空間是相似的凰荚。這并不意味著在每種情況下燃观,他們都會有相同的觀測和動作值。換句話說便瑟,Brain定義了所有可能的觀測和動作的空間缆毁,而與之相連的Agent(在本示例中是指軍醫(yī))可以各自擁有自己獨特的觀測和動作值。如果我們將游戲擴展到包含坦克駕駛員NPC到涂,那么附加到這些角色的Agent不能與連接到軍醫(yī)的Agent共享一個Brain(軍醫(yī)和駕駛員有不同的動作)脊框。
我們尚未討論ML-Agents如何訓(xùn)練行為以及Python API和External Communicator的作用。在我們深入了解這些細節(jié)之前践啄,讓我們總結(jié)一下先前的組件浇雹。每個游戲角色上附有一個Agent,而每個Agent都連接到一個Brain屿讽。Brain從Agent處接收觀測結(jié)果和獎勵并返回動作昭灵。Academy除了能夠控制環(huán)境參數(shù)之外,還可確保所有Agent和Brain都處于同步狀態(tài)伐谈。那么烂完,Brain如何控制Agent的動作呢?
實際上衩婚,我們有四種不同類型的Brain窜护,它們可以實現(xiàn)廣泛的訓(xùn)練和預(yù)測情形:
External - 使用Python API進行決策效斑。這種情況下非春,Brain收集的觀測結(jié)果和獎勵通過External Communicator轉(zhuǎn)發(fā)給Python API。Python API隨后返回 Agent 需要采取的相應(yīng)動作。
Internal - 使用TensorFlow訓(xùn)練的模型進行決策奇昙。TensorFlow訓(xùn)練的模型包含了學(xué)到的policy护侮,Brain直接使用 此模型來確定每個 Agent 的動作。
Player - 使用鍵盤或控制器的實際輸入進行決策储耐。這種情況下羊初,人類玩家負責(zé)控制Agent,由Brain 收集的觀測結(jié)果和獎勵不用于控制Agent什湘。
Heuristic - 使用寫死(硬編碼 hard-coded)的邏輯行為進行決策长赞,目前市面上大多數(shù)游戲角色行為都是這么定義的。這種類型有助于調(diào)試具有硬編碼邏輯行為的Agent闽撤。也有助于把這種由硬編碼邏輯指揮的Agent與訓(xùn)練好的Agent 進行比較得哆。在我們的示例中,一旦我們?yōu)檐娽t(yī)訓(xùn)練了Brain哟旗,我們便可以為一個軍隊的軍醫(yī)分配經(jīng)過訓(xùn)練的 Brain贩据,而為另一個軍隊的軍醫(yī)分配具有寫死邏輯行為的Heuristic Brain。然后闸餐,我們可以評估哪個軍醫(yī)的效率更高饱亮。
根據(jù)目前所述,External Communicator 和 Python API 似乎 只能由 External Brain 所用舍沙。實際并非如此近上。 我們可以配置 Internal、Player 和 Heuristic 類型的 Brain拂铡, 使它們也能通過 External Communicator(一種稱為 broadcasting 的功能) 將觀測結(jié)果戈锻、獎勵和動作發(fā)送給 Python API。我們很快就會 看到和媳,這樣可以實現(xiàn)其他的訓(xùn)練模式格遭。
4. 其他一些想法
PyTorch發(fā)展勢頭非常迅速,Tensorflow是基于靜態(tài)計算圖模型(Static Computational Graph, SCG)留瞳,而PyTorch基于動態(tài)圖模型(Dynamic Computational Graph, DCG)拒迅。他們都有各自的優(yōu)勢和劣勢,關(guān)于兩者的對比網(wǎng)上有很多總結(jié)的帖子她倘,例如這個(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)。兩者都是很成功的深度學(xué)習(xí)框架硬梁,擁有很多用戶前硫。具體如何選擇,還要根據(jù)自己的需求來決定荧止。在Unity Ml-Agent這里屹电,目前也只能選擇Tensorflow......
不知道什么時候Unity官方能支持PyTorch阶剑。但仔細想想,難度應(yīng)該很大危号。首先牧愁,Tensorflow更加成熟,生態(tài)系統(tǒng)發(fā)展更加完善外莲。像WebGL上用的Tensorflow.js(https://js.tensorflow.org/)猪半,移動設(shè)備上用的tensorflow lite(https://www.tensorflow.org/mobile/tflite/),有強大的google在背后做支撐偷线,產(chǎn)品線一應(yīng)俱全磨确。PyTorch還在發(fā)展過程中,這些東西幾乎沒有声邦。其次俐填,但是非常重要的一點是,Unity一直使用CSharp作為首要開發(fā)語言(以前的Unity Script已被拋棄)翔忽,TensorflowSharp(https://github.com/migueldeicaza/TensorFlowSharp)正好提供了這樣一個中間層英融, 對TensorFlow C API 進行.NET封裝,使得在Unity中使用Tensorflow變成了現(xiàn)實歇式。而PyTroch呢驶悟?是從Lua(雖然游戲界比較常用,但總體來說非常小眾的腳本語言)移植過來的材失,是完全面向Python的語言痕鳍,想與CSharp結(jié)合?除非有人專門去做龙巨,目前來看笼呆,這個需求實在是小眾。
盡管如此旨别,并不是說完全不能使用PyTorch來訓(xùn)練模型诗赌,通過曲線救國的方法,目前或許可以嘗試一下下面幾個思路:
1)使用PyTorch訓(xùn)練模型秸弛,使用開源的模型轉(zhuǎn)換器铭若,把訓(xùn)練好的模型轉(zhuǎn)成Tensorflow的格式,這個github(https://github.com/ysh329/deep-learning-model-convertor)中集合了現(xiàn)有的一些主流的深度學(xué)習(xí)框架模型轉(zhuǎn)換器递览,值得嘗試叼屠。
2) 使用ONNX(Open Neural Network Exchange)。ONNX(https://onnx.ai/)是一個深度學(xué)習(xí)模型開放格式绞铃,它相當(dāng)于制定了一個標(biāo)準(zhǔn)格式镜雨,讓各個框架訓(xùn)練出來的模型具備互操作能力。開發(fā)者使用它可以非常輕松的在深度學(xué)習(xí)框架儿捧、工具之間來回切換荚坞,能有效提高訓(xùn)練結(jié)果的復(fù)用能力挑宠。PyTorch 1.0 版本也有望支持更多的平臺(https://www.forbes.com/sites/janakirammsv/2018/05/04/facebook-announces-pytorch-1-0-and-expanded-onnx-ecosystem/#4b4bfb843fc0)。
純屬這么一說西剥,我沒有做任何實驗。;)
看到這里很容易亿汞,但要做到這里肯定需要花費不少時間瞭空,“時間是世界上一切成就的土壤”,相信付出就會有收獲疗我。