五子棋的深度學習模型
五子棋遊戲,是一個15x15大小的棋盤,橫豎斜三個方向連成5個棋子,就勝利。
可以將整個棋盤資料,以及當前下棋的棋手(白方還是黑方),作為神經網路的輸入。
輸出則是,下一步下棋的位置。
這就確定了神經網路的輸入層以及輸出層。
隱藏層怎麼確定呢?
現如今很多神經網路的隱藏層數量以及神經元數量,都是人為憑感覺設定的。極為不科學。
容易出現過擬合或欠擬合現象。
而且,如果直接將輸入層確定為,整個棋盤的資料,以及當前棋手。看起來沒什麼問題,AI(也就是神經網路)已經知道了所有資料。但是AI怎麼能知道下一步該怎麼下呢?就像一個對五子棋一無所知的人,你讓他跟你下棋,他都不知道規則,下一步給出的答案,很可能都不符合遊戲規則。例如他給出一個座標,此座標已經有棋子了,是非法的。
當然,如果一個新手,經過大量的觀察(訓練)之後,可以慢慢理解下棋的規則。
例如AI每次給出一個非法的解,則告訴AI非法,多次訓練之後,AI漸漸能理解遊戲規則,從而減少給出非法解的機會。
但是這樣一來,需要大量的訓練。而規則是死的,這是僅僅需要記住的東西,而不需要訓練。例如人下棋,首先了解規則,則不會出現非法的下棋步驟。
如何告知AI(神經網路)下棋的規則?
在這裡,我們對第一個隱藏層建模,這個隱藏層輸入是第一層的輸出,也就是棋盤資料。這個隱藏層的輸出,是棋盤上的可下的點。
注意,這個隱藏層的輸出,和第一層的輸出,本質上沒有任何區別。只是換了一個表示形式。
因為整個棋盤資料=棋盤上可下的棋子的點
理解這一點非常重要,因為棋盤資料確定的情況下,可下的棋子的點已經確定了。
雖然如此,意義卻非常不一樣。
棋盤上可下棋子的座標點,是在理解遊戲規則的前提下才能得出的。
也就是,在這一步輸出,AI已經理解了遊戲規則。換句話說,我們已經告知AI遊戲規則了。
注意這一步不需要學習。沒有任何學習引數。我們就應程式變成,寫一個函式,直接得出輸出。這個函式我們假設為F(x)。由整個棋盤資料,得出可以下棋的點,這個函式非常好寫。函式是確定的,輸入引數是棋盤資料,輸出則是可以下棋的座標點。
這樣可以極大的簡化AI學習任務。
我們輸出是可以下棋的點,是一個二維向量[ [1,1],[3,6] … ]。由於這個向量是動態長度的,不適合構建神經網路。我們換一種表示方式 [1,0,0,0,1,1,1,0,…]。這個一維向量,長度為15x15,對應棋盤每個格子是否可以下棋,1表示可以下棋,0表示不能下棋。由於棋盤的格子數量是固定的,所以這個向量長度也是固定的.
第一個隱藏層確定了。我們已經知道可以下棋的座標點了。接下來的任務是,得出最優解。
也就是我們要知道,哪個座標點是最優的。
注意的是,要得出棋盤可以下棋的點,五子棋比較特殊,它不需要當前下棋的棋手就可以得出。也就是不論當前是白方下,還是黑方下棋,可以下棋的座標點,都是一樣的。這不像中國象棋,必須要知道當前是哪一方下棋,才能得出可以下棋的點。
但是五子棋根據當前可以下棋的點,要得出最優解,這個棋手資訊就必不可少了。
所以當前的棋手資料,我們當作第三層的輸入。
在第三層這裡,輸入和輸出的關係不太容易確定。所以我們直接取一個函式進行擬合。
最簡單的函式是線性迴歸。但是,輸入和輸出之間,可以確定關係比較複雜,肯定不是線性關係。
要確定這個函式,首先需要了解,怎麼樣訓練這個函式的引數。
假設這個函式已經確定了,神經網路通過輸入,得出了一個輸出。我們根據輸出,與目標輸出的誤差,來重新調整引數,使下一次誤差減少。按照函式梯度下降的方向,逐漸使函式擬合。
關鍵問題是,五子棋遊戲我們沒有樣例(例如棋譜),所以沒有目標輸出。
這種情況下,我們的五子棋屬於無監督學習。
無監督學習有幾種方法:
最簡單的是遺傳演算法:先生成一批隨機引數的AI(神經網路)。然後讓這一批AI對弈,勝者留下,負者淘汰。然後將勝者雜交,生成新的後代,這樣不斷迭代,以讓AI自動進化。
這個方案運算量比較大,而且一旦神經元數量比較多的時候,不容易擬合。
優化方案是,是給每一步下棋打分。綜合分數高的留下,分數低的淘汰。這樣可以大大增加迭代的效率。不必等到每一盤棋下完,才進行迭代。
當然,還可以動用棋譜。棋譜的方案是最優的,我們調整引數,擬合棋譜。但是並不是每一步棋都有對應的棋譜。這個只能當作優化AI的手段。如果這一步有對應的棋譜,用反向傳播演算法調整引數。
最後,我們希望AI在與玩家對弈的時候,自動進化。從失敗中學到教訓。每一次輸棋之後,我們調整引數,使最後一步棋子,更大的概率挑選其他走法。