教你教電腦下圈叉棋
阿新 • • 發佈:2018-12-15
原理
主要是看了這一篇Get a taste of reinforcement learning — implement a tic tac toe agent,裡面作者提出了大概的訓練思路,我基本沒有參照他的具體實現,但是思路肯定是差不多的。而且訓練結果是我幾乎下不過這個AI,比這篇的結果要好很多(不過這種明顯演算法可以解決的問題用AI也沒什麼意思)。
實現
核心在於訓練一個模型,這個模型用來學習當前的棋局時,我們的當前玩家該怎麼處理。強化學習不需要訓練用例,而是我們自己產生訓練用例。這是一個有點迴圈依賴的問題。因為模型顯然自己不知道該往什麼方向發展,通常的機器學習訓練中,我們的依靠外在的資料讓模型去調整自己的引數。所幸,我們的服從一套遊戲規則,這個遊戲規則可以幫助我們產生(越來越好的)訓練用例。
訓練過程
我們的訓練流程是這樣的。圈圈用符號,叉叉用符號表示。先手圈圈的模型稱為,後手叉叉的模型稱為,他們需要學習一個對映,對映到當前獎勵。代表模型對當前各種走法(圈叉棋中至多9種)的價值的判斷。即
- 初始狀態時我們隨機初始化 和 。
- 然後我們利用當前引數的,在盤面上進行搏鬥,即產生(一個batch的)訓練用例。為了產生更廣泛的訓練樣例,我們採用演算法來產生隨機的訓練用例(之後定義演算法)。
- 利用訓練用例調整和的引數,返回 2。
演算法
- 隨機產生 盤合法棋局,這些棋局滿足遊戲規則,而且當前不存在勝者。
- 對於每個棋局 ,如果是輪到選手 , 則認為,否則 。
- 對於每個棋局 ,按照遊戲規則產生用例。對當前中每個空格,填入當前選手的符號。之後按照當前選手,通過 或 預測獎勵,選擇獎勵最大的位置進行走子(我們會解決當前模型預測獎勵最大的位置不是空格的問題*)。直到當前棋局 分出勝負(或平局)。對每個空格處理完後,我們可以對當前棋局按照如下規則進行估算獎勵,注意這裡的是棋局的當前玩家,可以當作一個9元向量,是上文所說的當前走位置的獎勵,假設我們把棋局編號到的整數。:
- 如果 已經被佔了,那麼 定義為 0。
- 如果 在上述過程第一步"填入當前選手的符號"後,經過 步勝利了,定義 ,這裡的 是我們自己定義的函式,它可以是常函式
lambda V : 1
也可以是某個關於step
的減函式,來促使我們的模型儘早勝利。我們可以定義最優的 。 - 如果 2 中,經過 步後平局或者沒有勝利,定義 。這個 F 也可以自己來定義。根據我的經驗,F是的增函式會促使模型學會堵子。
- 如此一來我們就有了分別面向模型和的訓練集和。
理解
模型訓練的核心顯然在我們為什麼用演算法能產生對和有優化作用的訓練用例集和。
正如訓練過程(1)所示,一開始和的引數是隨機的,所以我們左右互搏產生的測試用例實際是質量很低的,因為雙方並沒有建立起如實反映的對映。但是我們有強制的一步演算法的(3),我們對每個空格都進行了試驗,因此至少獲得了一部分 的真實 值,例如
當前選手是,那麼。之後我們對 (假設位置編號從左到右從上到下,從0開始。)便得到了可靠的目標值。然後我們在訓練過程 3. 中利用優化演算法,便使得我們的模型對 有了更加準確的對映。如此而來,由於 變得更加準確了,下一輪便能得到更加高質量的訓練用例。例如當