斗地主的深度學習方案
原論文出處:
https://openreview.net/pdf?id=rJzoujRct7&utm_source=wechat_session&utm_medium=social&utm_oi=40
中文另外一個翻譯版本
https://kknews.cc/zh-sg/news/5z8nj36.html
摘要
最近深度神經(jīng)網(wǎng)絡(luò)已經(jīng)取得了超越人類的成績,例如圍棋,國際象棋,日本象棋。 與圍棋相比,斗地主是一種非完美信息博奕(有不公開的信息,隨機)多輪合作和競爭的游戲。它是當前國內(nèi)廣泛流行的游戲。我介紹一種使用卷積神經(jīng)網(wǎng)絡(luò)的玩斗地主的方法。無需任何搜索,該神經(jīng)網(wǎng)絡(luò)擊敗了最好的AI程序,擊敗了最好的業(yè)余玩家。
介紹
斗地主是一種易學難精的撲克游戲。它在騰訊游戲平臺的日活量達到1.54千萬。與圍棋相比,斗地主屬于非完美信息博奕游戲,初始手牌完全是隨機的。三個人的游戲中,游戲玩家每局都拿到不同的手牌,并且他不知道另外兩名玩家的手牌。三名玩家中,要確定1名地主,2名農(nóng)民。農(nóng)民需要互相配合才能打敗地主。CNN(卷積神經(jīng)網(wǎng)絡(luò))是比較好的一種解決AI游戲的方法,我們選用CNN是基于以下的理由:
- CNN 在完美博奕中已經(jīng)超越人類。
- 斗地主中牌型有大小之分。例如上家出3,4,5,6,7; 玩家可以出4,5,6,7,8; 這是符合出牌規(guī)則的。但是反過來就不行,例如上家出4,5,6,7,8.那么玩家出3,4,5,6,7就不符合規(guī)則了。
目前為止,還沒有斗地主的卷積神經(jīng)網(wǎng)絡(luò)程序。在斗地主這種非完美博奕中,CNN能否可以有比較好的表現(xiàn)仍然有待證明。在做決定時結(jié)局是模糊不清的,這一點上斗地主與圍棋是一樣的。和圍棋一樣,斗地主很難評估在眾多選擇中,哪一個選擇價格最高。由于斗地主是有隊友的,第一個問題是要教會神經(jīng)網(wǎng)絡(luò)如何配合,如何幫助隊友打完手牌。另一個我們感興趣的問題,神經(jīng)網(wǎng)絡(luò)是否能夠以人類專家的邏輯去分析。DeepRocket是我們開發(fā)的取得相當成績的神經(jīng)網(wǎng)絡(luò)。我們證明了這個神經(jīng)網(wǎng)絡(luò)可以配合和推理。在下一節(jié),我們將介紹相關(guān)的神經(jīng)網(wǎng)絡(luò)。在第3節(jié)介紹論文中用到的關(guān)鍵述語。第4節(jié)將介紹具體組件,包括出牌網(wǎng)絡(luò),帶牌網(wǎng)絡(luò)。第5節(jié)展示如何做實現(xiàn)以及它與之前的AI和人類作比較。最后第6節(jié)描術(shù)了它有什么問題需要改善。
2 目前為止,Libratus 和DeepStack是最好的人工智能程序。(其它不重要,省略了)
3 斗地主術(shù)語
當前玩家:是指第一人稱的這位玩家。
下家:是指當前玩家的下一位玩家。
上家:是指當前玩家的上一位玩家,斗地主只有3人玩,也就是下下家了。
地主:是指搶地主時搶分數(shù)最高的那位。
農(nóng)民1:是指地主的下家
農(nóng)民2:是指地主的上家
地主牌:是指最后三張,交給地主的牌
一輪:是指3位玩家各出一次。例如:”3,3;9,9;pass”就是一輪。
分類:是指所有合法的牌型,例如一對,三帶一是合法的,33345是不合法的。
主牌和帶牌:三帶一張,三帶一對,飛機,四帶二,這些牌型才會有帶牌,比如3331,三個3是主牌,1是帶牌。
分組:是指不同分類分隔,例如 334567,分組成3,34567這兩個分類。
主動出牌:是指玩家可以出任意的牌。例如斗地主出的第一手牌。又比如你出了王炸之后所有人都Pass, 這時你可以出手上的任何一手牌,這時稱為主動出牌。
被動出牌:是指你要出什么牌,要取決于上一手的出牌。例如,上家出3,4,5,6,7;你只能出順子或者炸彈。
4 DeepRocket 基礎(chǔ)網(wǎng)絡(luò)
DeepRocket系統(tǒng)包括三部分,搶地主模塊,策略網(wǎng)絡(luò),帶牌網(wǎng)絡(luò)。開始游戲時,先調(diào)用搶地主模塊,它輸出分數(shù)用來決定是否搶地主。在出牌前調(diào)用策略網(wǎng)絡(luò),它將輸出主牌。如果還需要帶牌,那么還需要調(diào)用帶牌網(wǎng)絡(luò)。如下圖所示:

- 游戲開始
- 是否搶地主
- 不搶時進入出牌階段。
- 搶地主時,發(fā)三張地主牌。
- 出牌時調(diào)用策略網(wǎng)絡(luò)。
- 根據(jù)策略網(wǎng)絡(luò)返回值決定打什么牌。
策略網(wǎng)絡(luò)和帶牌網(wǎng)絡(luò)

4.1 搶地主模塊
首先,在開始打牌之前,需要確定誰是地主,我們設(shè)計了這個模塊用于決定是否搶地主。這個模塊是基于代碼邏輯來實現(xiàn)的,像人類的專家一樣,主要考慮手上的控制牌例如大小王,2,A的個數(shù),以及組合牌的情況,例如順子,飛機多不多。
但事實上,也可以使用簡單神經(jīng)網(wǎng)絡(luò)進行訓練,輸入數(shù)據(jù)為起手牌,標簽為是否搶地主,0表示不搶,1表示搶。
從以往的打牌數(shù)據(jù)中,收集搶地主以后,打牌結(jié)果是輸或者是贏。就可以訓練出來。
4.2 策略網(wǎng)絡(luò)
像AlphaGo一樣,我們使用監(jiān)督學習來預(yù)測人類專家的行為。策略網(wǎng)絡(luò)包含了10層CNN和1 個使用Relu激活函數(shù)的全連接層。最后一層使用Softmax激活函數(shù)來指出所有合法的出牌的概率分布。輸入的數(shù)據(jù)中包括了游戲的狀態(tài),用于表示當前狀態(tài)是搶地主狀態(tài)還是策略出牌的狀態(tài)。策略網(wǎng)絡(luò)是基于state-action對 (s,a)樣例來訓練的。我們使用了8百萬條數(shù)據(jù)進行策略網(wǎng)絡(luò)進行訓練。一條數(shù)據(jù)表達了一局完整的游戲,它可以分解成多個state-action對。它可能是幾輪到20多輪,這個輪數(shù)取決于游戲記錄的長度。例如:
撲克牌:
4456777889JKKAA2B;
335567899TTJJKAA2;
4456689TTJQQQK22S
地主牌:33Q
游戲過程:0,33;1,55;2,66,0,77,1,aa;1,6;2,T;0,j;1,k;0,2;2,S;2,44;0,KK;2,22;2,89TJQK;2,QQ;0,AA;0,56789;1,789TJ;1,3;2,5
如果我想訓練地主下家的打牌習慣,打牌過程就需要分解成下表所示的state-action對。
下表顯示用于訓練地主下家角色的state-action對,一局牌的出牌過程:

- 第一輪:地主出一對3,這時玩家需要出一對5
- 第二輪: 地主出一對3,玩家出一對5,地主上家出一對7; 這時玩家出一對A
- 第三輪:所有人Pass之后,玩家出一張6
- 第四輪:地主下家出一張10,地主出一張J, 這時玩家出一張K
0:表示地主,1:表示地主下家,2:表示地主下家
策略網(wǎng)絡(luò)的輸入數(shù)據(jù)是一個15X19X21的三維二進制tensor.(我們使用X ,Y, Z來表示這三維數(shù)據(jù))
X維數(shù)據(jù)表示手牌的點數(shù),從3,4,5,6,7,8,9,T,J,Q,K,A,2,S,B 分別表示3到大王,共15位。
Y維數(shù)據(jù)表示各個牌型的情況:單張,一對,三條,四條, 連對,順子,三帶一單,三帶一對,2飛機帶單,2飛機帶對,飛機不帶牌,炸彈,王炸, 3飛機帶單,3飛機帶對, 4飛機帶單,4飛機帶對, 5飛機帶單 等共19位。
Z維數(shù)據(jù)表示每輪的順序信息,這是用AlphaGo模型中學來的設(shè)計。為了統(tǒng)一長度,統(tǒng)一使用了21位數(shù)組, Z維數(shù)據(jù)用于表示最近的6輪的信息, 如下表所示。

經(jīng)過模型測試,發(fā)現(xiàn)512個濾波器是最為穩(wěn)定的,經(jīng)過重復(fù)測試,使用不同的學習步長,發(fā)現(xiàn)10層CNN性能最好.
策略網(wǎng)絡(luò)輸入309種決策概率,然后我們加上帶牌網(wǎng)絡(luò)到DeepRocket中,請參考table3.

值得注意的是,一手牌出牌的數(shù)量最大為20,這個數(shù)值限制了分類的個數(shù)。
上表中,原作者可能手誤,也可能把2也算進三張中去,導(dǎo)致數(shù)量不準確。事實上1,1,1,2,2,2
是不能構(gòu)成飛機的。
為了易于理解,把上面單張,一對,三張,四張,順子,飛機的所有牌型窮舉出來。








4.3 帶牌網(wǎng)絡(luò)
有了搶地主模塊以及策略網(wǎng)絡(luò)之后,原則上已經(jīng)可以了。但是,怎么帶牌同樣是一個問題。如果主牌有n種選擇,帶牌有m種選擇。那么總共就有m * n 種出牌的可能性。例如三帶一張中,三條共有13種可能,可以帶的牌有14種可能(從3到大小王,減去1), 那么出牌總共有13 * 14種可能性。在某些時候,玩家有飛機(例如333444) 飛機長度為i(例如333444飛機長度為 2), j 為可以帶的牌。那么它總共有i * j 種選擇。例如333444555666789J是合法的牌型,但是在8百萬個游戲記錄中卻很少出現(xiàn)。所以主牌+帶牌的這種牌型需要額外處理,而帶牌又有不同的帶牌規(guī)則,帶一單張,帶一對,帶2單張,帶2對等等;而帶牌規(guī)則將由策略網(wǎng)絡(luò)預(yù)測出來。
為了解決這個問題,我們加了這個額外的帶牌網(wǎng)絡(luò)。帶牌網(wǎng)絡(luò)的輸入包括手牌以及策略網(wǎng)絡(luò)預(yù)測出來的帶牌規(guī)則,它是一個15 * 9 * 3的3維Tensor。X維表示什么牌,這個跟策略網(wǎng)絡(luò)中定義是一樣的。
Y維與Z維如表4所示

Y維與Z維,主要收集了以下信息:
- 帶牌類型(單張/對子)角色(地主,地主下家,地主上家)剩余手牌,合法的單張對子。
- 游戲的記錄信息(還有幾輪打完)主牌長度,帶牌長度
- 剩余的牌,合法的牌以及其它特征。
帶入了帶牌網(wǎng)絡(luò)之后,策略網(wǎng)絡(luò)只需要預(yù)測主牌,以及帶牌類型,以及帶牌長度就可以了。否則策略網(wǎng)絡(luò)的輸出標簽就不止309種了,而是好幾千。但是事實上帶牌的組合對牌型的大小來說并不重要,例如333444555666789J和333444555666789Q大小是一樣的,策略網(wǎng)絡(luò)只需要輸出的信息里包括主牌333444555666,帶牌類型為帶單張,飛機長度為4就可以了。然后在帶牌網(wǎng)絡(luò)中就會預(yù)測出789J或者789Q這樣的組合牌出來。
帶牌網(wǎng)絡(luò)的輸入包括了以下信息,剩余手牌以及從策略網(wǎng)絡(luò)輸出的信息(如主牌,帶牌類型,飛機長度),它是一個15 * 9 * 3的三維 tensor.
帶牌網(wǎng)絡(luò)的輸出是28個可能性,代表15個單張,13個對子。
帶牌網(wǎng)絡(luò)包含了5層的CNN和一個全連接層,每次輸出一種可以帶的牌。例如帶牌網(wǎng)絡(luò)預(yù)測333444帶2單的情況,它會調(diào)用帶牌網(wǎng)絡(luò)2次,每次一張最有可能帶出的牌,然后再調(diào)用一次。
5 實驗
5.1 實驗建立
我們收集了8百萬條游戲數(shù)據(jù),并且把它分出來大概8千萬個state-action對。90%的數(shù)據(jù)為訓練集,10%的數(shù)據(jù)為測試集。然后把數(shù)據(jù)輸入到模型中進行訓練,最后使用TFRecords把模型保存到硬盤上。這并不只是為了方便更改模型參數(shù),它還可以讓訓練更快。大概每次花20個小時就可以訓練好策略網(wǎng)絡(luò)了。策略網(wǎng)絡(luò)的batch size是256. 策略網(wǎng)絡(luò)在測試集中的準確率為88左右。使用i7-7900X CPU, NVIDIA 1080TiGPS Ubuntu 16.04系統(tǒng),策略網(wǎng)絡(luò)每次計算只需要0.02秒左右。
帶牌網(wǎng)絡(luò)同樣也是采用監(jiān)督學習來訓練的,所有樣本同樣來自于8百萬條數(shù)據(jù)。帶牌網(wǎng)絡(luò)達到90%的準確率,它甚至比策略網(wǎng)絡(luò)更好。
我們曾經(jīng)更改過層數(shù),濾波器,以及其他參數(shù)得到很多模型?;潦褂肈uplicate Mode來測試它,比較了10000局游戲中地主的積分之后,我們最終選擇了最優(yōu)的模型。
5.2 與其它 AI模型比較
MicroWe曾經(jīng)在斗地主的人工智能比賽中贏得了多個獎項,在DeepRocket出現(xiàn)之前,它是最優(yōu)秀的斗地主模型。
圖三,圖四顯示了這兩個模型的測試情況。我們總共測試了50000局游戲。需要特別解釋的是,我們發(fā)了20張牌給一個人,然后指定他為地主。因此地主贏的機會比較少。其中 DR VS MW 表示 DeepRocket 為地主,MicroWe為地主上家。


我們可以得出結(jié)論DeepRocket 明顯優(yōu)于MicroWe,它曾經(jīng)是最好的斗地主AI.
5.3 與人類專家比較
舉行了一次測試比賽,我們邀請了4名頂尖的業(yè)余玩家參加。我們復(fù)制了多個模型,讓AI玩家與人類玩家進行比賽。DeepRocket擊敗了人類團隊以30比24勝出。請參閱后面附件。
5.4合作推理
在 DR 的游戲記錄中,我們找到了一個典型的例子能夠展現(xiàn)其良好的合作能力(T:10;B:大王;S:小王。其中冒號之前表示玩家,冒號后表示打出的牌,以分號作為某玩家出牌結(jié)束標志,0 代表地主)
牌面:
4456777889JKKAA2B;
335567899TTJJKAA2;
4456689TTJQQQK22S;
33Q;
游戲進程:
0,33;1,55;2,66;0,77;1,AA;1,6;2,T;0,J;1,K;0,2;2,S;2,44;0,KK;2,22;2,89TJQK;2,QQ;0,AA;0,56789;1,789TJ;1,3;2,5;
以上加粗部分是關(guān)鍵步驟,在游戲的最后 DR 打出一張“3”來幫助隊友取得勝利,由此可見 DR 具有良好合作能力的。
我們也找到了一個能夠展現(xiàn) DR 推理能力的例子:
牌面:
33345578TTJKKA22S;
34566789TQQQKKAA2;
4456678999TJJQA2B;
78J;
游戲進程:
0,345678;1,56789T;0,6789TJ;0,QQQKK;0,AA;2,22;2,55;2,3334;2,TT;2,A;0,2;
以上加粗部分是關(guān)鍵步驟,雖然最后農(nóng)民輸了,但是他選擇打“A”是一個不錯的選擇,因為地主只剩一張牌,而農(nóng)民手里還有 (“7, 8, J, A, S”)五張牌,選擇出“A”也是人類專家的正常邏輯,DR 能夠從人類中學到此行為。
展望
雖然,我們已經(jīng)證明了 CNN 能夠預(yù)測斗地主游戲中玩家的行為,并與隊友進行合作;在沒有任何的 MCTS 之下能達到頂級選手的水平甚至更高。但是,我們也還有許多方面要進行完善。第一個是強化問題,直接將應(yīng)用在 AlphaGo 的方法移植到 CCP 中是行不通的;第二個是關(guān)于 Monte Carlo 搜索或者 MCTS 的問題
在未來,DR 可以在以下方面進行改進:
叫地主的方式可以改進,在搶地主的過程中只有 0、1、2 和 3 是正確操作,0 代表玩家不想當?shù)刂?。我們將嘗試用深度神經(jīng)網(wǎng)絡(luò)去訓練叫地主的方式。
我們將嘗試使用隨機權(quán)重訓練模型。
我們將訓練分別代表三個角色的三個輸出模型。
筆者按:這里原作者在策略網(wǎng)絡(luò)中,輸入數(shù)據(jù)并沒有很好的解釋清楚。
15 * 19 * 21中,
X代表所有的牌,這個很清楚了。
但是Y代表所有的牌型,這個還不是很清楚為什么是19. 并且沒有展示數(shù)據(jù)是怎么子的。
另外,當有癩子的玩法時,模型應(yīng)該怎么改造也沒有提及到。
最后我也預(yù)祝作者的論文被成功接收,今后在這個項目上還可以再有進展!