AlphaZero,DeepMind陣營的最強棋士。python
關於AlphaZero的理論分析已經很多,最近Applied Data Science的聯合創始人David Foster,寫出了一份詳細的教程,教你如何搭建一套屬於本身的AlphaZero系統。並且還附上了代碼。git
原文地址:https://medium.com/applied-data-science/how-to-build-your-own-alphazero-ai-using-python-and-keras-7f664945c188github
如何構建本身的AlphaZero算法
首先,咱們須要學習和理解AlphaGo Zero的原理。我以前寫過一篇AlphaGo Zero的知識點速查手冊可供參考,Tim Wheeler的博客中一篇文章給也講的很詳細,一併推薦給你。後端
知識點速查手冊:網絡
https://medium.com/applied-data-science/alphago-zero-explained-in-one-diagram-365f5abf67e0app
Tim Wheeler博客:函數
http://tim.hibal.org/blog/alpha-zero-how-and-why-it-works/學習
我將基於下面這個代碼庫進行講解:ui
https://github.com/AppliedDataSciencePartners/DeepReinforcementLearning
咱們應該從哪裏開始構建本身的AlphaZero呢?
別急,能夠從運行Jupyter notebook中run.ipynb的前兩個panel開始。一旦它對遊戲有了足夠的定位,那麼神經網絡將開始訓練。經過額外的自我對弈和訓練,它將逐漸在預測遊戲中的各個行爲的價值和下一步行動上作得愈來愈好,從而作出更好的決策和更聰明的遊戲。
如今,咱們須要更詳細地看看面前的代碼,而且展現下AI是怎樣隨時間愈來愈厲害的。
咱們的算法將要學習如何玩Connect4(四子連珠)這個遊戲。雖然不如圍棋那樣複雜,但也有4531985219092種遊戲位置。
遊戲規則很簡單。玩家輪流在任何一欄的頂部佈置本身的顏色。誰最早在垂直、水平或對角線上都放置了同一種顏色就獲勝了,若是這種狀況沒有出現,那遊戲就是平局。
下面是組成代碼庫的關鍵文件:
game.py
這個文件包含Connect4的遊戲規則。
每一個正方形都被分配了一個從0到41的數字,以下圖所示:
game.py文件給除了從一種遊戲狀態到另外一種狀態的邏輯,而且給出了一個選擇的動做。好比,考慮到empty board和38號動做,takeAction方法返回到一個新的遊戲狀態,也就是底部一行的中心位置。
你能夠將game.py文件用任何符合相同API和算法的遊戲文件替換掉,根據你給它的規則,經過自我對弈的方法學習。
run.ipynb
這個文件包含開啓學習過程的代碼。它經過算法中的主要環節加載遊戲規則,而且由三個階段組成:
1.自我對弈
2.從新訓練神經網絡
3.評估神經網絡
有兩個智能體也參與到這個環節中,他們分別爲best_player和current_player。
best_player包含執行最佳的神經網絡,而且能夠用於生成自我對弈的記憶。而後,current_player在這些記憶上從新訓練它的神經網絡,而後再與best_player對弈。若是它贏了,best_player內部的神經網絡被轉換爲current_player內部的神經網絡,而後循環再次啓動。
agent.py
這個文件包含遊戲中的一個玩家Agent class。在遊戲中,每一個玩家都是用本身的神經網絡和蒙特卡羅搜索樹進行初始化的。
咱們須要用simulate method運行蒙特卡羅樹搜索過程。具體老說,智能體移動到樹的葉節點,用它的神經網絡對節點進行評估,而後經過樹將節點的值返回。
以後,咱們還須要用act method屢次重複模擬,讓智能體理解從當前位置移動最有利。而後它將最終選擇的動做返回到遊戲中,以執行動做。
最後,replay method利用之前遊戲的記憶,從新訓練神經網絡。
model.py
這個文件包括Residual_CNN類,這定義瞭如何構建一個神經網絡的實例。
它使用了AlphaGo Zero論文中的神經網絡結構的濃縮版本,而後是許多殘差層,而後分裂成價值和策略兩個分支。
卷積過濾的深度和數量能夠在配置文件中指定。
Keras庫用來搭建網絡,後端是TensorFlow。
要在神經網絡中查看單個卷積過濾和密集鏈接的層,請在run.ipynb notebook中運行如下內容:
current_player.model.viewLayers()
MCTS.py
這裏包含構成蒙特卡洛搜索樹的節點、邊緣和MCTS類。
MCTS類包含前面提到的moveToLeaf和backFill方法,邊緣類的實例存儲了每一個潛在行棋方法的統計信息。
config.py
在這裏設置影響算法的關鍵參數。
調整這些變量會影響運行時間、神經網絡的準確性和算法的總體成功與否。上述參數能生成一個高質量的四子連珠(Connect4)玩家,但須要深長時間。想讓算法加速,能夠嘗試用以下的參數替代:
funcs.py
這裏包括兩個智能體之間對弈的playMatches以及playMatchesBetweenVersions函數。
要和你的做品對弈,能夠運行下面的代碼(也是在run.ipynb notebook中)。
initialise.py
運行算法時,全部模型和memory文件都保存在根目錄下的run文件夾中。
要從某一記錄點重啓算法,須要把run文件夾轉移到run_archive文件夾,並在文件夾名中加入運行編號。而後把運行編號、模型版本號和memory版本號輸入到initialise.py文件中,對應run_archive文件夾中的相關文件。
其餘
memory.py:Memory類的實例存儲之前的遊戲,算法用這個來從新訓練當前玩家(current_player)的神經網絡。
loss.py:這個文件包括一個自定義的損失函數。
settings.py:run和run_archive文件夾的位置。
loggers.py:日誌文件保存到run文件夾下的log文件夾中。要打開日誌記錄,請在這個文件夾中,將logger_disabled變量的值設置爲False。
下圖來自logger.tourney文件,能夠看到每一個下法的機率。
結論
通過幾天的培訓後,咱們的模型會產生下面這樣的mini-batch的迭代損失數值:
最上面的一行是策略端的偏差(MCTS的交叉熵移動機率與神經網絡的輸出相對應),底部是與值之間的偏差(實際遊戲值與神經網絡值之間的均方差),中間這根線是上述二者的平均值。
顯然,隨着訓練時間的增長,神經網絡在預測每一個遊戲狀態的值和可能的下一步動做方面變得愈來愈好。
爲了展現這一成果是如何在更強的比賽中大展身手的,我讓17名玩家之間進行了一次聯賽,從首次迭代的神經網絡到第49次迭代,每對搭檔都交手了兩次,兩名玩家都有機會先上場。
最終的排名以下:
很明顯能夠看出,神經網絡的後期版本優於早期版本,贏得了大部分遊戲。但彷佛學習尚未飽和——隨着訓練時間的延長,玩家還在變得更厲害,學習更多更復雜的策略。
例如,神經網絡一直秉持的清晰策略是儘早搶佔中心欄,咱們能夠觀察下算法第一版和第30版的區別——
這是個不錯的策略,由於不管是經過哪一種方法取勝,都須要佔據中心列,因此玩家須要搶佔先機。
最重要的是,這是由神經網絡本身學會的,中途沒有任何人類輸入。
在games文件夾中,有一個名爲Metasquares的game.py文件。所謂Metasquares,就是雙方在網格中輪流下棋,棋子連成的方塊越大,得分越高。
若是把Connect4 game.py替換成Metasquares game.py,一樣的算法就開始學習玩新的Metasquares遊戲。
End