用神經網路玩史萊姆排球
利用遞歸神經網路玩的"史萊姆排球"遊戲。你能打敗AI嗎?
記得Java小程序很流行的時候,我喜歡玩一個叫「 史萊姆排球」 的java遊戲。雖然遊戲的物理引擎讓人忍俊不禁,但是我就是被這樣簡單的遊戲迷住了,曾經在晚上躲在宿舍玩了幾個小時,工作什麼的都忘得一乾二淨。
由於除了過時的JAVA程序版本之外,在網上實在找不到任何新的版本。所以我開始創建我自己的基於js + html5的遊戲版本(完成了神奇的街機風格的「物理引擎」)。我嘗試使用之前寫的的遺傳演算法來訓練一個簡單的循環神經網路來玩史萊姆排球。實際上,我想知道在使用NEAT之類的更先進的演算法之前,如果僅僅是一個簡單的傳統的神經進化技術,是否可以訓練一個神經網路使之成為這個遊戲的專家呢?
第一步是寫一個簡單的物理引擎,完成球與地面的反彈效果,球與圍欄、玩家的碰撞效果。 這是使用JavaScript中的設計器p5.js庫和一些簡單的物理數學方程來完成的。為了使球彈跳功能正常工作,我刷完了矢量數學。完成以上功能後,下一步就是添加鍵盤/觸摸板的操作,使玩家無論在手機上還是電腦上都可以移動、跳躍。
最興奮有趣的部分是創建AI模塊替代玩家控制,看看AI能不能熟練的玩遊戲。最後,我使用基本的CNE方法作為初始測試,訓練標準的循環神經網路,同時利用convnet.js庫訓練。下圖是我們利用循環(神經)網路訓練後的圖表,噹噹噹噹!:
神經網路將代理動作和速度的輸入,球的位置和速度,當然還有對手的一切動作。輸出將三個信號控制項激活,分別是「前進」、「後退」和「跳躍」。另外有4個隱藏的神經元將作為隱藏狀態並反饋給輸入,這種方式實質上是一個無限深層的前饋神經網路,它能自動記住以前發生的事件和狀態,能夠制定更複雜的遊戲策略。有一點要注意,只有在信號高於某個閾值(0.75)時才會觸發這一功能。
我將兩邊的AI代理一分為二,設置成獨立而又相同兩部分,無論AI代理是在圍欄的左邊或是右邊玩,它們的位置都是相對於圍欄的,而球的位置是根據他們是哪一方。這樣一來,被訓練過的的AI代理就可以在圍欄的任何一邊進行遊戲並且使用相同的神經網路。
我沒有使用sigmoid函數,而是使用支持convnet.js的雙曲正切(tanh)函數來控制。
tanh函數定義如下:
tanh函數對於神經網路來說可能是一個更好用的激活函數,因為當輸入被引導時,函數值趨向於+1或-1。x軸是遊戲的輸入部分,例如球與對手的位置和速度(全部在+/-1.0間震蕩或給出另一個1.0)同時也輸出隱藏神經網路的狀態(定義在+/- 1.0以內)。
由於速度和球位置可能是正的或負的,這可能比sigmoid函數更有效率,也更自然。正如前面所解釋的那樣,我同時將輸入也縮小到+/-1.0的範圍,類似於隱藏的神經元的輸出狀態,這樣網路上的所有輸入的大小的平均數就會大致相同。
訓練這樣一個遞歸的神經網路涉及到我之前做的遺傳演算法訓練器,因為實際上沒有適合的方法可以返回一個分數,因為任何一方都會有輸贏。我最終做的是寫一個類似比賽的功能,讓訓練人群中的每個AI都能與其他AI競爭。如果某AI獲勝,它的分數就+1,如果輸了就-1。如果遊戲時間超過擬定的20秒,不得分也不扣分。每個AI將在訓練循環中對抗其他的10個隨機AI。最多只保留20%的AI,其餘的丟棄掉。然後再次交叉訓練產生下一代更強的AI。這種被稱為「淘汰競賽」的方法可以訓練出足夠聰明的AI去玩一對一的遊戲。
通過使用這種方法,我們不需要幫助AI手工編寫任何觸發代碼和遊戲規則,而只是簡單地探索遊戲並找出如何取勝的方法。最後的結果表明,經過幾百代的進化,它們的遊戲技術非常高超!
下一步可以採用更先進的方法,如NEAT、ESP,但對於一個簡單的小遊戲來說,這可能太過了。由於遊戲策略非常簡單,同時,它也是應用在卷積神經網路Deep Q-Learner上的的候選。我想,到目前為止,我已經創造了一個相當強大的史萊姆排球AI,幾乎不可能被人類玩家連續擊敗。
嘗試自己去玩遊戲,看看你是否能夠一直打敗它。它可以在PC(鍵盤控制)或手機/平板上通過觸摸控制。PC版本的操作更加容易一點。你可以隨意使用Github上的源代碼,但是如果它不是最簡潔的結構化代碼,那麼真的對不住了,因為它更像是一個草圖,而不是一個的成熟程序。
翻譯人:Shawn_Kid
原文鏈接:http://blog.otoro.net/2015/03/28/neural-slime-volleyball/
原文作者:otoro
推薦閱讀:
※經濟學人:谷歌、亞馬遜等巨頭有數據技術優勢,會接管麥肯錫、波士頓諮詢手中業務
※使用 Tensorflow 構建生成式對抗網路(GAN)
※AI將會優化越來越多的產業,看看智能機器人就知道了
TAG:AI技術 | 深度學習DeepLearning | 神經網路 |