大數據文摘作品
編譯:葉一、Chloe、彭湘偉、錢天培
在2016年3月,Deepmind研發的AlphaGo以4:1的成績,擊敗了曾榮獲18次世界冠軍的圍棋選手,李世石(Lee Sedol)。超過2億觀眾見證了這一歷史時刻。一臺機器已經學會了一種超越人類的圍棋策略。這在以前被認為是一項不可能完成的任務,或者至少需要十年之功。
AlphaGo與李世石的第3場比賽
這已是一項了不起的成就。然而,在2017年10月18日,DeepMind又再次取得了突破。
論文《無需人類知識就能稱霸圍棋》(Mastering the Game of Go without Human Knowledge),揭示了一種新的算法——AlphaGo Zero,它以100:0的驚人成績打敗了AlphaGo。更令人難以置信的是,它從零開始,通過自我博弈,逐漸學會了能打敗自己之前的策略。至此,開發一個超級AI不再需要依賴人類專家的遊戲資料庫了。
僅48天後的2017年12月5日,DeepMind又發布了另一篇論文《通過一種通用的強化學習算法稱霸西洋棋和日本象棋》(Mastering Chess and Shogi by Self-Play with a General Reinforcement Learning Algorithm),它展示了AlphaGo Zero如何能夠學會西洋棋(StockFish和Elmo)和象棋。整個學習過程,從第一次參與遊戲到成為世界上最厲害的電腦程式,只用了24小時。
就這樣,AlphaZero華麗麗地誕生了——它無需儲備任何人類棋譜,就可以以通用算法完成快速自我升級。
關於這個成就,有兩點最讓人稱奇:
AlphaZero對人類遊戲經驗根本就不需要
這點的重要性怎麼說都不過分。也就是說,對於任何有充分信息的遊戲(對陣雙方對遊戲狀態都全程掌握),AlphaGo Zero的方法論都可以得到完美應用!因為除了遊戲規則之外,人類任何遊戲經驗值都是不需要的。
AlphaGo Zero的基礎方法可以應用於任何具有完美信息的遊戲(遊戲狀態在任何時候,雙方玩家都完全知道的),因為在遊戲規則之外,不需要事先的專家知識。
這就是DeepMind能在發表AlphaGo Zero論文48天後,馬上就能發表第二篇論文。毫不誇張地說,所需要改變的僅僅是新遊戲規則,及與神經網絡和蒙特卡羅樹搜索相關的超參數。
這個算法的優雅程度秒殺眾生
即便AlphaZero使用的是世界上只有極少數人能夠看懂的超複雜算法,它仍然是項了不起的成就。同它相比,之前的算法可謂不複雜不成活,這才是它真正的魅力。究其核心,無非是以下極簡而美的學習邏輯:
腦補各種場景,挑能贏的路走,想想別人會怎麼應對,並不斷探索未知。在思考未來可能的情景時,優先考慮有前途的路徑,同時考慮其他人最有可能如何對你的行動作出反應,並繼續探索未知。遇到不熟悉的狀況,評估它的利害程度,把它同之前的各種讓你走到今天這一步的場景作比較。窮盡你對未來的想像,用你試過最多的招數來應對。在你考慮了未來的可能性之後,採取你已經探索過的行動。遊戲結束時,回頭看看在哪裡犯過錯,然後洗心革面、更新認知。在遊戲結束時,回過頭來評估你在哪裡錯誤地判斷了未來的位置,並相應地更新你的理解。
這聽起來是不是很像你學玩遊戲的方式? 當做錯一個動作時,要麼是因為你誤判了這個動作會帶來的結果,要麼是你誤判了對手可能會採取的行動。這兩點正是AlphaZero學會如何玩遊戲的法門。
如何構建自己的AlphaZero
首先,我們需要學習和理解AlphaGo Zero的原理。我之前寫過一篇AlphaGo Zero的知識點速查手冊可供參考:
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
從運行Jupyter notebook中run.ipynb的前兩個panel開始。一旦它完成了遊戲的足夠回合,那麼神經網絡將開始訓練。通過隨後的自我對弈和訓練,它將逐漸在預測勝率和下一步行動上做得越來越好,從而做出更好的決策。
現在,我們需要更詳細地看看面前的代碼,並且展示下AI是怎樣隨著時間的增加變得越來越厲害的。
四子連珠(Connect4)
我們的算法將要學習如何玩這個遊戲。雖然不如圍棋那樣複雜,但也有4531985219092種遊戲走位。
四子連珠
遊戲規則很簡單。玩家輪流在任何一欄的頂部布置自己的顏色。最先在垂直、水平或對角線上放置一排同一種顏色棋子的玩家獲勝,如果這種情況沒有出現,那遊戲就是平局。
下面是組成代碼庫的關鍵文件:
game.py——這個文件包含四子連珠的遊戲規則
每個正方形都被分配了一個從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
在遊戲中,每個玩家都是用自己的神經網絡和蒙特卡羅搜索樹進行初始化的。
我們需要用模擬的辦法運行蒙特卡羅樹搜索過程。具體地說,智能體移動到樹的葉節點,用它的神經網絡對節點進行評估,然後通過樹將節點的值返回。
之後,我們還需要用act method多次重複模擬,讓智能體理解從當前位置出發的最有利的移動。然後它將最終選擇的動作返回到遊戲中,以執行動作。
最後,replay method利用以前遊戲的記憶,重新訓練神經網絡。
model.py——這個文件包括residual_cnn類,它定義了如何建立神經網絡的實例
用Keras搭建殘差卷積網絡示例
它採用的是AlphaGoZero論文中濃縮版的神經網絡結構——即一個卷積層,接著是許多剩餘層,然後分成一個數值和指揮中樞。
可以在config文件中指定卷積篩選器的深度和數量。
Keras庫是用來與後臺的tensorflow建立網絡。
查看個人的卷積濾波器和濃密連接層的神經網絡,在run.ipynb筆記本運行以下代碼:
current_player.model.viewLayers()
神經網絡中的卷積核
MCTS.py——這個文件包含節點(Node),邊(Edge)和MCTS類,構成了蒙特卡洛樹搜索
MCTS類包含了前文提到的 moveToLeaf 和backFill 方法,以及Edge類的實例存儲有關每個潛在移動的統計信息。
config.py——這是你設置影響算法的關鍵參數的地方
調整這些變量會影響運行時間,神經網絡的準確性和整體算法的成功。以上參數產生一個高品質的四子連珠選手,但要花很長時間才能做到。為了加快算法的速度,請嘗試以下參數。
funcs.py——包含可以在兩個智能體之間進行比賽的playMatches和playMatchesBetweenVersions函數
如果你想挑戰之前創建的智能算法,可以運行下面的代碼(在run.ipynb筆記本)
from game import Gamefrom funcs import playMatchesBetweenVersionsimport loggers as lgenv = Game()playMatchesBetweenVersions(env, 1 # the run version number where the computer player is located, -1 # the version number of the first player (-1 for human), 12 # the version number of the second player (-1 for human), 10 # how many games to play, lg.logger_tourney # where to log the game to, 0 # which player to go first - 0 for random)
initialise.py——當你運行該算法,所有的模型和存儲文件保存在 runfolder的根目錄下
稍後要從此檢查點重新運行算法,請將運行文件夾傳輸到run_archive文件夾,並將運行編號附加到文件夾名稱。然後,將運行編號,型號版本號和內存版本號輸入到initialise.py文件中,對應於run_archive文件夾中相關文件的位置。像往常一樣運行算法,然後從這個檢查點開始。
memory.py
Memory類的一個實例存儲以前遊戲的記憶,該算法用於重新訓練current_player的神經網絡。
loss.py
該文件包含一個自定義損失函數,在傳遞到交叉熵損失函數之前,屏蔽了來自非法移動的預測。
settings.py
run和run_archive文件夾的位置。
loggers.py
日誌文件保存到運行文件夾內的日誌文件夾中。
要打開日誌記錄,請在此文件中將logger_disabled變量的值設置為False。
查看日誌文件將幫助你了解該算法的工作原理,並在其「頭腦」中查看。 例如,下面是logger.mcts文件中的示例。
logger.mcts文件的輸出
同樣從logger.tourney文件,你可以在評估階段看到每個移動的概率:
logger.tourney文件的輸出
訓練出的結果讓人驚喜
通過幾天的訓練,得到以下小批量迭代次數與損失的關係圖:
小批量迭代次數與損失的關係圖
最上面的線是策略頭中的誤差(MCTS移動概率的交叉熵,相對於神經網絡的輸出)。底部的線是價值頭(實際遊戲數值和神經網絡預測值之間的均方誤差)。中間的線是兩者的平均值。
顯然,神經網絡在預測每個遊戲狀態的值以及可能的下一步移動方面正在變得更好。為了說明這個結果如何變得越來越強大,我讓17個參與者組成聯賽,從神經網絡的第1次迭代到第49次。每一組比賽兩次,兩個玩家都有機會先玩。
這是最後的排名:
顯然,神經網絡的最新版本比早期版本更勝一籌,贏得了大部分的遊戲。 這也似乎表明學習過程沒有達到極限 - 隨著訓練時間的進一步延長,玩家將會繼續變得更強大,學習越來越複雜的策略。
作為一個例子,隨著時間的推移,一個神經網絡挑選的策略較早的佔據了中間列。觀察算法的第一個版本與第三十個版本之間的區別:
第一個神經網絡版本
第三十個神經網絡樣本
這是一個很好的策略,因為很多線路都需要中間列 – 儘早佔領這一列可以確保你的對手無法利用這一優勢。 神經網絡已經在沒有人類指導下,學到了這一點。
學習其他遊戲
在遊戲文件中有一個稱為「Metasquares」 的game.py文件。其中的X和O用於形成不同大小的正方形。較大的方格意味著要落更多的棋子,當棋盤布滿時,落子多的一方獲勝。
如果你將Connect4 (四子連珠) 的game.py文件替換成Metasquares的game.py文件,同樣算法將會用於學習玩Metasquares遊戲。
趕緊自己來動手試試吧!
原文地址:
https://medium.com/applied-data-science/how-to-build-your-own-alphazero-ai-using-python-and-keras-7f664945c181