安妮 允中 編譯整理 本文經AI新媒體量子位(公眾號ID:qbitai )授權轉載,轉載請聯絡出處。
AlphaZero,DeepMind陣營的最強棋士。
關於AlphaZero的理論分析已經不少,最近Applied Data Science的聯合創始人David Foster,寫出了一份詳細的教程,教你如何搭建一套屬於自己的AlphaZero系統。而且還附上了程式碼。
原文地址:https://medium.com/applied-data-science/how-to-build-your-own-alphazero-ai-using-python-and-keras-7f664945c188
如何構建自己的AlphaZero
首先,我們需要學習和理解AlphaGo Zero的原理。我之前寫過一篇AlphaGo Zero的知識點速查手冊可供參考,Tim Wheeler的部落格中一篇文章給也講的很詳細,一併推薦給你。
知識點速查手冊:
https://medium.com/applied-data-science/alphago-zero-explained-in-one-diagram-365f5abf67e0
Tim Wheeler部落格:
http://tim.hibal.org/blog/alpha-zero-how-and-why-it-works/
程式碼
我將基於下面這個程式碼庫進行講解:
https://github.com/AppliedDataSciencePartners/DeepReinforcementLearning
我們應該從哪裡開始構建自己的AlphaZero呢?
別急,可以從執行Jupyter notebook中run.ipynb的前兩個panel開始。一旦它對遊戲有了足夠的定位,那麼神經網路將開始訓練。通過額外的自我對弈和訓練,它將逐漸在預測遊戲中的各個行為的價值和下一步行動上做得越來越好,從而做出更好的決策和更聰明的遊戲。
現在,我們需要更詳細地看看面前的程式碼,並且展示下AI是怎樣隨時間越來越厲害的。
Connect4
我們的演算法將要學習如何玩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版的區別——
△ 初版神經網路
△ 第30版的神經網路
這是個不錯的策略,因為無論是通過哪種方法取勝,都需要佔據中心列,所以玩家需要搶佔先機。
最重要的是,這是由神經網路自己學會的,中途沒有任何人類輸入。
學習不同的遊戲
在games資料夾中,有一個名為Metasquares的game.py檔案。所謂Metasquares,就是雙方在網格中輪流下棋,棋子連成的方塊越大,得分越高。
如果把Connect4 game.py替換成Metasquares game.py,同樣的演算法就開始學習玩新的Metasquares遊戲。
End