AI玩跳一跳的終極奧義:首個端到端神經網路,看AI在玩遊戲時注意什麼

本文首發於新智元!

相對新智元的原文略有刪改!

1 前言

微信跳一跳自發布以來,迅速成為了人們茶餘飯後的休閑利器,同時也演變成了各路程序員的競技場。程序員們爭先開發出各種牛逼外掛,讓計算機自己來玩跳一跳,把小遊戲玩出了新的境界。

然而,在深度學習如此火熱,AlphaZero已經征服各種棋類,Atari遊戲已經被計算機吊打的情況下,目前出來的各種外掛版本,大多採用傳統的方法來實現,比如使用傳統計算機視覺的顏色,邊緣檢測等方法來尋找棋子的位置。傳統做法,雖然已能夠在遊戲中取得較好分數,但是代碼複雜,需要針對不同手機設置不同的參數,簡單點說就是逼格不夠,不夠AI。

那麼,到底能不能用純深度神經網路來玩跳一跳呢?

答案當然是Yes。

在本文中,我們祭出微信跳一跳AI的終極奧義:僅使用一個端到端的神經網路,就能玩!

2 代碼

Talk is easy, show me the code!

So, here is the code??:

songrotek/wechat_jump_end_to_endgithub.com圖標

這個git僅包含所需的運行代碼,就兩個文件一個ios,一個android。

使用方法非常簡單:

(1)安裝iOS或Android開發所需的軟體及依賴,具體詳見:

https://github.com/wangshub/wechat_jump_game/wiki/Android-%E5%92%8C-iOS-%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4github.com圖標

(2) 安裝本代碼所需的PyTorch深度學習框架:

pytorch.orgpytorch.org

(3) 手機連接好電腦,注意iphone需要在run_ios.py中更改一下WebDriverAgentRunner運行後得到的ip。打開微信跳一跳,然後在Terminal中輸入:

python run_ios.py

或者

python run_android.py

接下來就是見證奇蹟的時刻!

再看看代碼,也就是100行!驚不驚喜!意不意外!

這到底是怎麼實現的呢?

下面我們來解密實現方法!

3 端到端神經網路玩跳一跳是怎麼實現的?

估計有很多朋友的第一反應是:難道是用深度增強學習(Deep Reinforcement Learning),也就是AlphaGo的方法?

老實說我一開始也是打算這麼乾的,但是具體分析一下發現並不是那麼好做。首先是我們獲取不了遊戲內部數據,不方便獲取Reward,即使我們要自己設定一個Reward,比如計算棋子離盒子正中心的位置,我們依然需要通過計算機視覺分析的方式實現,違背了我們純端到端神經網路實現的初衷。其次是跳一跳這個小遊戲,玩的速度很慢,基本上一步要一秒多。而使用深度增強學習最大的問題就是需要訓練幾十萬步。這樣看來,要用深度增強學習訓練出一個能玩的網路,大概要訓練到明年吧!

因此,我們不用深度增強學習,而改用模仿學習(Imitation Learning)!並且使用模仿學習中最簡單的行為克隆(Behavior Cloning)方法。簡單的說,就是收集很多好的遊戲輸入輸出數據,然後使用監督學習訓練。

本質上說,這種模仿學習的做法就是把人工編寫的複雜程序存進一個神經網路中!

好了,確定了方法論。下面就可以開始具體實施了。

3.1 構造遊戲資料庫

從哪裡搞到很多的遊戲輸入輸出數據呢?別忘了,傳統方法都已經可以玩到10000分以上了,我們完全可以用傳統方法來收集數據。在這裡,我基於下面的代碼稍作修改收集數據:

BeiTown/wechat_jump_gamegithub.com圖標

這個代碼加了點小AI,訓練了通過線性回歸訓練了一個簡單的線性模型來估計跳躍距離和按壓時間的關係,相對人工設定的參數會好一些。

一個用線性模型玩跳一跳的結果

有了這個,我們就可以將每一次跳躍的屏幕截圖及按壓時間記錄下來:

其中圖像先做一下預處理,居中裁成正方形,方便之後的訓練,而按壓數據則存在Json中,一個圖片名稱對應一個按壓時間。圖片名稱很簡單,直接使用的截圖時間。

就這樣,我們讓微信跳一跳跳了n個小時,終於收集到了5000多個數據樣本。

有了資料庫,下面就是如何訓練了。

3.2 構造端到端神經網路模型及訓練

這裡我構造了一個5層的卷積神經網路,每一層神經網路包含一個64 通道的3x3 卷積核的卷積層,一個BatchNorm,一個ReLU及一個2x2的Max-Pooling層。具體如下圖所示:

由於輸出的按壓時間是一個單值,非常簡單,我們使用Mean Square Error來作為模型的損失函數Loss。因此,我們的模型是一個簡單的回歸模型。我們使用構建的資料庫進行訓練。在訓練之前,我們對圖像數據進行預處理,將其壓縮成224x224的RGB圖像,然後再輸入到神經網路。我們採用Adam作為優化器,學習率設定為0.001,訓練200個episode,一個episode隨機遍歷整個數據集一遍。

具體的訓練代碼見:

https://github.com/songrotek/wechat_jump_end_to_end_traingithub.com圖標

4 神經網路在玩遊戲的過程中思考了嗎?

上面就是端到端神經網路的實現方法,看起來過於簡單了。只玩到這不太符合我們的Geek精神。因此,我們不禁要問:神經網路在玩遊戲的過程中思考了嗎?是不是神經網路也思考了傳統做法中我們人考慮的問題,比如確定棋子和盒子的位置。為了驗證這一點,我們做的一個額外的實驗,構建一個帶有注意力(Attention)機制的神經網路進行訓練。我們使用一個4層的U-Net來輸出一個和圖像輸入維度一致的注意力蒙版(Attention Mask),然後將原有圖像與注意力蒙版相乘(Element-wise Product)就得到帶蒙版的圖像,即僅考慮注意力區域的圖像。然後將帶蒙版圖像輸入到4層卷積全連接後輸出按壓時間。具體網路結構如下圖所示:

注意力蒙版每一個維度的值我們限制為[0,1],越趨於1就表示越關注,反之亦然。基於這樣的網路模型訓練後,我們就可以來看看神經網路關注了什麼。下面是一些對應的截圖:

可以看出,神經網路一定程度上自動捕捉了棋子和盒子的位置信息,特別注意棋子上頭的高亮,這非常符合人玩遊戲的方式,也符合傳統做法的方法。一定程度上說明整個端到端神經網路內部也會自動捕捉到這些重要的位置信息!

5 小結

微信跳一跳的終極奧義就介紹到這了!大家肯定會驚訝於深度學習的神奇之處。老實說只看運行的代碼我也非常驚訝。但是再看看訓練的方式似乎不過如此。這大概也是深度學習的魅力吧!

希望這個Work能給大家帶來更多歡樂!

推薦閱讀:

TAG:深度学习DeepLearning | 人工智能 | 跳一跳 |