您的位置:首頁>正文

一文詳解如何使用Python和Keras構建屬於你的AlphaZero AI

圖:pixabay

作者:David Foster

「雷克世界」編譯:嗯~是阿童木呀、KABUDA

在這篇文章中, 我將試圖對以下三件事情進行闡述:

1.AlphaZero之所以被認為是人工智慧向前邁進一大步的兩個理由。

2.如何構建AlphaZero方法的副本, 從而使其能夠玩Connect4遊戲。

3.如何調整代碼從而使其能夠插入到其他遊戲中。

AlphaGo→AlphaGo Zero→AlphaZero

2016年3月, 在一場超過2億人觀看次數的比賽中, Deepmind的AlphaGo以 4-1的比分擊敗了獲得過18次世界冠軍的圍棋選手李世石(Lee Sedol)。 一台機器已經學會了能夠下圍棋的超人類策略, 這是一個以往從未有過被認為是不可能的壯舉, 或者, 至少是十年之後才能達到這一水準。

AlphaGo vs李世石的第三場比賽

這本身就是一個了不起的成就。 然而, 2017年10月18日, DeepMind再一次向前邁出了一大步。

在這篇名為《在沒有人類知識的情況下掌握圍棋遊戲》(https://deepmind.com/research/publications/mastering-game-go-without-human-knowledge/)文章中, 揭示了該演算法的一個新變體——AlphaGo Zero, 且以100-0的比分擊敗了AlphaGo。 令人難以置信的是, 它是通過自我學習, 完全“從零開始(tabula rasa)”開始, 並逐漸找到能夠擊敗自身以往身份的策略。 不再需要用人類專家遊戲資料庫去構建一個超越人類的AI。

《在沒有人類知識的情況下掌握圍棋遊戲》文中的圖

僅僅48天后, 在2017年12月5日, DeepMind又發佈了另一篇論文《使用通用強化學習演算法自我學習掌握國際象棋和日本象棋》, 展示了AlphaGo Zero是如何能夠在國際象棋和日本象棋中擊敗世界冠軍項目StockFish和Elmo。 整個學習過程, 從第一次觀看遊戲比賽到成為世界上最好的電腦程式, 僅僅花費了不到24小時的時間。

基於此, AlphaZero就誕生了——這是一種通用演算法, 它能夠快速獲得某些知識,

而不需要任何人類專家策略的先驗知識。

關於這個成就, 有以下兩個令人驚奇的地方:

1. AlphaZero需要零人類專家知識作為輸入

這一點的重要性不言而喻。 這意味著AlphaGo Zero的潛在方法可以應用于任何具有完美資訊的遊戲(兩個玩家都可以隨時瞭解遊戲狀態), 因為除了遊戲規則之外不需要任何專業知識。

這就是為什麼DeepMind能夠在原始AlphaGo Zero論文發表48天后, 便發表國際象棋日本象棋論文。 毫不誇張地說, 所有需要改變的只是輸入檔, 即描述遊戲的機制, 並調整與神經網路和蒙特卡羅樹搜索有關的超參數。

2.該演算法非常優雅

如果AlphaZero使用的是超級複雜的演算法, 世界上只有少數人能夠理解, 那麼這將只不過是一個令人難以置信的成就。

之所以讓它與眾不同的是, 本文中的許多觀點實際上遠沒有以前的版本那麼複雜。 它的核心就在於以下簡單的學習方法:

對可能的未來場景進行思考, 優先考慮最有前景的路徑, 同時考慮其他人將最有可能對自己的行為所作出的反應, 並繼續探索未知的情況。

在達到一個陌生的狀態之後, 評估你對自己的位置是否有利的置信度, 並通過導致這一點的精神通路中的先前位置將分數級聯回來。

在你已經思考了未來的可能性之後, 採取你已經探索過最多的行動。

在遊戲結束時, 返回並評估在哪些位置你對未來位置進行了錯誤評估, 並相應地更新你的理解。

這聽起來不像你在學習玩一個遊戲嗎?當你做出不好的舉動時, 可能是因為你錯誤地判斷了所得到位置的未來價值,或者你錯誤地判斷了你的對手會採取某種行動的可能性,所以沒有想到去探索這種可能性。而這些正是AlphaZero被訓練去學習的遊戲的兩個方面。

如何構建你自己的AlphaZero

首先,查看AlphaGo Zero備忘錄,以便高度瞭解AlphaGo Zero的工作原理。當我們遍歷代碼的每個部分時,你會發現這是很值得參考的。這裡還有一篇很好的文章,更為詳細地解釋了AlphaZero是如何運行的。

代碼

該連結(https://github.com/AppliedDataSciencePartners/DeepReinforcementLearning)裡面包含我將引用的代碼。

要開始學習過程,請運行run.ipynb Jupyter記事本中的前兩個面板。一旦它建立了足夠的遊戲位置來填補它的記憶,神經網路就會開始進行訓練。通過附加的自我練習和訓練,在預測遊戲價值和接下來的任何位置移動的過程中,它將逐漸變得更好,從而做出更好的決策和更聰明的遊戲玩法。

現在我們來看看更詳細的代碼,並展示一些結果,證明隨著時間的推移AI變得更強大。

N.B——這是我對AlphaZero運行原理的理解,主要是基於上面提到的論文中所提供的資訊。如果以下存在任何不正確性,在此致以最真摯的道歉,並盡力糾正!

Connect4

我們的演算法將學習玩的遊戲是Connect4(或者Four In A Row)。不像圍棋那麼複雜,但總共還是會有4,531,985,219,092個遊戲位置。

Connect4

遊戲規則很簡單。玩家輪流在任何可用列的頂部輸入他們的顏色。第一個獲得連續四個顏色的玩家——每一種都呈現垂直、水準或對角,則獲勝。如果整個網格被填滿而沒有成功地創建出同一顏色存在于同一行的現象,則遊戲終止。

以下是組成代碼庫的關鍵檔的總結:

game.py

該檔包含Connect4的遊戲規則。

每個方格分配一個從0到41的數字,如下所示:

Connect4的動作方塊

game.py檔給出了從一個遊戲狀態轉移到另一個遊戲狀態的邏輯,給出了一個選擇的動作。例如,給定一個空板和動作38,takeAction方法返回一個新的遊戲狀態,而起始玩家的部分位於中間列的底部。

你可以用任何符合相同API的遊戲檔替換game.py檔,演算法將原則上根據你給定的規則通過自我學習來學習策略。

run.ipynb

這包含啟動學習過程的代碼。它載入遊戲規則,然後遍歷演算法的主迴圈,其中主要包括三個階段:

1.自我練習

2.重新訓練神經網路

3.評估神經網路

在這個迴圈中有兩個智慧體,best_player和current_player。

best_player包含表現最好的神經網路,並用於生成自我練習的記憶。current_player然後根據這些記憶重新訓練它們的神經網路在,然後與best_player進行互搏。如果它贏了,那麼best_player裡面的神經網路將被切換到current_player中的神經網路,然後,迴圈再次開始。

agent.py

這包含智能體類(遊戲中的玩家)。每個玩家都用自己的神經網路和蒙特卡羅搜尋樹進行初始化。

simulate方法運行蒙特卡洛樹搜索過程。具體來說,智慧體移動到樹的葉節點,用它的神經網路評估節點,然後通過樹回填節點的值。

act方法多次重複模擬,以瞭解從當前位置進行的移動哪個是最有利的。然後它將選定的動作返回給遊戲,以執行該動作。

replay方法使用以前的遊戲記憶重新訓練神經網路。

model.py

使用Keras構建殘差卷積網路的示例

該檔包含Residual_CNN類,該類定義了如何構建神經網路的實例。

它使用的是AlphaGoZero論文中神經網路架構的壓縮版本——即卷積層,接著是許多殘差層,然後分解為一個值和策略。

卷積篩檢程式的深度和數量可以在設定檔中進行指定。

Keras庫是用來建立網路的,且還使用Tensorflow後端。

要在神經網路中查看單個卷積篩檢程式和密集連接層,請在run.ipynb記事本中運行以下內容:

current_player.model.viewLayers()

來自神經網路的卷積篩檢程式

MCTS.py

這包含Node、Edge和MCTS class,它們構成了蒙特卡羅搜尋樹。

MCTS類包含前面提到的moveToLeaf和backFill方法,並且Edge類的實例存儲了每個可能移動的統計資訊。

config.py

你可以在此設置影響演算法的關鍵參數。

調整這些變數將影響演算法的執行時間、神經網路的精准度和整體演算法的成功率。上述參數會產生一個高品質的四子連珠(Connect4)玩家,但這樣做需要花費很長的時間。如果想加快演算法的速度,可以進行以下嘗試。

funcs.py

包含在兩個智慧體之間進行匹配的play matches和play matches between Versions函數。

如果要與你創建的玩家進行對戰,可以運行下面的代碼(這也是在run.ipynb記事本中)

from game import Game

from funcs import playMatchesBetweenVersions

import loggers as lg

env = 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.pyv

運行演算法時,所有模型和記憶體檔都保存在run資料夾的根目錄中。如果稍後要從此檢查點重新開機演算法,需要將運行資料夾轉移到run_archive資料夾中,並將一個運行號附加到資料夾名稱上。然後,將運行編號、型號版本號和記憶體版本號,按照其在run_archive資料夾中的相應位置,輸入到initialise.py文件中。然後從這個檢查點開始,像往常一樣運行演算法。

memory.py

Memory class的一個實例,用以存儲遊戲記錄的記憶,該演算法用於重新訓練current_player的神經網路。

loss.py

此檔包含一個自訂損失函數,用以在傳遞到交叉熵損失函數之前,對非法移動的預測進行遮罩處理。

settings.py

run和run_archive資料夾的位置。

loggers.py

日誌檔保存到運行資料夾中的日誌資料夾中。

要打開日誌記錄,需在此檔中將logger_disabled變數的值設置為False。

查看日誌檔將説明你瞭解演算法的工作原理,並瞭解其“思想”。例如,這裡是logger.mcts檔中的一個示例。

logger.mcts文件中的輸出

同樣來自於logger.tourney檔,你可以在評估階段看到每個與移動相關的概率。

logger.tourney檔的輸出

結果

經過幾天的訓練,可以根據最小梯度的反覆運算次數得出以下損失圖表:

對小批量反覆運算數的損失

最上面的線是策略頭部(policy head)的誤差(MCTS相對於神經網路輸出的交叉熵移動概率)。最下面一行是值頭(value head)的誤差(實際遊戲之和神經網路預測值之間的均方誤差)。中間的線是二者的平均值。

顯然,神經網路在預測每個遊戲狀態的值和下一步可能採取的動作方面正變得越來越好。為了說明這一結果是如何在越來越強的比賽中產生的,我在17名球員中選出了一個聯盟,從神經網路的第1次反覆運算到第49次。每一組玩兩次,兩個玩家都有機會先玩。

這是最後的排名:

顯然,後期版本的神經網路優於早期版本,並贏得了它們之間的大部分比賽。另外,學習似乎並沒有達到飽和,隨著訓練時間的進一步延長,球員們變得越來越強大,並且學習的策略越來越複雜。

例如,隨著時間的推移,神經網路所傾向的一個明確的策略是儘早抓住中心欄。觀察演算法的第1個版本和第30個版本之間的差別:

第1代神經網路版本:

第30代神經網路版本:

這是一個很好的策略,因為很多行都需要中間欄——要求儘早確保對手無法利用這一點。神經網路已經學會了這一點,並且不需要任何輸入。

學習不同的遊戲

遊戲檔中有一個名為“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-7f664945c188

可能是因為你錯誤地判斷了所得到位置的未來價值,或者你錯誤地判斷了你的對手會採取某種行動的可能性,所以沒有想到去探索這種可能性。而這些正是AlphaZero被訓練去學習的遊戲的兩個方面。

如何構建你自己的AlphaZero

首先,查看AlphaGo Zero備忘錄,以便高度瞭解AlphaGo Zero的工作原理。當我們遍歷代碼的每個部分時,你會發現這是很值得參考的。這裡還有一篇很好的文章,更為詳細地解釋了AlphaZero是如何運行的。

代碼

該連結(https://github.com/AppliedDataSciencePartners/DeepReinforcementLearning)裡面包含我將引用的代碼。

要開始學習過程,請運行run.ipynb Jupyter記事本中的前兩個面板。一旦它建立了足夠的遊戲位置來填補它的記憶,神經網路就會開始進行訓練。通過附加的自我練習和訓練,在預測遊戲價值和接下來的任何位置移動的過程中,它將逐漸變得更好,從而做出更好的決策和更聰明的遊戲玩法。

現在我們來看看更詳細的代碼,並展示一些結果,證明隨著時間的推移AI變得更強大。

N.B——這是我對AlphaZero運行原理的理解,主要是基於上面提到的論文中所提供的資訊。如果以下存在任何不正確性,在此致以最真摯的道歉,並盡力糾正!

Connect4

我們的演算法將學習玩的遊戲是Connect4(或者Four In A Row)。不像圍棋那麼複雜,但總共還是會有4,531,985,219,092個遊戲位置。

Connect4

遊戲規則很簡單。玩家輪流在任何可用列的頂部輸入他們的顏色。第一個獲得連續四個顏色的玩家——每一種都呈現垂直、水準或對角,則獲勝。如果整個網格被填滿而沒有成功地創建出同一顏色存在于同一行的現象,則遊戲終止。

以下是組成代碼庫的關鍵檔的總結:

game.py

該檔包含Connect4的遊戲規則。

每個方格分配一個從0到41的數字,如下所示:

Connect4的動作方塊

game.py檔給出了從一個遊戲狀態轉移到另一個遊戲狀態的邏輯,給出了一個選擇的動作。例如,給定一個空板和動作38,takeAction方法返回一個新的遊戲狀態,而起始玩家的部分位於中間列的底部。

你可以用任何符合相同API的遊戲檔替換game.py檔,演算法將原則上根據你給定的規則通過自我學習來學習策略。

run.ipynb

這包含啟動學習過程的代碼。它載入遊戲規則,然後遍歷演算法的主迴圈,其中主要包括三個階段:

1.自我練習

2.重新訓練神經網路

3.評估神經網路

在這個迴圈中有兩個智慧體,best_player和current_player。

best_player包含表現最好的神經網路,並用於生成自我練習的記憶。current_player然後根據這些記憶重新訓練它們的神經網路在,然後與best_player進行互搏。如果它贏了,那麼best_player裡面的神經網路將被切換到current_player中的神經網路,然後,迴圈再次開始。

agent.py

這包含智能體類(遊戲中的玩家)。每個玩家都用自己的神經網路和蒙特卡羅搜尋樹進行初始化。

simulate方法運行蒙特卡洛樹搜索過程。具體來說,智慧體移動到樹的葉節點,用它的神經網路評估節點,然後通過樹回填節點的值。

act方法多次重複模擬,以瞭解從當前位置進行的移動哪個是最有利的。然後它將選定的動作返回給遊戲,以執行該動作。

replay方法使用以前的遊戲記憶重新訓練神經網路。

model.py

使用Keras構建殘差卷積網路的示例

該檔包含Residual_CNN類,該類定義了如何構建神經網路的實例。

它使用的是AlphaGoZero論文中神經網路架構的壓縮版本——即卷積層,接著是許多殘差層,然後分解為一個值和策略。

卷積篩檢程式的深度和數量可以在設定檔中進行指定。

Keras庫是用來建立網路的,且還使用Tensorflow後端。

要在神經網路中查看單個卷積篩檢程式和密集連接層,請在run.ipynb記事本中運行以下內容:

current_player.model.viewLayers()

來自神經網路的卷積篩檢程式

MCTS.py

這包含Node、Edge和MCTS class,它們構成了蒙特卡羅搜尋樹。

MCTS類包含前面提到的moveToLeaf和backFill方法,並且Edge類的實例存儲了每個可能移動的統計資訊。

config.py

你可以在此設置影響演算法的關鍵參數。

調整這些變數將影響演算法的執行時間、神經網路的精准度和整體演算法的成功率。上述參數會產生一個高品質的四子連珠(Connect4)玩家,但這樣做需要花費很長的時間。如果想加快演算法的速度,可以進行以下嘗試。

funcs.py

包含在兩個智慧體之間進行匹配的play matches和play matches between Versions函數。

如果要與你創建的玩家進行對戰,可以運行下面的代碼(這也是在run.ipynb記事本中)

from game import Game

from funcs import playMatchesBetweenVersions

import loggers as lg

env = 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.pyv

運行演算法時,所有模型和記憶體檔都保存在run資料夾的根目錄中。如果稍後要從此檢查點重新開機演算法,需要將運行資料夾轉移到run_archive資料夾中,並將一個運行號附加到資料夾名稱上。然後,將運行編號、型號版本號和記憶體版本號,按照其在run_archive資料夾中的相應位置,輸入到initialise.py文件中。然後從這個檢查點開始,像往常一樣運行演算法。

memory.py

Memory class的一個實例,用以存儲遊戲記錄的記憶,該演算法用於重新訓練current_player的神經網路。

loss.py

此檔包含一個自訂損失函數,用以在傳遞到交叉熵損失函數之前,對非法移動的預測進行遮罩處理。

settings.py

run和run_archive資料夾的位置。

loggers.py

日誌檔保存到運行資料夾中的日誌資料夾中。

要打開日誌記錄,需在此檔中將logger_disabled變數的值設置為False。

查看日誌檔將説明你瞭解演算法的工作原理,並瞭解其“思想”。例如,這裡是logger.mcts檔中的一個示例。

logger.mcts文件中的輸出

同樣來自於logger.tourney檔,你可以在評估階段看到每個與移動相關的概率。

logger.tourney檔的輸出

結果

經過幾天的訓練,可以根據最小梯度的反覆運算次數得出以下損失圖表:

對小批量反覆運算數的損失

最上面的線是策略頭部(policy head)的誤差(MCTS相對於神經網路輸出的交叉熵移動概率)。最下面一行是值頭(value head)的誤差(實際遊戲之和神經網路預測值之間的均方誤差)。中間的線是二者的平均值。

顯然,神經網路在預測每個遊戲狀態的值和下一步可能採取的動作方面正變得越來越好。為了說明這一結果是如何在越來越強的比賽中產生的,我在17名球員中選出了一個聯盟,從神經網路的第1次反覆運算到第49次。每一組玩兩次,兩個玩家都有機會先玩。

這是最後的排名:

顯然,後期版本的神經網路優於早期版本,並贏得了它們之間的大部分比賽。另外,學習似乎並沒有達到飽和,隨著訓練時間的進一步延長,球員們變得越來越強大,並且學習的策略越來越複雜。

例如,隨著時間的推移,神經網路所傾向的一個明確的策略是儘早抓住中心欄。觀察演算法的第1個版本和第30個版本之間的差別:

第1代神經網路版本:

第30代神經網路版本:

這是一個很好的策略,因為很多行都需要中間欄——要求儘早確保對手無法利用這一點。神經網路已經學會了這一點,並且不需要任何輸入。

學習不同的遊戲

遊戲檔中有一個名為“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-7f664945c188

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示