Unity機器學習 | 編寫代理及建立遊戲AI
自2017年9月Unity推出了機器學習代理工具, 機器學習的開發者持續增長並在社群中獲得認可。Unity機器學習代理專案入選mybridge評選2017年最佳30個機器學習開源專案,並在Github中獲得1710星。Unity機器學習社群挑戰賽也在如火如荼的進行中。
今天的文章中,我們將會學習如何設定一個基本代理,它能利用強化機器學習達到隨機選擇的數字目標。我們將使用到最新的Unity機器學習代理工具建立並訓練代理,完成指定任務,並探討將這個簡單的代理優化為真正的遊戲AI。
設定Unity機器學習代理工具和TensorFlow
開始之前,我們需要設定好機器學習代理工具。設定請參考以下文章:
配置Unity機器學習代理工具和TensorFlow環境
Mac下配置Unity機器學習代理工具
說明:本文的程式碼和執行環境基於Windows 10環境。
機器學習代理(ML-Agents)場景設定
當我們完成設定後,開啟Unity專案,建立新場景。
首先新建一個遊戲物件,命名為“NumberAcademy“。新增“TemplateAcademy”元件到“NumberAcademy“遊戲物件中。
TemplateAcademy元件指令碼可從Github下載:
https://github.com/Unity-Technol ... /TemplateAcademy.cs
場景設定過程並不需要這個元件做太多事,所以我們只用模板中的基本內容即可。
NumberAcademy遊戲物件
在這個元件下,建立子游戲物件,命名為“NumberBrain“。
新增一個Brain元件。將狀態數量(State Size)和動作數量(Action Size)的值設為2。將動作空間型別(Action Space Type)設為離散(Discrete)。
在這專案中,我們將會用到兩個獨立的動作,也就是“上”和“下”。之所以使用離散型別,是因為這些動作會以整數值形式呈現。
將狀態空間型別(State Space Type)設為連續(Continuous)。我們將跟蹤兩個浮點數,所以使用連續型別。
NumberBrain遊戲物件
將大腦型別(Brain Type)設為玩家(Player),並加入兩個動作。選擇任意兩個鍵位,在此我們選擇的是A和B,並分別賦值為0和1。繫結0的鍵位將減小當前值,而繫結1的鍵位將增大它。
Brain指令碼元件
現在我們來建立新指令碼,命名為NumberDemoAgent.cs,將其基本類設定為Agent,替換原有的“: MonoBehaviour with : Agent”。程式碼如下:
[C#] 純文字檢視 複製程式碼
|
currentNumber和targetNumber欄位在這段程式碼裡最重要。其它的程式碼都是用作除錯和視覺化。我們的代理將挑選一個隨機的targetNumber,試著通過使用增長和減小指令,將currentNumber的值調整到目標值。
下面將重寫CollectState方法。程式碼如下:
[C#] 純文字檢視 複製程式碼
|
在上面這段段程式碼裡,我們會返回兩個浮點數給currentNumber和targetNumber,作為代理的狀態。
注意:這裡是如何匹配二個狀態變數的,而且它們都是浮點數,這就是為什麼我們要將狀態空間型別設為連續而不是分離。
為了訓練我們的代理,需要選取隨機目標數,所以要重寫AgentReset()方法。程式碼如下:
[C#] 純文字檢視 複製程式碼
|
最後也是最重要的一部分是AgentReset()方法。這是我們的輸入動作,處理任務,也就是迴應動作,如果代理回報(reward)結果則為成功。
程式碼如下:
[C#] 純文字檢視 複製程式碼
|
首先我們會看到文字的變化。這只是用於除錯或視覺化,它讓我們能看到當前值,還有目標值,以及我們所需要解決問題(即達到目標值)所測試的數值次數。
下一步是切換檢視動作和完成任務的地方。在示例中,指令碼要麼通過減小當前值迴應動作0,要麼增大當前值迴應動作1。除此之外,輸入的其它值都無效,但若是指令碼得到了其它值,指令碼會忽略這個值並返回。
現在我們基於currentNumber移動立方體,這個值會用作x軸偏移值。該立方體在此用於視覺化,對實際的邏輯或訓練過程沒有任何影響。
然後檢查currentNumber對大小限制的反應。因為我們選取的隨機數是在-1和1之間的,如果隨機數為-1.2或是1.2,將視作失敗,因為數值超過了極限。本示例中,我們給代理回報-1,表示失敗,然後給done變數賦值為true,以讓代理能重置並再次嘗試。
最後,我們會檢查currentNumber和目標值的差值是否小於0.01。若小於,則認為是匹配值,將回報(reward)值設為1.0,表示成功,給done賦值為true表示完成。我們還會再次期間使用solved變數作為計數器,用於除錯,這樣我們就能知道成功的次數了。
下面是完整的指令碼程式碼:
[C#] 純文字檢視 複製程式碼
|
設定代理
現在指令碼完成了,我們需要新建遊戲物件,命名為“NumberDemoAgent”。
將剛剛寫好的NumberDemoAgent.cs指令碼附加到該遊戲物件上,並將NumberBrain新增到該元件的Brain部分。
NumberDemoAgent遊戲物件
下一步新建文字(Text)物件,將其放到明顯的位置,理想位置是在螢幕的中央,字號要大。將該文字物件附加到NumberDemoAgent上。
新建立方體(Cube)物件,將它們也新增到NumberDemoAgent上,這樣我們可以看到過程的變化,比閱讀一個個數值更輕鬆。
在執行模式下測試
點選play,就能用設定好的鍵位A和B,左右移動立方體。當我們將方塊向球體移動時,它將增大solved計數器,並重置。如果朝錯誤的方向移動的太遠,它也會重置(請記住1.2的範圍值限制)。
訓練
當它在執行模式下成功執行後,選擇brain並把Brain Type設為外部(External)。儲存場景,並構建一個可執行檔案,檔案中只包含了一個啟用除錯模式的場景。
關於輸出資料夾,選擇python資料夾作為存放這個機器學習代理專案的資料夾。例如,我的資料夾的地址是這個:C:\ml-agents\python。別忘了該可執行檔案的名字,因為後續我們就需要它了。
Anaconda / Jupyter
啟動Anaconda命令指示符。將目錄定位到剛剛的構建目錄,也就是那個python資料夾下,命令示例:cd c:\ml-agents\python
輸入命令“jupyter notebook”(提示:這裡可能要打兩次回車),自動開啟瀏覽器介面。會得到這樣一個網頁介面:
提示:這裡要修改高亮部分。對於env_name變數,要輸入可執行檔案的名字。對於buffer_size和batch_size,你可以使用截圖裡的值。要注意,這裡面的當前值部分只在測試的時候會看到。
當編輯好Hyperparameters部分後,按照步驟執行。從第一步和第二步開始。在第三步時,你會看到一個開啟的遊戲視窗。第一次開啟時,你也許會得到視窗許可對話方塊,記得要選擇允許。
在進行到第四步時,先注意得到的結果,第一次執行時也許會需要幾分鐘。
當它儲存多次後,點選stop按鈕。然後繼續第五步,並執行。這將匯出你的訓練資料到一個與可執行檔案同名的.bytes檔案中,匯出位置在上述python目錄的子目錄下。示例:python/models/ppo。
複製.bytes檔案,(再次提醒,它的名字會和你的可執行檔名字一樣)將這個貼上到Unity專案裡的某個位置。
選擇Brain指令碼元件,將Brain Type設為Internal。把.byetes檔案新增到Graph Model欄位上。
儲存並點選執行,就這樣我們就完成建立自定義代理。
結語
這個示例相當簡單,只是用來讓你理解這個系統的運作方式。我們很期待能看到這個專案你能夠繼續開發,並構建成更大更有趣的專案,用來控制遊戲AI,從而製作出有意思的遊戲機制和AI。更多精彩的機器學習文章歡迎訪問 Unity官方社群(Unitychina.cn)! 更多Unity機器學習社群挑戰賽的資訊請訪問Unity Connect!
參考資訊
Unity ML Agents GitHub
https://github.com/Unity-Technologies/ml-agents
HyperParameters Doc
https://github.com/Unity-Technol ... st-practices-ppo.md
2017年最佳30個機器學習開源專案
https://medium.mybridge.co/30-am ... v-2018-b853b8621ac7