安妮 允中 編譯整理
量子位 出品 | 公眾號 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
量子位元把其中的核心內容轉發如下。
首先, 我們需要學習和理解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開始。 一旦它對遊戲有了足夠的定位, 那麼神經網路將開始訓練。 通過額外的自我對弈和訓練, 它將逐漸在預測遊戲中的各個行為的價值和下一步行動上做得越來越好, 從而做出更好的決策和更聰明的遊戲。
現在, 我們需要更詳細地看看面前的代碼,
Connect4
我們的演算法將要學習如何玩Connect4(四子連珠)這個遊戲。 雖然不如圍棋那樣複雜, 但也有4531985219092種遊戲位置。
遊戲規則很簡單。 玩家輪流在任何一欄的頂部佈置自己的顏色。 誰最先在垂直、水準或對角線上都放置了同一種顏色就獲勝了,
下面是組成代碼庫的關鍵檔:
game.py
這個檔包含Connect4的遊戲規則。
每個正方形都被分配了一個從0到41的數字, 如下圖所示:
game.py檔給除了從一種遊戲狀態到另一種狀態的邏輯,
你可以將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遊戲。
— 完 —
誠摯招聘
它使用了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遊戲。
— 完 —
誠摯招聘