0
| 本文作者: 汪思穎 | 2018-01-15 09:41 |
雷鋒網(wǎng) AI 科技評(píng)論按,本文作者一縷陽光,本文首發(fā)于知乎專欄強(qiáng)化學(xué)習(xí)知識(shí)大講堂,雷鋒網(wǎng) AI 科技評(píng)論獲其授權(quán)轉(zhuǎn)載。

2 個(gè)多月前,AlphaGo Zero 橫空出世,完全從零開始,僅通過自我對(duì)弈就能天下無敵,瞬間刷爆朋友圈,各路大神分分出來解讀,驚嘆于其思想的簡單、效果的神奇。很快就有大神放出了開源版的 AlphaGo Zero,但是只有代碼,沒有訓(xùn)練出來的模型,因?yàn)閾?jù)大神推算,在普通消費(fèi)級(jí)的電腦上想訓(xùn)練出 AlphaGo Zero 的模型需要 1700 年!然而 DeepMind 在 AlphaGo Zero 的論文里只強(qiáng)調(diào)運(yùn)行的時(shí)候需要 4 個(gè) TPU,而完全沒有提及訓(xùn)練過程的最大計(jì)算需求在于生成 self-play 數(shù)據(jù),還引起了一點(diǎn)小爭議。
還好,過了不到兩個(gè)月,在 12 月初,DeepMind 就在 Arxiv 上低調(diào)放出了更加通用的 AlphaZero 的論文。AlphaZero 幾個(gè)小時(shí)就征服圍棋、國際象棋和日本將棋的壯舉再次驚嘆世人,但同時(shí) DeepMind 大方公開的 self-play 階段使用的 5000 個(gè) TPU 也讓大家紛紛感嘆,原來是“貧窮限制了我們的想象力”!
扯得有點(diǎn)遠(yuǎn)了,讓我們回到這篇文章的正題:AlphaZero 實(shí)戰(zhàn),通過自己動(dòng)手從零訓(xùn)練一個(gè) AI,去體會(huì) AlphaZero 自我對(duì)弈學(xué)習(xí)成功背后的關(guān)鍵思想和一些重要技術(shù)細(xì)節(jié)。這邊選擇了五子棋作為實(shí)踐對(duì)象,因?yàn)槲遄悠逑鄬?duì)比較簡單,大家也都比較熟悉,這樣我們能更專注于 AlphaZero 的訓(xùn)練過程,同時(shí)也能通過親自對(duì)陣,來感受自己訓(xùn)練出來的 AI 慢慢變強(qiáng)的過程。
經(jīng)過實(shí)踐發(fā)現(xiàn),對(duì)于在 6*6 的棋盤上下 4 子棋這種情況,大約通過 500~1000 局的 self-play 訓(xùn)練(2 小時(shí)),就能訓(xùn)練出比較靠譜的 AI;對(duì)于在 8*8 的棋盤上下 5 子棋這種情況,通過大約 2000~3000 局自我對(duì)弈訓(xùn)練(2 天),也能得到比較靠譜的 AI。所以雖然貧窮,但我們還是可以去親身感受最前沿成果的魅力!完整代碼以及 4 個(gè)訓(xùn)練好的模型已經(jīng)上傳到了 github:https://github.com/junxiaosong/AlphaZero_Gomoku
我們先來看兩局訓(xùn)練好的 AI 模型(3000 局 self-play 訓(xùn)練得到)對(duì)弈的情況,簡單感受一下:


從上面的對(duì)局樣例可以看到,AI 已經(jīng)學(xué)會(huì)了怎么下五子棋,知道什么時(shí)候要去堵,怎么樣才能贏,按我自己對(duì)陣 AI 的感受來說,要贏 AI 已經(jīng)不容易了,經(jīng)常會(huì)打平,有時(shí)候稍不留神就會(huì)輸?shù)簟?/p>
這里有一點(diǎn)需要說明,上面展示的兩局 AI 對(duì)弈中,AI 執(zhí)行每一步棋的時(shí)候分別只執(zhí)行了 400 次和 800 次 MCTS 模擬,進(jìn)一步增大模擬次數(shù)能夠顯著增強(qiáng) AI 的實(shí)力,參見 AlphaZero 論文中的 Figure 2(注:AlphaZero 在訓(xùn)練的時(shí)候每一步只執(zhí)行 800 次 MCTS simulations,但在評(píng)估性能的時(shí)候每一步棋都會(huì)執(zhí)行幾十萬甚至上百萬次 MCTS 模擬)。
下面,我結(jié)合 AlphaZero 算法本身,以及 github 上的具體實(shí)現(xiàn),從自我對(duì)局和策略價(jià)值網(wǎng)絡(luò)訓(xùn)練兩個(gè)方面來展開介紹一下整個(gè)訓(xùn)練過程,以及自己實(shí)驗(yàn)過程中的一些觀察和體會(huì)。

完全基于 self-play 來學(xué)習(xí)進(jìn)化是 AlphaZero 的最大賣點(diǎn),也是整個(gè)訓(xùn)練過程中最關(guān)鍵也是最耗時(shí)的環(huán)節(jié)。這里有幾個(gè)關(guān)鍵點(diǎn)需要說明:
1. 使用哪個(gè)模型來生成 self-play 數(shù)據(jù)?
在 AlphaGo Zero 版本中,我們需要同時(shí)保存當(dāng)前最新的模型和通過評(píng)估得到的歷史最優(yōu)的模型,self-play 數(shù)據(jù)始終由最優(yōu)模型生成,用于不斷訓(xùn)練更新當(dāng)前最新的模型,然后每隔一段時(shí)間評(píng)估當(dāng)前最新模型和最優(yōu)模型的優(yōu)劣,決定是否更新歷史最優(yōu)模型。
而到了 AlphaZero 版本中,這一過程得到簡化,我們只保存當(dāng)前最新模型,self-play 數(shù)據(jù)直接由當(dāng)前最新模型生成,并用于訓(xùn)練更新自身。直觀上我們可能會(huì)感覺使用當(dāng)前最優(yōu)模型生成的 self-play 數(shù)據(jù)可能質(zhì)量更高,收斂更好,但是在嘗試過兩種方案之后,我們發(fā)現(xiàn),在 6*6 棋盤上下 4 子棋這種情況下,直接使用最新模型生成 self-play 數(shù)據(jù)訓(xùn)練的話大約 500 局之后就能得到比較好的模型了,而不斷維護(hù)最優(yōu)模型并由最優(yōu)模型生成 self-play 數(shù)據(jù)的話大約需要 1500 局之后才能達(dá)到類似的效果,這和 AlphaZero 論文中訓(xùn)練 34 小時(shí)的 AlphaZero 勝過訓(xùn)練 72 小時(shí)的 AlphaGo Zero 的結(jié)果也是吻合的。
個(gè)人猜測,不斷使用最新模型來生成 self-play 數(shù)據(jù)可能也是一個(gè)比較有效的 exploration 手段,首先當(dāng)前最新模型相比于歷史最優(yōu)模型一般不會(huì)差很多,所以對(duì)局?jǐn)?shù)據(jù)的質(zhì)量其實(shí)也是比較有保證的,同時(shí)模型的不斷變化使得我們能覆蓋到更多典型的數(shù)據(jù),從而加快收斂。
2. 如何保證 self-play 生成的數(shù)據(jù)具有多樣性?
一個(gè)有效的策略價(jià)值模型,需要在各種局面下都能比較準(zhǔn)確的評(píng)估當(dāng)前局面的優(yōu)劣以及當(dāng)前局面下各個(gè) action 的相對(duì)優(yōu)劣,要訓(xùn)練出這樣的策略價(jià)值模型,就需要在 self-play 的過程中盡可能的覆蓋到各種各樣的局面。
前面提到,不斷使用最新的模型來生成 self-play 數(shù)據(jù)可能在一定程度上有助于覆蓋到更多的局面,但僅靠這么一點(diǎn)模型的差異是不夠的,所以在強(qiáng)化學(xué)習(xí)算法中,一般都會(huì)有特意設(shè)計(jì)的 exploration 的手段,這是至關(guān)重要的。
在 AlphaGo Zero 論文中,每一個(gè) self-play 對(duì)局的前 30 步,action 是根據(jù)正比于 MCTS 根節(jié)點(diǎn)處每個(gè)分支的訪問次數(shù)的概率采樣得到的(也就是上面 Self-play 示意圖中的 ,有點(diǎn)類似于隨機(jī)策略梯度方法中的探索方式),而之后的 exploration 則是通過直接加上 Dirichlet noise 的方式實(shí)現(xiàn)的(
,有點(diǎn)類似于確定性策略梯度方法中的探索方式)。在我們的實(shí)現(xiàn)中,self-play 的每一步都同時(shí)使用了這兩種 exploration 方式,Dirichlet noise 的參數(shù)取的是 0.3,即
, 同時(shí)
.
3. 始終從當(dāng)前 player 的視角去保存 self-play 數(shù)據(jù)
在 self-play 過程中,我們會(huì)收集一系列的 數(shù)據(jù),
表示局面,
是根據(jù) MCTS 根節(jié)點(diǎn)處每個(gè)分支的訪問次數(shù)計(jì)算的概率,
是 self-play 對(duì)局的結(jié)果,其中
和
需要特別注意從每一步的當(dāng)前 player 的視角去表示。比如
中用兩個(gè)二值矩陣分別表示兩個(gè) player 的棋子的位置,那么可以是第一個(gè)矩陣表示當(dāng)前 player 的棋子位置,第二個(gè)矩陣表示另一個(gè) player 的棋子位置,也就是說第一個(gè)矩陣會(huì)交替表示先手和后手 player 的棋子位置,就看
局面下誰是當(dāng)前 player。
也類似,不過需要在一個(gè)完整的對(duì)局結(jié)束后才能確定這一局中每一個(gè)
中的
,如果最后的勝者是
局面下的當(dāng)前 player,則
,如果最后的敗者是
局面下的當(dāng)前 player,則
,如果最后打平,則
.
4. self-play 數(shù)據(jù)的擴(kuò)充
圍棋具有旋轉(zhuǎn)和鏡像翻轉(zhuǎn)等價(jià)的性質(zhì),其實(shí)五子棋也具有同樣的性質(zhì)。在 AlphaGo Zero 中,這一性質(zhì)被充分的利用來擴(kuò)充 self-play 數(shù)據(jù),以及在 MCTS 評(píng)估葉子節(jié)點(diǎn)的時(shí)候提高局面評(píng)估的可靠性。但是在 AlphaZero 中,因?yàn)橐瑫r(shí)考慮國際象棋和將棋這兩種不滿足旋轉(zhuǎn)等價(jià)性質(zhì)的棋類,所以對(duì)于圍棋也沒有利用這個(gè)性質(zhì)。
而在我們的實(shí)現(xiàn)中,因?yàn)樯?self-play 數(shù)據(jù)本身就是計(jì)算的瓶頸,為了能夠在算力非常弱的情況下盡快的收集數(shù)據(jù)訓(xùn)練模型,每一局 self-play 結(jié)束后,我們會(huì)把這一局的數(shù)據(jù)進(jìn)行旋轉(zhuǎn)和鏡像翻轉(zhuǎn),將 8 種等價(jià)情況的數(shù)據(jù)全部存入 self-play 的 data buffer 中。這種旋轉(zhuǎn)和翻轉(zhuǎn)的數(shù)據(jù)擴(kuò)充在一定程度上也能提高 self-play 數(shù)據(jù)的多樣性和均衡性。

所謂的策略價(jià)值網(wǎng)絡(luò),就是在給定當(dāng)前局面 的情況下,返回當(dāng)前局面下每一個(gè)可行 action 的概率以及當(dāng)前局面評(píng)分的模型。前面 self-play 收集到的數(shù)據(jù)就是用來訓(xùn)練策略價(jià)值網(wǎng)絡(luò)的,而訓(xùn)練更新的策略價(jià)值網(wǎng)絡(luò)也會(huì)馬上被應(yīng)用到 MCTS 中進(jìn)行后面的 self-play,以生成更優(yōu)質(zhì)的 self-play 數(shù)據(jù)。兩者相互嵌套,相互促進(jìn),就構(gòu)成了整個(gè)訓(xùn)練的循環(huán)。下面還是從幾個(gè)點(diǎn)分別進(jìn)行說明:
1. 局面描述方式
在 AlphaGo Zero 中,一共使用了 17 個(gè) 的二值特征平面來描述當(dāng)前局面,其中前 16 個(gè)平面描述了最近 8 步對(duì)應(yīng)的雙方 player 的棋子位置,最后一個(gè)平面描述當(dāng)前 player 對(duì)應(yīng)的棋子顏色,其實(shí)也就是先后手。
在我們的實(shí)現(xiàn)中,對(duì)局面的描述進(jìn)行了極大的簡化,以 的棋盤為例,我們只使用了 4 個(gè)
的二值特征平面,其中前兩個(gè)平面分別表示當(dāng)前 player 的棋子位置和對(duì)手 player 的棋子位置,有棋子的位置是 1,沒棋子的位置是 0。然后第三個(gè)平面表示對(duì)手 player 最近一步的落子位置,也就是整個(gè)平面只有一個(gè)位置是 1,其余全部是 0。 第四個(gè)平面,也就是最后一個(gè)平面表示的是當(dāng)前 player 是不是先手 player,如果是先手 player 則整個(gè)平面全部為 1,否則全部為 0。
其實(shí)在最開始嘗試的時(shí)候,我只用了前兩個(gè)平面,也就是雙方的棋子的位置,因?yàn)橹庇^感覺這兩個(gè)平面已經(jīng)足夠表達(dá)整個(gè)完整的局面了。但是后來在增加了后兩個(gè)特征平面之后,訓(xùn)練的效果有了比較明顯的改善。個(gè)人猜想,因?yàn)樵谖遄悠逯校曳较乱徊降穆渥游恢猛鶗?huì)在對(duì)手前一步落子位置的附近,所以加入的第三個(gè)平面對(duì)于策略網(wǎng)絡(luò)確定哪些位置應(yīng)該具有更高的落子概率具有比較大的指示意義,可能有助有訓(xùn)練。同時(shí),因?yàn)橄仁衷趯?duì)弈中其實(shí)是很占優(yōu)勢的,所以在局面上棋子位置相似的情況下,當(dāng)前局面的優(yōu)劣和當(dāng)前 player 到底是先手還是后手十分相關(guān),所以第四個(gè)指示先后手的平面可能對(duì)于價(jià)值網(wǎng)絡(luò)具有比較大的意義。
2. 網(wǎng)絡(luò)結(jié)構(gòu)
在 AlphaGo Zero 中,輸入局面首先通過了 20 或 40 個(gè)基于卷積的殘差網(wǎng)絡(luò)模塊,然后再分別接上 2 層或 3 層網(wǎng)絡(luò)得到策略和價(jià)值輸出,整個(gè)網(wǎng)絡(luò)的層數(shù)有 40 多或 80 多層,訓(xùn)練和預(yù)測的時(shí)候都十分緩慢。
所以在我們的實(shí)現(xiàn)中,對(duì)這個(gè)網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行了極大的簡化,最開始是公共的 3 層全卷積網(wǎng)絡(luò),分別使用 32、64 和 128 個(gè) 的 filter,使用 ReLu 激活函數(shù)。然后再分成 policy 和 value 兩個(gè)輸出,在 policy 這一端,先使用 4 個(gè)
的 filter 進(jìn)行降維,再接一個(gè)全連接層,使用 softmax 非線性函數(shù)直接輸出棋盤上每個(gè)位置的落子概率;在 value 這一端,先使用 2 個(gè)
的 filter 進(jìn)行降維,再接一個(gè) 64 個(gè)神經(jīng)元的全連接層,最后再接一個(gè)全連接層,使用 tanh 非線性函數(shù)直接輸出
之間的局面評(píng)分。整個(gè)策略價(jià)值網(wǎng)絡(luò)的深度只有 5~6 層,訓(xùn)練和預(yù)測都相對(duì)比較快。
3. 訓(xùn)練目標(biāo)
前面提到,策略價(jià)值網(wǎng)絡(luò)的輸入是當(dāng)前的局面描述 ,輸出是當(dāng)前局面下每一個(gè)可行 action 的概率
以及當(dāng)前局面的評(píng)分
,而用來訓(xùn)練策略價(jià)值網(wǎng)絡(luò)的是我們?cè)?self-play 過程中收集的一系列的
數(shù)據(jù)。
根據(jù)上面的策略價(jià)值網(wǎng)絡(luò)訓(xùn)練示意圖,我們訓(xùn)練的目標(biāo)是讓策略價(jià)值網(wǎng)絡(luò)輸出的 action 概率 更加接近 MCTS 輸出的概率
,讓策略價(jià)值網(wǎng)絡(luò)輸出的局面評(píng)分
能更準(zhǔn)確的預(yù)測真實(shí)的對(duì)局結(jié)果
。
從優(yōu)化的角度來說,我們是在 self-play 數(shù)據(jù)集上不斷的最小化損失函數(shù): ,其中第三項(xiàng)是用于防止過擬合的正則項(xiàng)。既然是在最小化損失函數(shù),那么在訓(xùn)練的過程中,如果正常的話我們就會(huì)觀察到損失函數(shù)在慢慢減小。
下圖展示的是一次在 棋盤上進(jìn)行五子棋訓(xùn)練的過程中損失函數(shù)隨著 self-play 局?jǐn)?shù)變化的情況,這次實(shí)驗(yàn)一共進(jìn)行了 3050 局對(duì)局,損失函數(shù)從最開始的 4 點(diǎn)幾慢慢減小到了 2.2 左右。

在訓(xùn)練過程中,除了觀察到損失函數(shù)在慢慢減小,我們一般還會(huì)關(guān)注策略價(jià)值網(wǎng)絡(luò)輸出的策略(輸出的落子概率分布)的 entropy 的變化情況。
正常來講,最開始的時(shí)候,我們的策略網(wǎng)絡(luò)基本上是均勻的隨機(jī)輸出落子的概率,所以 entropy 會(huì)比較大。隨著訓(xùn)練過程的慢慢推進(jìn),策略網(wǎng)絡(luò)會(huì)慢慢學(xué)會(huì)在不同的局面下哪些位置應(yīng)該有更大的落子概率,也就是說落子概率的分布不再均勻,會(huì)有比較強(qiáng)的偏向,這樣 entropy 就會(huì)變小。
也正是由于策略網(wǎng)絡(luò)輸出概率的偏向,才能幫助 MCTS 在搜索過程中能夠在更有潛力的位置進(jìn)行更多的模擬,從而在比較少的模擬次數(shù)下達(dá)到比較好的性能。
下圖展示的是同一次訓(xùn)練過程中觀察到的策略網(wǎng)絡(luò)輸出策略的 entropy 的變化情況。

另外,在漫長的訓(xùn)練過程中,我們最希望看到的當(dāng)然是我們訓(xùn)練的 AI 正在慢慢變強(qiáng)。所以雖然在 AlphaZero 的算法流程中已經(jīng)不再需要通過定期評(píng)估來更新最優(yōu)策略,在我們的實(shí)現(xiàn)中還是每隔 50 次 self-play 對(duì)局就對(duì)當(dāng)前的 AI 模型進(jìn)行一次評(píng)估,評(píng)估的方式是使用當(dāng)前最新的 AI 模型和純的 MCTS AI(基于隨機(jī) rollout)對(duì)戰(zhàn) 10 局。
pure MCTS AI 最開始每一步使用 1000 次模擬,當(dāng)被我們訓(xùn)練的 AI 模型 10:0 打敗時(shí),pure MCTS AI 就升級(jí)到每一步使用 2000 次模擬,以此類推,不斷增強(qiáng),而我們訓(xùn)練的 AlphaZero AI 模型每一步始終只使用 400 次模擬。在上面那次 3050 局自我對(duì)局的訓(xùn)練實(shí)驗(yàn)中,我們觀察到:
經(jīng)過 550 局,AlphaZero VS pure_MCTS 1000 首次達(dá)到 10:0
經(jīng)過 1300 局,AlphaZero VS pure_MCTS 2000 首次達(dá)到 10:0
經(jīng)過 1750 局,AlphaZero VS pure_MCTS 3000 首次達(dá)到 10:0
經(jīng)過 2450 局,AlphaZero VS pure_MCTS 4000 取得 8 勝 1 平 1 負(fù)
經(jīng)過 2850 局,AlphaZero VS pure_MCTS 4000 取得 9 勝 1 負(fù)。
OK,到這里整個(gè) AlphaZero 實(shí)戰(zhàn)過程就基本介紹完了,感興趣的小伙伴可以下載我 github 上的代碼進(jìn)行嘗試。為了方便大家直接和已經(jīng)訓(xùn)練好的模型進(jìn)行對(duì)戰(zhàn)體驗(yàn),我專門實(shí)現(xiàn)了一個(gè)純 numpy 版本的策略價(jià)值前向網(wǎng)絡(luò),所以只要裝了 python 和 numpy 就可以直接進(jìn)行人機(jī)對(duì)戰(zhàn)啦,祝大家玩的愉快!^_^
參考文獻(xiàn):
AlphaZero: Mastering Chess and Shogi by Self-Play with a General Reinforcement Learning Algorithm
AlphaGo Zero: Mastering the game of Go without human knowledge
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。