蒙特卡罗树搜索(MCTS)【转】
簡(jiǎn)介
最近AlphaGo Zero又火了一把,paper和各種分析文章都有了,有人看到了說(shuō)不就是普通的Reinforcement learning嗎,有人還沒(méi)理解估值網(wǎng)絡(luò)、快速下子網(wǎng)絡(luò)的作用就放棄了。
實(shí)際上,圍棋是一種零和、信息對(duì)稱(chēng)的combinatorial game,因此AlphaGo用的是蒙特卡羅樹(shù)搜索算法的一種,在計(jì)算樹(shù)節(jié)點(diǎn)Q值時(shí)使用了ResNet等神經(jīng)網(wǎng)絡(luò)模型,只是在論文中也歸類(lèi)為增強(qiáng)學(xué)習(xí)而已。
如果你想真正了解AlphaGo的原理(或者不被其他AI將統(tǒng)治人類(lèi)的文章所忽悠),理解蒙特卡羅樹(shù)搜索(Monte Carlo Tree Search)、博弈論(Game Theory)、多臂laohu機(jī)(Multi-arm Bandit)、探索與利用(Exploration and Exploitation)等基礎(chǔ)必不可少。
MCTS初探
MCTS也就是蒙特卡羅樹(shù)搜索(Monte Carlo Tree Search),是一類(lèi)樹(shù)搜索算法的統(tǒng)稱(chēng),可以較為有效地解決一些探索空間巨大的問(wèn)題,例如一般的圍棋算法都是基于MCTS實(shí)現(xiàn)的。
這類(lèi)算法要解決的問(wèn)題是這樣的,我們把圍棋的每一步所有可能選擇都作為樹(shù)的節(jié)點(diǎn),第零層只有1個(gè)根節(jié)點(diǎn),第1層就有361種下子可能和節(jié)點(diǎn),第2層有360種下子可能和節(jié)點(diǎn),這是一顆非常大的樹(shù),我們要在每一層樹(shù)節(jié)點(diǎn)中搜索出贏概率最大的節(jié)點(diǎn),也就是下子方法。
那么樹(shù)搜索的算法有很多,如果樹(shù)的層數(shù)比較淺,我們可以窮舉計(jì)算每個(gè)節(jié)點(diǎn)輸贏的概率,那么可以使用一種最簡(jiǎn)單的策略,叫做minmax算法。基本思路是這樣的,從樹(shù)的葉子結(jié)點(diǎn)開(kāi)始看,如果是本方回合就選擇max的,如果是對(duì)方回合就是min的,實(shí)際上這也是假設(shè)對(duì)方是聰明的也會(huì)使用minmax算法,這樣在博弈論里面就達(dá)到一個(gè)納什均衡點(diǎn)。
這是搜索空間比較小的時(shí)候的策略,MCTS要解決的問(wèn)題是搜索空間足夠大,不能計(jì)算得到所有子樹(shù)的價(jià)值,這是需要一種較為高效的搜索策略,同時(shí)也得兼顧探索和利用,避免陷入局部最優(yōu)解。MCTS實(shí)現(xiàn)這些特性的方式有多種,例如經(jīng)典的UCB(Upper Confidence Bounds)算法,就是在選擇子節(jié)點(diǎn)的時(shí)候優(yōu)先考慮沒(méi)有探索過(guò)的,如果都探索過(guò)就根據(jù)得分來(lái)選擇,得分不僅是由這個(gè)子節(jié)點(diǎn)最終贏的概率來(lái),而且與這個(gè)子節(jié)點(diǎn)玩的次數(shù)成負(fù)相關(guān),也就是說(shuō)這個(gè)子節(jié)點(diǎn)如果平均得分高就約有可能選中(因?yàn)檎J(rèn)為它比其他節(jié)點(diǎn)更值得利用),同時(shí)如果子節(jié)點(diǎn)選中次數(shù)較多則下次不太會(huì)選中(因?yàn)槠渌?jié)點(diǎn)選擇次數(shù)少更值得探索),因此MCTS根據(jù)配置探索和利用不同的權(quán)重,可以實(shí)現(xiàn)比隨機(jī)或者其他策略更有啟發(fā)式的方法。
到這里我們需要理解,蒙特卡羅樹(shù)搜索是一種基于樹(shù)數(shù)據(jù)結(jié)構(gòu)、能權(quán)衡探索與利用、在搜索空間巨大仍然比較有效的的搜索算法。至于這個(gè)樹(shù)搜索算法主要包括Selection、Expansion、Simulation和Backpropagation四個(gè)階段,具體原理和實(shí)現(xiàn)會(huì)在后面介紹。
前面提到MCTS的使用場(chǎng)景需要是搜索空間巨大,因?yàn)樗阉骺臻g如果在計(jì)算能力以內(nèi),其實(shí)是沒(méi)必要用MCTS的,而真正要應(yīng)用上還需要有其他的假設(shè)。涉及到博弈論的概念,我們要求的條件是zero-sum、fully information、determinism、sequential、discrete,也就是說(shuō)這個(gè)場(chǎng)景必須是能分出輸贏(不能同時(shí)贏)、游戲的信息是完全公開(kāi)的(不像打牌可以隱藏自己的手牌)、確定性的(每一個(gè)操作結(jié)果沒(méi)有隨機(jī)因素)、順序的(操作都是按順序執(zhí)行的)、離散的(沒(méi)有操作是一種連續(xù)值),除了博弈論我們要求場(chǎng)景是類(lèi)似多臂laohu機(jī)的黑盒環(huán)境,不能通過(guò)求導(dǎo)或者凸優(yōu)化方法找到最優(yōu)解,否則使用MCTS也是沒(méi)有意義。因此在討論蒙特卡羅樹(shù)搜索前,我們需要先有下面的理論基礎(chǔ)。
Game theory基礎(chǔ)
Game theory翻譯過(guò)來(lái)就是博弈論,其實(shí)是研究多個(gè)玩家在互相交互中取勝的方法。例如在耶魯大學(xué)的博弈論公開(kāi)課中,有一個(gè)游戲是讓全班同學(xué)從0到100中選一個(gè)數(shù),其中如果選擇的數(shù)最接近所有數(shù)的平均值的三分之一則這個(gè)玩家獲勝。首先大家應(yīng)該不會(huì)選擇比33大的數(shù),因?yàn)槠渌硕歼x擇100也不能贏不了,那么如果大家都選擇比33小,自己就應(yīng)該選擇比11小的數(shù),考慮到其他人也是這樣想的,那么自己應(yīng)該選擇比11小很多的數(shù),如果我知道別人也知道自己選擇比11小很多的數(shù)的話,那應(yīng)該選擇更小的數(shù)。那么這個(gè)游戲的理想值是0,也就是納什均衡點(diǎn),就是當(dāng)對(duì)方也是深晦游戲規(guī)則并且知道你也很懂游戲規(guī)則時(shí)做出的最優(yōu)決定,當(dāng)然第一次游戲大家都不是完美的決策者(或者不知道對(duì)方是不是完美的決策者),因此不一定會(huì)選擇納什均衡點(diǎn),但多次游戲后結(jié)果就是最終取勝的就是非常接近0的選擇。
那么前面提到的什么是納什均衡點(diǎn)呢?這是Game theory里面很神奇的概念,就是所有人已經(jīng)選擇了對(duì)自己而言的最優(yōu)解并且自己?jiǎn)畏矫孀銎渌x擇也無(wú)法再提高的點(diǎn)。也就是說(shuō),如果玩家都是高手,能達(dá)到或者逼近納什均衡的策略就是最優(yōu)策略,如果對(duì)手不是高手不會(huì)選擇最優(yōu)策略,那么納什均衡點(diǎn)不一定保證每局都贏,但長(zhǎng)遠(yuǎn)來(lái)看極大概率會(huì)贏這樣的新手。
那么前面提到MCTS適用于特定的游戲場(chǎng)景,因此MCTS也是一種找到逼近納什均衡的搜索策略。那么逼近納什均衡點(diǎn)的策略還有很多,例如前面提到的minmax算法,還有適用于非信息對(duì)稱(chēng)游戲的CFR(Counterfactual Regret)算法。像德州撲克我們就會(huì)考慮用CFR而不是MCTS,為什么呢?因?yàn)镸CTS要求是一種Combinatorial Game而不能是信息不對(duì)稱(chēng)的。
在博弈論里,信息對(duì)稱(chēng)(Perfect information / Fully information)是指游戲的所有信息和狀態(tài)都是所有玩家都可以觀察到的,因此雙方的游戲策略只需要關(guān)注共同的狀態(tài)即可,而信息不對(duì)稱(chēng)(Imperfect information / Partial information)就是玩家擁有只有自己可以觀察到的狀態(tài),這樣游戲決策時(shí)也需要考慮更多的因素。
還有一個(gè)概念就是零和(zero-sum),就是所有玩家的收益之和為零,如果我贏就是你輸,沒(méi)有雙贏或者雙輸,因此游戲決策時(shí)不需要考慮合作等因素。
那么博弈論中,我們把zero-sum、perfect
information、deterministic、discrete、sequential的游戲統(tǒng)稱(chēng)為Combinatorial Game,例如圍棋、象棋等,而MCTS只能解決Combinatorial Game的問(wèn)題。
對(duì)博弈論感興趣的,可以在 網(wǎng)易公開(kāi)課 參加耶魯大學(xué)博弈論公開(kāi)課。
Black box optimization基礎(chǔ)
了解完Game theory,第二個(gè)需要了解的是Black box optimization,也就是黑盒優(yōu)化。我們知道優(yōu)化就是根據(jù)給定的數(shù)據(jù)集找到更好的選擇,例如機(jī)器學(xué)習(xí)就是典型的優(yōu)化過(guò)程,但我們用的機(jī)器學(xué)習(xí)算法如LR、SVM、DNN都不是黑盒,而是根據(jù)數(shù)學(xué)公式推導(dǎo)通過(guò)對(duì)函數(shù)求導(dǎo)等方式進(jìn)行的優(yōu)化。如果我們能把問(wèn)題描述成一個(gè)函數(shù)或者凸優(yōu)化問(wèn)題,那么我們通過(guò)數(shù)學(xué)上的求導(dǎo)就可以找到最優(yōu)解,這類(lèi)問(wèn)題并不需要用到MCTS等搜索算法,但實(shí)際上很多問(wèn)題例如圍棋就無(wú)法找到一個(gè)描述輸贏的函數(shù)曲線,這樣就無(wú)法通過(guò)純數(shù)學(xué)的方法解決。
這類(lèi)問(wèn)題統(tǒng)稱(chēng)為黑盒優(yōu)化問(wèn)題,我們不能假設(shè)知道這個(gè)場(chǎng)景內(nèi)部的函數(shù)或者模型結(jié)構(gòu),只能通過(guò)給定模型輸入得到模型輸出結(jié)果來(lái)優(yōu)化。例如多臂laohu機(jī)(Multi-arm Bandit)問(wèn)題,我們有多臺(tái)laohu機(jī)可以投幣,但不知道每一臺(tái)輸贏的概率,只能通過(guò)多次投幣來(lái)測(cè)試,根據(jù)觀察的結(jié)果預(yù)估每臺(tái)機(jī)器的收益分布,最終選擇認(rèn)為收益最大的,這種方法一般會(huì)比隨機(jī)方法效果好。
黑盒優(yōu)化的算法也有很多,例如進(jìn)化算法、貝葉斯優(yōu)化、MCTS也算是,而這些算法都需要解決如何權(quán)衡探索和利用(Exploration and Exploitation)的問(wèn)題。如果我們只有一個(gè)投幣,那么當(dāng)前會(huì)選擇期望收益最高的laohu機(jī)來(lái)投(Exploitation),但如果我們有一萬(wàn)個(gè)投幣,我們不應(yīng)該只投一個(gè)laohu機(jī),而應(yīng)該用少量幣來(lái)探索一下其他laohu機(jī)(Exploration),說(shuō)不定能跳過(guò)局部最優(yōu)解找到更優(yōu)解,當(dāng)然我們也不能全部投幣都用來(lái)探索了。
對(duì)于Exploration和Exploitation,我在 一種更好的超參數(shù)調(diào)優(yōu)方式 有更詳細(xì)的剖析,感興趣可以關(guān)注下 。
UCB算法基礎(chǔ)
前面講了Game theory和Black box optimization,這里再補(bǔ)充一個(gè)UCB算法基礎(chǔ),這是MCTS的經(jīng)典實(shí)現(xiàn)UCT(Upper Confidence bounds for Trees)里面用到的算法。
算法本身很簡(jiǎn)單,公式如下。
其中v'表示當(dāng)前樹(shù)節(jié)點(diǎn),v表示父節(jié)點(diǎn),Q表示這個(gè)樹(shù)節(jié)點(diǎn)的累計(jì)quality值,N表示這個(gè)樹(shù)節(jié)點(diǎn)的visit次數(shù),C是一個(gè)常量參數(shù)(可以控制exploitation和exploration權(quán)重)。
這個(gè)公式的意思時(shí),對(duì)每一個(gè)節(jié)點(diǎn)求一個(gè)值用于后面的選擇,這個(gè)值有兩部分組成,左邊是這個(gè)節(jié)點(diǎn)的平均收益值(越高表示這個(gè)節(jié)點(diǎn)期望收益好,越值得選擇,用于exploitation),右邊的變量是這個(gè)父節(jié)點(diǎn)的總訪問(wèn)次數(shù)除以子節(jié)點(diǎn)的訪問(wèn)次數(shù)(如果子節(jié)點(diǎn)訪問(wèn)次數(shù)越少則值越大,越值得選擇,用戶exploration),因此使用這個(gè)公式是可以兼顧探索和利用的。
用Python也很容易實(shí)現(xiàn)這個(gè)算法,其中C常量我們可以使用 ,這是Kocsis、Szepesvari提出的經(jīng)驗(yàn)值,完整代碼如下。
這樣我們就有了MCTS的最基礎(chǔ)選擇算法實(shí)現(xiàn)了,下面討論完整的MCTS算法實(shí)現(xiàn)。
MCTS算法原理
首先,MCTS的完整實(shí)現(xiàn)代碼在 tobegit3hub/ml_implementation ,想直接看源碼或者測(cè)試的可以去下載運(yùn)行。
然后,我們需要知道MCTS的算法步驟,可以參考論文 A Survey of Monte Carlo Tree Search Methods http://pubs.doc.ic.ac.uk/survey-mcts-methods/survey-mcts-methods.pdf 。
MCTS的算法分為四步,第一步是Selection,就是在樹(shù)中找到一個(gè)最好的值得探索的節(jié)點(diǎn),一般策略是先選擇未被探索的子節(jié)點(diǎn),如果都探索過(guò)就選擇UCB值最大的子節(jié)點(diǎn)。第二步是Expansion,就是在前面選中的子節(jié)點(diǎn)中走一步創(chuàng)建一個(gè)新的子節(jié)點(diǎn),一般策略是隨機(jī)自行一個(gè)操作并且這個(gè)操作不能與前面的子節(jié)點(diǎn)重復(fù)。第三步是Simulation,就是在前面新Expansion出來(lái)的節(jié)點(diǎn)開(kāi)始模擬游戲,直到到達(dá)游戲結(jié)束狀態(tài),這樣可以收到到這個(gè)expansion出來(lái)的節(jié)點(diǎn)的得分是多少。第四步是Backpropagation,就是把前面expansion出來(lái)的節(jié)點(diǎn)得分反饋到前面所有父節(jié)點(diǎn)中,更新這些節(jié)點(diǎn)的quality value和visit times,方便后面計(jì)算UCB值。
基本思路就是這樣的,通過(guò)不斷的模擬得到大部分節(jié)點(diǎn)的UCB值,然后下次模擬的時(shí)候根據(jù)UCB值有策略得選擇值得利用和值得探索的節(jié)點(diǎn)繼續(xù)模擬,在搜索空間巨大并且計(jì)算能力有限的情況下,這種啟發(fā)式搜索能更集中地、更大概率找到一些更好的節(jié)點(diǎn)。下面是論文的偽代碼實(shí)現(xiàn)。
其中TREE_POLICY就是實(shí)現(xiàn)了Selection和和Expansion兩個(gè)階段,DEFAULT_POLICY實(shí)現(xiàn)了Simulation階段,BACKUP實(shí)現(xiàn)了Backpropagation階段,基本思路和前面介紹的一樣。
MCTS算法實(shí)現(xiàn)
最后我們看一下前面基于Python的MCTS代碼實(shí)現(xiàn),源碼在 tobegit3hub/ml_implementation ,這是整理的代碼實(shí)現(xiàn)架構(gòu)圖。
由于這是一棵樹(shù),我們需要定義N叉樹(shù)的Node數(shù)據(jù)結(jié)構(gòu)。
首先Node包含了parent和children屬性,還有就是用于計(jì)算UCB值的visit times和quality value,為了關(guān)聯(lián)游戲狀態(tài),我們還需要為每個(gè)Node綁定一個(gè)State對(duì)象。Node需要實(shí)現(xiàn)增加節(jié)點(diǎn)、刪除節(jié)點(diǎn)等功能,還有需要提供函數(shù)判斷子節(jié)點(diǎn)的個(gè)數(shù)和是否有空閑的子節(jié)點(diǎn)位置。
而State的定義與我們使用MCTS的游戲定義有關(guān),我們定義下面的數(shù)據(jù)結(jié)構(gòu)。
每一個(gè)State都需要包含當(dāng)前的游戲得分,可以繼續(xù)當(dāng)前游戲玩到第幾輪,還有每一輪的選擇是什么。當(dāng)然更重要的,它還需要實(shí)現(xiàn)is_terminal()方法判斷游戲是否結(jié)局,實(shí)現(xiàn)compute_reward()方法告訴用戶當(dāng)前得分是多少,還有提供get_next_state()方法用戶進(jìn)行游戲得到新的狀態(tài),幾個(gè)函數(shù)與游戲場(chǎng)景游戲,這里簡(jiǎn)單實(shí)現(xiàn)了一個(gè)“選擇數(shù)字保證累加和為1”的游戲。
要實(shí)現(xiàn)偽代碼提到的幾個(gè)方法,我們直接定義一個(gè)monte_carlo_tree_search()函數(shù),然后依次調(diào)用tree_policy()、default_policy()、backup()這些方法實(shí)現(xiàn)即可。
為了避免程序無(wú)限搜索下去,我們需要定義一個(gè)computation budget,限制搜索次數(shù)或者搜索時(shí)間,這里限制只能向下搜索1000次,然后通過(guò)下面的方法來(lái)找到expansion node、計(jì)算reward、并且backpropation到所有有關(guān)的節(jié)點(diǎn)中。我們繼續(xù)看一下tree_policy()實(shí)現(xiàn)。
這里代碼很簡(jiǎn)潔,實(shí)現(xiàn)了一個(gè)策略,就是檢查如果一個(gè)節(jié)點(diǎn)下面還有未探索的子節(jié)點(diǎn),那么先expansion下面的子節(jié)點(diǎn)就可以了,如果沒(méi)有子節(jié)點(diǎn),那么就用best_child()函數(shù)(其實(shí)也就是UCB算法)來(lái)得到下一個(gè)子節(jié)點(diǎn),然后便利下直到有未探索的節(jié)點(diǎn)可以探索。
best_child()算法很簡(jiǎn)單,就是根據(jù)Node的State獲取quality value和visit times,然后計(jì)算出UCB值,然后比較返回UCB值最大的子節(jié)點(diǎn)而已。
expand()函數(shù)實(shí)現(xiàn)稍微復(fù)雜些,實(shí)際上就是在當(dāng)前節(jié)點(diǎn)下,選擇一個(gè)未被執(zhí)行的Action來(lái)執(zhí)行即可,策略就是隨機(jī)選,如果有隨機(jī)選中之前已經(jīng)執(zhí)行過(guò)的則重新選。
因此tree_policy()方法就是根據(jù)是否有未探索子節(jié)點(diǎn)和UCB值(也就是權(quán)衡和exploration和exploitation)后選出了expansion節(jié)點(diǎn),然后就是用default_policy()來(lái)模擬剩下的游戲了。
在這個(gè)游戲種模擬也很簡(jiǎn)單,我們直接調(diào)用State類(lèi)中實(shí)現(xiàn)的隨機(jī)玩游戲策略,一直玩到最后得到一個(gè)reward值即可,當(dāng)然對(duì)于AlphaGo等其他游戲可能需要實(shí)現(xiàn)一個(gè)更優(yōu)的快速走子網(wǎng)絡(luò)實(shí)現(xiàn)類(lèi)似的功能,后面會(huì)細(xì)談區(qū)別與AlphaGo的區(qū)別。
那么最后我們就需要把前面計(jì)算的這個(gè)reward反饋到“相關(guān)的”的節(jié)點(diǎn)上了,這個(gè)相關(guān)的意思是從根節(jié)點(diǎn)開(kāi)始一直到這個(gè)expansion節(jié)點(diǎn)經(jīng)過(guò)的所有節(jié)點(diǎn),他們的quality value和visit times都需要更新,backup()函數(shù)實(shí)現(xiàn)如下。
這就是實(shí)現(xiàn)一個(gè)典型MCTS算法的完整實(shí)現(xiàn),大概兩百多行代碼即可,可以通過(guò)它來(lái)玩搜索空間很大的游戲,并且在給定一定計(jì)算能力的基礎(chǔ)上找到較優(yōu)的解。感興趣的還可以關(guān)注下 tobegit3hub/ml_implementation,里面有更多機(jī)器學(xué)習(xí)算法的實(shí)現(xiàn)源碼,也可以提Pull-request貢獻(xiàn)更多的算法代碼。
AlphaGo算法區(qū)別
前面我們實(shí)現(xiàn)的這種基于UCB的MCTS算法,實(shí)際上離訓(xùn)練圍棋機(jī)器人的算法還是比較遠(yuǎn)的,其中AlphaGo也是基于MCTS算法,但做了很多優(yōu)化。
我簡(jiǎn)單看了下 http://www.algorithmdog.com/alphago-zero-notes 的介紹,AlphaGo不僅替換了經(jīng)典實(shí)現(xiàn)的UCB算法,而是使用policy network的輸出替換父節(jié)點(diǎn)訪問(wèn)次數(shù),同樣使用子節(jié)點(diǎn)訪問(wèn)次數(shù)作為分母保證exploration,Q值也改為從快速走子網(wǎng)絡(luò)得到的所有葉子節(jié)點(diǎn)的均值,神經(jīng)網(wǎng)絡(luò)也是從前代的CNN改為最新的ResNet,這樣復(fù)雜的神經(jīng)網(wǎng)絡(luò)模型比一般的UCB算法效果會(huì)好更多。
首先,AlphaGo每個(gè)節(jié)點(diǎn)可選action太多了,selection階段不能像前面先遍歷完所有子節(jié)點(diǎn)再expansion,這里是用改進(jìn)的UCB算法來(lái)找到最優(yōu)的需要expansion子節(jié)點(diǎn),算法基本類(lèi)似也是有控制exploration/exploitation的常量C并且與該子節(jié)點(diǎn)visit times成反比。
其次,進(jìn)行expansion時(shí)不會(huì)像前面這樣直接random選擇任意的action,而是這里也考慮到exploration/exploitation,一般前30步根據(jù)visit times成正比來(lái)選擇,這樣可以盡可能得先探索(根節(jié)點(diǎn)加入了狄利克雷分布保證所有點(diǎn)都經(jīng)過(guò)),后面主要是根據(jù)visit times來(lái)走了。
第三,新版AlphaGo Zero去掉了基于handcraft規(guī)則的rollout policy,也就是快速走子網(wǎng)絡(luò),以前是必須有快速走子直到完成比賽才能得到反饋,現(xiàn)在是直接基于神經(jīng)網(wǎng)絡(luò)計(jì)算預(yù)估的winer value概率值,然后平均得到每個(gè)子節(jié)點(diǎn)的state-action value也就是Q值。
第四,AlphaGo在MCTS基礎(chǔ)上收集最終的比賽結(jié)果作為label,MCTS作為policy evalution和policy iteration來(lái)實(shí)現(xiàn)增強(qiáng)學(xué)習(xí)。
當(dāng)然AlphaGo在MCTS上還可以做更懂優(yōu)化,只是一旦我們理解了MCTS的核心原理,看這些paper和介紹就更加清晰明了。
總結(jié)
最后再次推薦蒙特卡羅樹(shù)搜索的論文 A Survey of Monte Carlo Tree Search Methods http://pubs.doc.ic.ac.uk/survey-mcts-methods/survey-mcts-methods.pdf ,里面提到MCTS適用于各種Combinatorial game的場(chǎng)景,當(dāng)然也提到它的不足,例如在象棋游戲種就不如圍棋效果好。
希望大家看完有所啟發(fā),也能用蒙特卡羅樹(shù)搜索做出更有意思的東西!!!
轉(zhuǎn)自:https://zhuanlan.zhihu.com/p/30458774
知乎對(duì)于人機(jī)大戰(zhàn)的關(guān)注度很高,所以寫(xiě)這個(gè)系列,希望能讓大家對(duì)于人工智能和圍棋有更多的了解。如果有收獲,請(qǐng)記得點(diǎn)一下贊。
本系列已更新多篇,其它幾篇的傳送門(mén):
(1) : 圍棋 AI 基礎(chǔ) 知乎專(zhuān)欄
(2) : 安裝 MXNet 搭建深度學(xué)習(xí)環(huán)境 知乎專(zhuān)欄
(3) : 訓(xùn)練策略網(wǎng)絡(luò),真正與之對(duì)弈 知乎專(zhuān)欄(4) : 對(duì)于策略網(wǎng)絡(luò)的深入分析(以及它的弱點(diǎn)所在) 知乎專(zhuān)欄(4.5):后文預(yù)告(Or 為什么你應(yīng)該試試 Batch Normalization 和 ResNet)知乎專(zhuān)欄(5):結(jié)合強(qiáng)化學(xué)習(xí)與深度學(xué)習(xí)的 Policy Gradient(左右互搏自我進(jìn)化的基礎(chǔ)) 知乎專(zhuān)欄蒙特卡洛樹(shù)搜索(MCTS)是所有現(xiàn)代圍棋程序的核心組件。在此之上可以加入各種小技巧(如 UCT,RAVE/AMAF,Progressive Bias,Virtual win & lose,Progressive Widening,LGR,Criticality 等等)和大改進(jìn)(如 AlphaGo 的策略網(wǎng)絡(luò)和價(jià)值網(wǎng)絡(luò))。
網(wǎng)上很少見(jiàn)到關(guān)于 MCTS 的詳細(xì)介紹,而且許多看似詳細(xì)的介紹實(shí)際有錯(cuò)誤,甚至許多人會(huì)混淆蒙特卡洛樹(shù)搜索和蒙特卡洛方法。這兩者有本質(zhì)區(qū)別。用做過(guò)渲染器的朋友會(huì)理解的話來(lái)說(shuō):蒙特卡洛方法有偏差(Bias),而MCTS沒(méi)有偏差(Bias)。我們?cè)诤笪臅?huì)解釋。
一、極小極大(Minimax)搜索
先看傳統(tǒng)的博弈游戲樹(shù)搜索,著名的極小極大(Minimax)搜索,學(xué)過(guò)算法的朋友會(huì)清楚。看下圖,假設(shè)現(xiàn)在輪到黑棋,黑棋有b1和b2兩手可選,白棋對(duì)于b1有w1和w2兩手可選,白棋對(duì)于b2有w3 w4 w5三手可選:
然后假設(shè)走完w1/w2/w3/w4/w5后,經(jīng)過(guò)局面評(píng)估,黑棋的未來(lái)勝率分別是 50%/48%/62%/45%/58%(等一下,這些勝率是怎么評(píng)估出來(lái)的?我們后文會(huì)說(shuō)這個(gè)問(wèn)題)。
請(qǐng)問(wèn),黑棋此時(shí)最佳的著法是b1還是b2?如果是用蒙特卡洛方法,趨近的會(huì)是其下所有勝率的平均值。例如經(jīng)過(guò)蒙特卡洛模擬,會(huì)發(fā)現(xiàn)b1后續(xù)的勝率是49% = (50+48)/2,而b2后續(xù)的勝率是55% = (62+45+58)/3。
于是蒙特卡洛方法說(shuō)應(yīng)該走b2,因?yàn)?5%比49%的勝率高。但這是錯(cuò)誤的。因?yàn)槿绻灼鍓蚵斆鳎瑫?huì)在黑棋走b1的時(shí)候回應(yīng)以w2(盡量降低黑棋的勝率),在黑棋走b2的時(shí)候回應(yīng)以w4(盡量降低黑棋的勝率)。
所以走b1后黑棋的真實(shí)勝率是48%,走b2后黑棋的真實(shí)勝率是45%。黑棋的正解是b1。這就是 Minimax 搜索的核心思想:在搜索樹(shù)中,每次輪到黑棋走時(shí),走對(duì)黑棋最有利的;輪到白棋走時(shí),走對(duì)黑棋最不利的。由于圍棋是零和游戲,這就可以達(dá)到最優(yōu)解。這是一個(gè)由底往上的過(guò)程:先把搜索樹(shù)畫(huà)到我們可以承受的深度,然后逐層往上取最大值或最小值回溯,就可以看到雙方的正解(如果勝率評(píng)估是準(zhǔn)確的)。而實(shí)際編程的時(shí)候,是往下不斷生長(zhǎng)節(jié)點(diǎn),然后動(dòng)態(tài)更新每個(gè)父節(jié)點(diǎn)的勝率值。
下圖是一個(gè)更多層的例子:
值得注意的是,在實(shí)際對(duì)局中,勝率評(píng)估會(huì)有不準(zhǔn)確的地方,這就會(huì)導(dǎo)致“地平線效應(yīng)”,即由于電腦思考的深度不夠,且勝率評(píng)估不夠準(zhǔn)確,因此沒(méi)有看見(jiàn)正解。
Minimax 搜索還有許多后續(xù)發(fā)展,如課本會(huì)說(shuō)的 Alpha-beta 剪枝,以及更進(jìn)一步的 Null Window / NegaScout / MTD(f) 等等。可惜這些方法更適合象棋等棋類(lèi),對(duì)于圍棋的意義不大(除非已經(jīng)接近終局),請(qǐng)讀者思考原因。
蒙特卡洛樹(shù)搜索和蒙特卡洛方法的區(qū)別在于:
如果用蒙特卡洛方法做上一百萬(wàn)次模擬,b1和b2的勝率仍然會(huì)固定在49%和55%,不會(huì)進(jìn)步,永遠(yuǎn)錯(cuò)誤。所以它的結(jié)果存在偏差(Bias),當(dāng)然,也有方差(Variance)。而蒙特卡洛樹(shù)搜索在一段時(shí)間模擬后,b1和b2的勝率就會(huì)向48%和45%收斂,從而給出正確的答案。所以它的結(jié)果不存在偏差(Bias),只存在方差(Variance)。但是,對(duì)于復(fù)雜的局面,它仍然有可能長(zhǎng)期陷入陷阱,直到很久之后才開(kāi)始收斂到正確答案。
二、蒙特卡洛樹(shù)搜索
如果想把 Minimax 搜索運(yùn)用到圍棋上,立刻會(huì)遇到兩個(gè)大問(wèn)題:
搜索樹(shù)太廣。棋盤(pán)太大了,每一方在每一步都有很多著法可選。
很難評(píng)估勝率。除非把搜索樹(shù)走到終局,這意味著要走夠三百多步(因?yàn)閷?duì)于電腦來(lái)說(shuō),甚至很難判斷何時(shí)才是雙方都同意的終局,所以只能傻傻地填子,一直到雙方都真的沒(méi)地方可以走為止)。簡(jiǎn)單地說(shuō),搜索樹(shù)也需要特別深。
蒙特卡洛樹(shù)搜索的意義在于部分解決了上述兩個(gè)問(wèn)題:
它可以給出一個(gè)局面評(píng)估,雖然不準(zhǔn),但比沒(méi)有強(qiáng)。這就部分解決了第二個(gè)問(wèn)題。根據(jù)它的設(shè)計(jì),搜索樹(shù)會(huì)較好地自動(dòng)集中到“更值得搜索的變化”(注意,也不一定準(zhǔn))。如果發(fā)現(xiàn)一個(gè)不錯(cuò)的著法,蒙特卡洛樹(shù)搜索會(huì)較快地把它看到很深,可以說(shuō)它結(jié)合了廣度優(yōu)先搜索和深度優(yōu)先搜索,類(lèi)似于啟發(fā)式搜索。這就部分解決了第一個(gè)問(wèn)題。最后,隨著搜索樹(shù)的自動(dòng)生長(zhǎng),蒙特卡洛樹(shù)搜索可以保證在足夠長(zhǎng)的時(shí)間后收斂到完美解(但可能需要極長(zhǎng)的時(shí)間)。下面看具體過(guò)程(需要指出,下圖是網(wǎng)絡(luò)上常見(jiàn)的一個(gè)圖,但其實(shí)有錯(cuò)誤):
上圖中每個(gè)節(jié)點(diǎn)代表一個(gè)局面。而 A/B 代表這個(gè)節(jié)點(diǎn)被訪問(wèn) B 次,黑棋勝利了 A 次。例如一開(kāi)始的根節(jié)點(diǎn)是 12/21,代表總共模擬了 21 次,黑棋勝利了 12 次。
我們將不斷重復(fù)一個(gè)過(guò)程(很多萬(wàn)次):
這個(gè)過(guò)程的第一步叫選擇(Selection)。從根節(jié)點(diǎn)往下走,每次都選一個(gè)“最值得看的子節(jié)點(diǎn)”(具體規(guī)則稍后說(shuō)),直到來(lái)到一個(gè)“存在未擴(kuò)展的子節(jié)點(diǎn)”的節(jié)點(diǎn),如圖中的 3/3 節(jié)點(diǎn)。什么叫做“存在未擴(kuò)展的子節(jié)點(diǎn)”,其實(shí)就是指這個(gè)局面存在未走過(guò)的后續(xù)著法。第二步叫擴(kuò)展(Expansion),我們給這個(gè)節(jié)點(diǎn)加上一個(gè) 0/0 子節(jié)點(diǎn),對(duì)應(yīng)之前所說(shuō)的“未擴(kuò)展的子節(jié)點(diǎn)”,就是還沒(méi)有試過(guò)的一個(gè)著法。
第三步是模擬(Simluation)。從上面這個(gè)沒(méi)有試過(guò)的著法開(kāi)始,用快速走子策略(Rollout policy)走到底,得到一個(gè)勝負(fù)結(jié)果。按照普遍的觀點(diǎn),快速走子策略適合選擇一個(gè)棋力很弱但走子很快的策略。因?yàn)槿绻@個(gè)策略走得慢(比如用 AlphaGo 的策略網(wǎng)絡(luò)走棋),雖然棋力會(huì)更強(qiáng),結(jié)果會(huì)更準(zhǔn)確,但由于耗時(shí)多了,在單位時(shí)間內(nèi)的模擬次數(shù)就少了,所以不一定會(huì)棋力更強(qiáng),有可能會(huì)更弱。這也是為什么我們一般只模擬一次,因?yàn)槿绻M多次,雖然更準(zhǔn)確,但更慢。
第四步是回溯(Backpropagation)。把模擬的結(jié)果加到它的所有父節(jié)點(diǎn)上。例如第三步模擬的結(jié)果是 0/1(代表黑棋失敗),那么就把這個(gè)節(jié)點(diǎn)的所有父節(jié)點(diǎn)加上 0/1。
三、重要細(xì)節(jié)
怎么選擇節(jié)點(diǎn)?和從前一樣:如果輪到黑棋走,就選對(duì)于黑棋有利的;如果輪到白棋走,就選對(duì)于黑棋最不利的。但不能太貪心,不能每次都只選擇“最有利的/最不利的”,因?yàn)檫@會(huì)意味著搜索樹(shù)的廣度不夠,容易忽略實(shí)際更好的選擇。
因此,最簡(jiǎn)單有效的選擇公式是這樣的:
其中 x 是節(jié)點(diǎn)的當(dāng)前勝率估計(jì)(注意,如前所述,要考慮當(dāng)前是黑棋走還是白棋走!),N 是節(jié)點(diǎn)的訪問(wèn)次數(shù)。C 是一個(gè)常數(shù)。C 越大就越偏向于廣度搜索,C 越小就越偏向于深度搜索。注意對(duì)于原始的 UCT 有一個(gè)理論最優(yōu)的 C 值,但由于我們的目標(biāo)并不是最小化“遺憾”,因此需要根據(jù)實(shí)際情況調(diào)參。
我們看例子說(shuō)明這是什么意思,就看之前的圖吧。假設(shè)根節(jié)點(diǎn)是輪到黑棋走。那么我們首先需要在 7/10、5/8、0/3 之間選擇:
其中 7/10 對(duì)應(yīng)的分?jǐn)?shù)為 。其中 5/8 對(duì)應(yīng)的分?jǐn)?shù)為 。其中 0/3 對(duì)應(yīng)的分?jǐn)?shù)為 。可以注意到,C越大,就會(huì)越照顧訪問(wèn)次數(shù)相對(duì)較少的子節(jié)點(diǎn)。如果 C 比較小,我們將會(huì)選擇 7/10,接著就要在 2/4 和 5/6 間選擇。注意,由于現(xiàn)在是白棋走,需要把勝率估計(jì)倒過(guò)來(lái):其中 2/4 對(duì)應(yīng)的分?jǐn)?shù)為 。其中 5/6 對(duì)應(yīng)的分?jǐn)?shù)為 。
那么我們下一步肯定應(yīng)該選 2/4。所以說(shuō)之前的圖是錯(cuò)誤的,因?yàn)橹茍D的人并沒(méi)有注意到要把勝率倒過(guò)來(lái)(有朋友會(huì)說(shuō)是不是可以認(rèn)為它的白圈代表白棋的勝率,但這樣它的回溯過(guò)程就是錯(cuò)的)。
最后,AlphaGo 的策略網(wǎng)絡(luò),可以用于改進(jìn)上述的分?jǐn)?shù)公式,讓我們更準(zhǔn)確地選擇需擴(kuò)展的節(jié)點(diǎn)。而 AlphaGo 的價(jià)值網(wǎng)絡(luò),可以與快速走子策略的模擬結(jié)果相結(jié)合,得到更準(zhǔn)確的局面評(píng)估結(jié)果。注意,如果想寫(xiě)出高效的程序,這里還有很多細(xì)節(jié),因?yàn)椴呗跃W(wǎng)絡(luò)和價(jià)值網(wǎng)絡(luò)的運(yùn)行畢竟需要時(shí)間,我們不希望等到網(wǎng)絡(luò)給出結(jié)果再進(jìn)行下一步,在等的時(shí)候可以先做其它事情,例如 AlphaGo 還有一個(gè)所謂 Tree policy,是在策略網(wǎng)絡(luò)給出結(jié)果之前先用著。
相信大家現(xiàn)在就可以寫(xiě)出正確的 MCTS 程序了(注意:最終應(yīng)該選擇訪問(wèn)量最大的節(jié)點(diǎn),而不是勝率最高的節(jié)點(diǎn),簡(jiǎn)單地說(shuō)是因?yàn)樵L問(wèn)量最大的節(jié)點(diǎn)的結(jié)果更可靠)。如果要寫(xiě)一個(gè)高效的程序,你會(huì)發(fā)現(xiàn)必須自己寫(xiě)一個(gè)內(nèi)存池。關(guān)于 MCTS 還有很多話題可以說(shuō),這篇就到這里吧。
本系列已更新多篇,其它幾篇的傳送門(mén):
(1) : 圍棋 AI 基礎(chǔ) 知乎專(zhuān)欄
(2) : 安裝 MXNet 搭建深度學(xué)習(xí)環(huán)境 知乎專(zhuān)欄
(3) : 訓(xùn)練策略網(wǎng)絡(luò),真正與之對(duì)弈 知乎專(zhuān)欄(4) : 對(duì)于策略網(wǎng)絡(luò)的深入分析(以及它的弱點(diǎn)所在) 知乎專(zhuān)欄(4.5):后文預(yù)告(Or 為什么你應(yīng)該試試 Batch Normalization 和 ResNet)知乎專(zhuān)欄(5):結(jié)合強(qiáng)化學(xué)習(xí)與深度學(xué)習(xí)的 Policy Gradient(左右互搏自我進(jìn)化的基礎(chǔ)) 知乎專(zhuān)欄
轉(zhuǎn)自:https://zhuanlan.zhihu.com/p/25345778
總結(jié)
以上是生活随笔為你收集整理的蒙特卡罗树搜索(MCTS)【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 什么胃药好(五类常见胃药)
- 下一篇: 韩国总理办公室疫情-韩国疫情最新消息