1. 程式人生 > >教你教電腦下圈叉棋

教你教電腦下圈叉棋

原理

主要是看了這一篇Get a taste of reinforcement learning — implement a tic tac toe agent,裡面作者提出了大概的訓練思路,我基本沒有參照他的具體實現,但是思路肯定是差不多的。而且訓練結果是我幾乎下不過這個AI,比這篇的結果要好很多(不過這種明顯演算法可以解決的問題用AI也沒什麼意思)。

實現

核心在於訓練一個模型MM,這個模型用來學習當前的棋局GG時,我們的當前玩家pp該怎麼處理。強化學習不需要訓練用例,而是我們自己產生訓練用例。這是一個有點迴圈依賴的問題。因為模型顯然自己不知道該往什麼方向發展,通常的機器學習訓練中,我們的依靠外在的資料讓模型去調整自己的引數。所幸,我們的G

G服從一套遊戲規則,這個遊戲規則可以幫助我們產生(越來越好的)訓練用例。

訓練過程

我們的訓練流程是這樣的。圈圈用符號OO,叉叉用符號XX表示。先手圈圈的模型稱為MOM_O,後手叉叉的模型稱為MXM_X,他們需要學習一個對映,對映到當前獎勵EpE_pEpE_p代表模型對當前各種走法(圈叉棋中至多9種)的價值的判斷。即
MO=GEOM_O = G\mapsto E_O
MX=GEXM_X = G\mapsto E_X

  1. 初始狀態時我們隨機初始化MOM_OMXM_X
  2. 然後我們利用當前引數的MOM_OM
    XM_X
    在盤面上進行搏鬥,即產生(一個batch的)訓練用例。為了產生更廣泛的訓練樣例,我們採用演算法AA來產生隨機的訓練用例(之後定義演算法AA)。
  3. 利用訓練用例調整MOM_OMXM_X的引數,返回 2。

演算法AA

  1. 隨機產生 bb 盤合法棋局SgS_g,這些棋局滿足遊戲規則,而且當前不存在勝者。
  2. 對於每個棋局 sSgs\in S_g ,如果是輪到選手 OO, 則認為sSOs \in S_O,否則 sSXs \in S_X
  3. 對於每個棋局 sSgs\in S_g ,按照遊戲規則產生用例。對當前ss中每個空格,填入當前選手的符號。之後按照當前選手,通過M
    OM_O
    MXM_X預測獎勵,選擇獎勵最大的位置進行走子(我們會解決當前模型預測獎勵最大的位置不是空格的問題*)。直到當前棋局 ss 分出勝負(或平局)。對每個空格處理完後,我們可以對當前棋局ss按照如下規則進行估算獎勵Ep,sE_{p,s},注意這裡的pp是棋局ss的當前玩家,Ep,sE_{p,s}可以當作一個9元向量,Ep,siE_{p,s}^i是上文所說的當前走位置ii的獎勵,假設我們把棋局ss編號到k[0,9)k\in[0,9)的整數。:
    • 如果 sis^i 已經被佔了,那麼 Ep,siE_{p,s}^i 定義為 0。
    • 如果 sis^i 在上述過程第一步"填入當前選手的符號"後,經過 stepstep 步勝利了,定義 Ep,si=V(step)E_{p,s}^i = V(step),這裡的 VV 是我們自己定義的函式,它可以是常函式 lambda V : 1 也可以是某個關於 step 的減函式,來促使我們的模型儘早勝利。我們可以定義最優的 Ep,si=1E_{p,s}^i = 1
    • 如果 2 中,經過 stepstep 步後平局或者沒有勝利,定義 Ep,si=F(step)E_{p,s}^i = F(step)。這個 F 也可以自己來定義。根據我的經驗,F是stepstep的增函式會促使模型學會堵子。
  4. 如此一來我們就有了分別面向模型MOM_OMXM_X的訓練集TOT_OTXT_X
    TO={(s,EO,s)sSO}T_O = \{ (s, E_{O, s})|s\in S_O \}
    TX={(s,EX,s)sSX}T_X = \{ (s, E_{X, s})|s\in S_X \}

理解

模型訓練的核心顯然在我們為什麼用演算法AA能產生對MOM_OMXM_X有優化作用的訓練用例集TOT_OTXT_X
正如訓練過程(1)所示,一開始MOM_OMXM_X的引數是隨機的,所以我們左右互搏產生的測試用例實際是質量很低的,因為雙方並沒有建立起如實反映GEPG\mapsto E_P的對映MPM_P。但是我們有強制的一步演算法AA的(3),我們對每個空格都進行了試驗,因此至少獲得了一部分 SSgS'\subset S_g 的真實 Ep,sE_{p,s} 值,例如
s=OO_XX____S s = \begin{matrix} O & O & \_ \\ X & X & \_ \\ \_ & \_ & \_ \end{matrix} \in S'

當前選手是OO,那麼。之後我們對Eo,s2=V(1)E_{o,s}^2 = V(1) (假設位置編號從左到右從上到下,從0開始。)便得到了可靠的目標值。然後我們在訓練過程 3. 中利用優化演算法,便使得我們的模型對 SS' 有了更加準確的對映。如此而來,由於 MpM_p 變得更加準確了,下一輪便能得到更加高質量的訓練用例。例如當
s=OO_X_____S s' = \begin{matrix} O & O &am