電腦棋手的“思維” (推薦)

來源:互聯網
上載者:User

以下摘自網上的一篇論文:

電腦棋手的“思維”
李聰 licong@hotmail.com

關鍵詞:博弈 搜尋 學習
摘要:本文關注於電腦博弈的原理和現狀,並有選擇性地介紹一些最新的搜尋和學習技術。
1. 博弈與計算科學
    也許讀者從幾年前一些媒體的報道上聽說過IBM的超級電腦深藍與國際象棋最強者卡斯帕羅夫(Kasparov)的大戰;也許讀者在電腦上玩過和電腦下象棋、國際象棋乃至圍棋的遊戲。電腦棋手是如何進行思考的?它們是否具和人一樣具有智能?
    在我看來,很多易於接觸到的相關的論調都帶有極大的誤導性。
    記得小時候曾經聽說這樣的故事,電腦棋手和一個大師進行對弈,在形勢不利、即將落敗之際,電腦棋手放電致大師於死地。當然,現在無從考證真正的事實狀況和資訊來源,但這與其說是資訊傳播中的扭曲,倒不如說是謠言創造者豐富的幻想能力。如果電腦棋手聰明到這種地步,恐怕所有的人都不是電腦的對手。
    還有一個很有趣的說法,那就是和電腦棋手下棋時盡量走不符合常規的棋,那樣電腦就會不知所措。真是這樣的嗎?我想在看完了第3部分之後,這個問題就會迎刃而解。
    至於所謂超級電腦深藍預測足球大賽冠軍的言論,已經到了聳人聽聞的地步。它的國際象棋下得還不錯,但它絕對不可能用它下國際象棋的能力來預測比賽結果。
    類似下棋的問題被稱為博弈問題。狹義地說,博弈中的博是指賭博,而弈就是下棋。賭博並不提倡,在這裡所說的博弈就單指下棋。就一局棋而言,一方獲勝,則另一方失利,在某些棋類中,如果雙方僵持不下,則形成和棋。總之,在一局棋的任何一個時刻,一方獲得的利益就相當與另一方的損失。也就是說,不會出現“雙贏”的局面。這類問題被稱為零和博弈,因為雙方的所得加在一起等於0。
    博弈在電腦上的實現出現在電腦誕生後的十多年間。當人們試圖用電腦來類比人類智能之時,博弈成為了一個典型的問題。當時,人工智慧的創始人之一A. L. Samuel編了一個電腦下西洋跳棋的程式。1959年,該程式戰勝了設計者本人,1962年則擊敗了美國的一個州冠軍。
    現在的世界上有各種各樣電腦棋手。能夠在普通電腦上啟動並執行國際象棋程式已經達到了職業棋手的水平,就黑白棋而言,人類已經不是電腦的對手。但是就圍棋而言,電腦與人進行抗衡的路還很遙遠。
    如果電腦棋手戰勝了人類棋手,那麼是否就可以說它和人一樣具有智能?這個問題,將放到最後進行討論。我首先將向大家展示,電腦棋手是如何下棋的。
2. 擇優而行
    電腦棋手下棋的原理,簡單地說,就是選出它所認為最有利的下法。

A()
/    |    /
B(4) C(3) D(-1)

    我們來看上面這個圖。假設在某一個時刻,擺在電腦棋手面前的是一個局面A。當然,電腦棋手懂下棋的規則,於是它發現一共有三種符合規則的下法(為了畫圖方便,所以少了一些,事實上,在國際象棋和中國象棋中,符合規則的下法一般為數十種,圍棋則多達兩三百種)。這三種下法將分別形成局面B、C、D。現在,我們假設電腦棋手能夠判斷局面的優劣,為每一個局面都計算一個分數,比如局面B的得分為4,局面C的得分為3,局面D的得分為-1。當然,我們可以作一些規定:分數越高局面越好,分數越低局面越差;當分數為0時表示雙方均勢,則正分表示電腦棋手方優勢,負分表示電腦棋手處於劣勢。於是,電腦棋手就選擇對它最有利的下法,即第一種下法,最後形成了局面B。此時,在這種情況下,作為一個副產品,那就是局面A被認為是4分,因為後面兩種下法對電腦而言是沒有意義的,所以B的分數也就是A的分數。
    接下來的問題是電腦如何做到為每一個局面評出一個得分。這在下棋中被稱為形勢判斷。
    現在以中國象棋或國際象棋為例(這個問題對圍棋而言是很複雜的),最簡單的形勢判斷就是評價以下棋局中雙方的子力對比。例如,在中國象棋中,每個車記8分,每個馬或炮記3.5分,每個兵、士、相都記1分,將帥無價,姑且記1000分,那麼很容易就可以計算出雙方的兵力,兩者的差就形成了一種最簡單的形勢判斷。當然,這種形勢判斷是十分粗糙的。
    稍稍複雜一些的形勢判斷,除了考慮子力優勢之外,還要考慮局面優勢。比如一方的馬處於十分積極的盤河位置,而另一方的馬則還留在原位沒有跳出,兩者之間顯然存在著差距。這時,需要將這些差距折算成分數,加到形勢判斷中去。在電腦中,這是最通俗、或者說最常用的形勢判斷方法。
    一般說,對局面的形勢判斷可以用一個數學式子計算得出。舉一個簡單的例子:
    設在形勢中一共考慮n個因素(或特徵)。用xi表示第i個因素是否在當前的局面G中出現,如果出現則取1,沒有出現則取0,比如第6個因素是指一方的第1個車,那麼當這個車還存在時,x6=1,這個車不存在時,x6=0。用wi表示第i個因素在形勢判斷中所計算的分數,這被稱為權重,例如一個車的分數為8,則w6=8。那麼對局面G的形勢判斷為:

f(G)=w1x1+w2x2+…+wnxn=S…

    符號S被稱為累加符,如果讀者以前不知道這個符號,只要看著上面的等式,將它想像為在for迴圈中套了一個加法的命令,就很容易理解了。這是為了書寫方便而引入的符號。
3. 搜尋的魔術
    如果形勢判斷十分準確,故事就簡單地結束了。可惜的是,問題沒有這麼簡單。我們(無論是電腦還是人類)永遠不可能得到一個準確的形勢判斷。這是因為,形勢判斷是靜態,而棋局是動態,要從靜態特徵中擷取動態資訊,這並非易事。當然,如果需要做到萬無一失,那麼在形勢判斷中,必須包括所有可以想到的對局面產生影響的因素,但這時,因素的數量是一個天文數字,我們既不可能對所有的因素都賦一個權重,也不可能在有限的時間內計算出局面的形勢判斷。
    我們回過來看,人在下棋時也不能一眼就對靜態局勢作出準確的判斷,籠統地說,他們往往需要向後面計算幾步,看看在走了幾步棋之後,局面的形勢如何。這被稱為“多算勝”,也就是說,誰看得越深遠,誰就可以獲勝。這個思維方式立刻被用到了電腦上。

3.1 最小最大樹
以第2部分中出現過的圖為例,假設向後再多考慮一步,得到

A()
/   |   /
B() C() D()
/    |    /      /    |     /
E(5) F(3) G(2.5) H(2) I(-2) J(10)

    這是一棵樹。看到,假設在三個局面B、C、D下,都恰好有兩種符合規則的下法,可以形成局面E、F、G、H、I、J,而這些局面的形勢判斷已經得到了。電腦棋手的任務是利用這些已知條件,選擇局面B、C、D的中對它最有利的一個局面。我們可以發現,局面J的得分最大,那麼是不是應該選擇局面D,以便形成對電腦棋手最有利的局面J呢?
    假設電腦棋手的對手(可能是人,也可能是一個電腦程式,現在為了便於說明問題時不產生混淆,假設對手是人)面對的是局面B,那麼他一定會選擇對自己最有利的下法。由於是零和博弈,對人最有利的下法就是電腦最不利的下法,那麼在E和F之中,他會選擇F。這時,如果電腦棋手選擇局面B,那麼對方就會選擇F,最後電腦棋手得到的結果是3,也就是說,B的形勢判斷結果應該為3。同樣道理,如果人處於C中,他會選擇H,於是f(C) = f(H) = 2。同理,f(D) = -2。最後,發現是B的得分最高,因此電腦會選擇B,此時f(A) = f(B) = 3。
    按前面的猜測,如果因為f(J)=10而電腦選擇了局面D,那麼對手就會選擇I,最後電腦得到了最差的結果-2。
    從這裡我們可以看出,在電腦棋手下棋的局面中,它總是選擇下一個層次中由該局面衍生出的局面中得分最高的,而在對手下棋的局面中,它總是選擇下一個層次中由該局面衍生出的局面中得分最低的。用資料結構中的術語,假設對於某一個局面,已經將在幾步棋之後的所有可能形成的局面的得分都計算了出來,那麼從這棵樹的最底層一層層向上推,在對手下棋的層次中,每一個結點取其子結點的最小值,在電腦下棋的層次中,每一個結點取子結點的最大值。這就被稱為最小最大樹。
    最後,問題轉化為對某一局面下衍生出的最小最大樹的遍曆。這種遍曆用一個深度優先搜尋就很可以處理了。在搜尋的過程中,當前路徑上的每一個結點上都儲存著搜尋到目前為止的當前最優值。搜尋用一個遞迴函式實現,該函數的功能是計算某個結點的最優值。每當一個結點得到子結點的傳回值時,就從當前最優值和傳回值中選取一個更優的值作為當前最優值。當一個結點的子結點都搜尋完畢之時,其當前最優值就是該結點的實際最優值,也就是這個結點的得分,這時,將這個值返回其父結點。下面給出最大最小搜尋的偽碼:
  double minimax( int depth, Position p )
  {                        /* 計算局面p的分值 */
      int i;
      double f, t;
      if( depth == 0 )
        return evaluate( p );                      /* 葉結點 */
      找出p的後繼局面p_1, …, p_w;
      if( 電腦下棋 )
        f = -1000;
      else
        f = 1000;      /*初始化當前最優值,假設1000為一個不可能達到的值*/
      for( i = 1; i <= w; i++ )
      {
        t = minimax( depth - 1, p_i );
        if( t > f && 電腦下棋 )
          f = t;
        if( t < f && 對手下棋 )
          f = t;
      }
      return f;
  }
    需要注意的是,在搜尋過程中,我們不僅僅關心每個局面的得分是多少,我們同樣關心是如何得到這個得分的,也就是說,在這個局面下,電腦棋手或是對手應選擇什麼下法,才能得到這個得分。這個功能沒有包括在上面的偽碼中。不過只要讀者理解了上面的偽碼,就一定能夠自己將相應的代碼加進去。
    進一步,由於是零和博弈,假設從對手角度考慮形式判斷函數為g,則有g = -f。這樣,在深度優先搜尋中,電腦下棋的結點時考慮取子結點中f最大的,而對手下棋的結點中取f最小的,也就是g最大的,這樣兩者就完全統一成取最大值。而在傳回值時,只需要把符號改變一下,就可以把f和g值相互轉換了。例如在前面的例子中,當位於對手下棋的局面B時,有g(E)= -f(E)= -5,g(F)= -f(F)= -3,g(B)取最大值,則g(B)= -3,隨後返回到電腦下棋的局面A時,改變符號,使用f(B)= -g(B)= 3,在A點取f的最大值。這被稱為負最大搜尋,它比最小最大搜尋來得簡單。下面給出負最大搜尋的偽碼,相信有一定基礎的讀者看了之後就會明白。
  double negamax( int depth, Position p )
  {                        /* 計算局面p的分值 */
    int i;
    double f, t;
    if( depth == 0 )
      return evaluate( p );                      /* 葉結點 */
    找出p的後繼局面p_1, …, p_w;
    f = -1000;        /*初始化當前最優值,假設1000為一個不可能達到的值*/
    for( i = 1; i <= w; i++ )
    {
      t = -negamax( depth - 1, p_i );
      if( t > f )
        f = t;
    }
    return f;
  }
3.2 α-β裁剪
    新的問題又出現了,假設我們考慮的是中國象棋或國際象棋,現在希望每次都可以搜尋到5個回合之後。5個回合就相當於雙方一共下10步棋,每一次都有幾十種下法可以選擇,姑且算每次有30種選擇,於是最小最大樹的葉結點個數總共多達3010,這是一個非常龐大的數字。搜尋的結點越多就相當於在搜尋中花費的時間更多,我們總不能忍受電腦棋手一年才下一步棋。減少搜尋結點的最簡單的方法是減小搜尋深度,但這大大影響了電腦棋手的棋力。是否有辦法在不減小搜尋深度的前提下將需要搜尋的結點減小一些?

A(3)
|
B(2)
/    |   /
C(4) E() F()

    假設是在深度優先搜尋過程中的一個局部,用fnow表示搜尋到目前狀態結點的當前最優值。B是電腦下棋的結點,A和C則是對手下棋的結點,當前正處於結點C所屬的子樹已經搜尋完畢,從結點C返回至結點B的時刻,方框中的結點表示搜尋到目前為止的當前最優值,即fnow(A)=3,fnow(B)=2,fnow(C)=f(C)=4。我們知道,由於B是電腦下棋的結點,因此當f(C)>fnow(B)時,應當更新結點B的當前最優值,即令fnow (B)=f (C)=4。此時,雖然結點E、F尚未搜尋,但由於結點B處為電腦下棋,應取子結點中最大值,其當前最優值隨著搜尋的進行只會增加而不會減小,因此有f(B)>=fnow(B)=4。而結點A是對手下棋,應取子結點的最小值,而f(B)>=4>=3=fnow(A),其當前值必然小於結點B的實際最優值,因此對手處於結點A時必然不會選擇到結點B的下法,也就是說,結點B不會對結點A的最優值產生影響。因此,不必再進行結點E和結點F的搜尋,結點B就可以直接返回其父結點A。
    在搜尋過程中,電腦下棋結點的當前最優值被稱為α值(即前面的例子中局面B的最大值),對手下棋結點的當前最優值被稱為β值(即例子中A的最小值)。在搜尋過程中,α值遞增,β值遞減,兩者構成了一個區間。這個區間被稱為視窗,而對手下棋的結點最終的最優值將落在這個視窗中。一旦在電腦下棋的結點得到其子結點的傳回值大於β值,則發生剪枝。
    同樣,a-b裁剪也有簡潔的負最大的版本,這時對手的α值即負的電腦的β值,對手的 值即負的電腦的α值。a-b裁剪的偽碼如下:
  double alphabeta( int depth, double alpha, double beta, Position &p );  
  {                        /* 計算局面p的最優值 */
    int i;
    double t;
    if( depth == 0 )
      return evaluate( p );                      /* 葉結點 */
    找出p的後繼局面p_1, …, p_w;
    for( i = 1; i <= w; i++ )
    {
      t = -alphabeta( depth - 1, -beta, -alpha, p_i );
      if( t > alpha )
        if( t > beta )
          return t;
        else
          alpha = t;
    }
    return alpha;
  }
3.3 NegaScout搜尋
    正常情況下,在搜尋樹的根結點,也就是電腦棋手需要決策的局面,我們可以調用3.2中給出的函數alphabeta來得到根結點的分值,同時也可以得到應該走哪一步棋的結論。這時,調用該函數時,我們應使參數alpha=-1000,beta=1000,這裡1000是一個足夠大的數。這是因為在根結點時,我們需要把視窗初始化成最大,在搜尋過程中,隨著資訊的獲得,這個視窗會漸漸地減小,最後收斂到根結點的最優值上。
    現在我們來看一個有趣的現象:如果我們調用alphabeta( d, b – 0.1, b, p )會產生什麼結果?這裡0.1是一個較小的常數,而b是某一個數值。
    直接從程式中分析,現在形式參數beta就等於b。如果函數的傳回值大於b(也就是beta),說明對於局面p,至少有一個子結點的傳回值比b大,所以其最優值必然大於b。這時,我們知道b是局面p最優值的下界。注意,在這種情況下,後面也許還有子結點根本來不及搜尋就被裁剪了,所以這時的傳回值並不代表局面p的實際最優值,可能比實際最優值小。如果函數的傳回值小於b,說明沒有一個子結點的最優值比b大,於是局面p的最優值必然小於b(事實行,由於初始的視窗在函數遞迴過程中被反覆傳遞下去,所有的傳回值都只體現了是否比b大的資訊,所以傳回值不是局面p的實際最優值)。此時,b是局面p最優值的上界。於是,我們得到結論,運用這種類型的alphabeta函數調用,根據傳回值是否比b大,可以得出局面p的最優值是否比b大的結論。
    注意到在函數調用過程中,alpha和beta很接近,因此視窗很小,在視窗很小的情況下,搜尋樹的各個層次中,得到的傳回值比beta大的可能性就大大增加了,這樣剪枝的可能性也變大了。
    這種類型的alphabeta函數調用被稱為零視窗a-b搜尋,由於產生了大量的剪枝,它的時間消耗比正規的a-b裁剪少。但正規的a-b裁剪可以得到一個局面的實際最優值,而零視窗a-b調用只能得到實際最優值和某一個特定值b比大小的結果,也就是說,一個上界或下界的資訊。
    於是,我們可以對a-b裁剪作一個改進:在每次向下搜尋之前,首先先用零視窗a-b調用判斷一下,這個搜尋是否能夠改善當前的最優值,即局面p某一個子結點的實際最優值是否比alpha大。如果比alpha小,則跳過這個子結點。進一步,當該子結點的傳回值大於alpha時,從前面的分析中已經知道,它的實際最優值大於這個值,所以當傳回值大於beta時,其實際最優值也超過了beta,這時就應該進行剪枝。這就是NegaScout搜尋。在這個新演算法中,增加的時間消耗是零視窗a-b調用,而如果零視窗a-b調用的傳回值比alpha小,那麼就可以節約一個較大視窗的a-b調用花費的時間,當零視窗a-b調用的傳回值比beta大時,則直接產生了進一步的剪枝。實踐證明,由於零視窗a-b裁剪中產生了大量的剪枝,所以其實踐消耗相對於大視窗a-b調用而言是很小的。總的說,NegaScout搜尋較a-b裁剪有效。下面依照前述的思想,給出一個不算太規範的NegaScout演算法的偽碼(這裡也使用了負最大搜尋):
  double negascout( int depth, double alpha, double beta, Position &p );  
  {                        /* 計算局面p的最優值 */
    int i;
    double t;
    if( depth == 0 )
      return evaluate( p );                      /* 葉結點 */
    找出p的後繼局面p_1, …, p_w;
    for( i = 1; i <= w; i++ )
    {
      t = -negascout( depth - 1, -alpha – 0.1, -alpha, p_i );
      if( t > alpha )
        if ( t < beta )
        {
          t = -negascout( depth - 1, -beta, -t, p_i );
          if( t > alpha )
            if( t > beta )
              return t;
            else
              alpha = t;
        }
        else
          return t;
    }
    return alpha;
  }
    關於NegaScout的細節及其進一步的最佳化,讀者可以查閱文獻[1]。

3.4 魔術所在
    按理說,搜尋技術發展到這個地步,似乎已經很完善了。而事實上,這隻是一個開始而已。
    首先出現的是一些改進的技術。例如,在前面討論的各種搜尋中,除了儲存當前的搜尋路徑(搜尋樹的一個分支)的堆棧之外,不需要其它的記憶體消耗。這種做法並沒有充分利用資源。在實際的電腦博弈程式中,需要建立散列,用以儲存在以前的搜尋過程中所遇到的局面。這樣,一旦在搜尋過程中再次遇到相同的局面(這很常見,如幾種不同的行棋次序可能導致相同的局面),就可以利用以前計算的結果。關於這方面的細節,有興趣的讀者可以參閱文獻[2]。
    然而,真正的革命在於搜尋演算法全新的變化。
    MTD(f)(全稱是Memory-enhanced Test Driver)就是其中一個相當優秀的新方法。它的思想非常簡單:既然零視窗的a-b調用可以判斷局面的最優值是否大於或小於一個固定的值,那麼就反覆運用這個調用。假設已知局面的最優值f的範圍是min £ f £ max(例如在最初,min=-1000,max=1000),那麼就在這個範圍選一個值g,然後用這個值進行零視窗a-b調用。如果調用結果比g大,那麼說明g是f的下界,就得到min=g,反之max=g,這樣,範圍就縮小了。以上過程反覆進行,直到上下界收斂到相同的一個值為止。
    MTD(f)演算法中,雖然也利用了a-b裁剪,但其僅僅作為一個協助工具輔助出現。其思想卻非常有趣,完全跳出了前面的思維,以全新的方式出現在了我們的面前。
    如果在搜尋過程中能夠使用散列儲存已經搜尋過的局面的特性,那麼這個演算法的效率將優於NegaScout。關於MTD(f)的細節,請有興趣的讀者查閱文獻[3]。在此,我只簡單地給出演算法的偽碼:
  double mtdf( int depth, double f, Position p )
  {
    double g, sup = 1000, inf = -1000, beta;
    g = f;
    while( inf < sup )
    {
      if ( g == inf )
        beta = g + 0.1;
      else
        beta = g;
      g = alphabetawithmemory( depth, beta – 0.1, beta, p );
      if ( g < beta )
        sup = g;
      else
        inf = g;
    }
    return g;
  }
    需要注意的是,既然演算法的名稱中有Memory-enhanced,在這裡使用的a-b裁剪應使用散列儲存以前的搜尋結果(這裡使用了函數alphabetawithmemory,以區分於原先的不使用散列的a-b裁剪)。在MTD(f)中,被重複搜尋的相同局面大大增加,當以前的結果被保留下來時,才可能提高效率。在國際象棋的實驗中,該演算法使效率提高了15%。
    此外,還有其它的一些搜尋演算法,如SSS*[4]、B*[5]、Probcut[6],這些演算法和我們討論的演算法多少有些不同(或在局面的評價上、或在剪枝上、或在搜尋的次序上),在這裡就不再論述,有興趣的讀者可以自行參閱文獻,進行研究。

4. 電腦棋手的學習
    機器學習技術的發展為電腦下棋水平的提高帶來了新的希望。各種各樣的學習技術都被試圖應用於博弈的某一個部分。文獻[7]綜述了機器學習在電腦象棋對弈中的應用。
    在此,我將展示一個典型的方案:對形勢判斷函數進行學習。

4.1 監督學習
    回顧一下第2部分中的內容,一個一般的形勢判斷函數(或稱估價函數)具有如下的形式:

f(G)=w1x1+w2x2+…+wixi+…+wnxn=S…

    其中,xi表示局面的某一個因素(或特徵),而wi是這個特徵在形勢判斷中所起的重要程度(即相應的分值),通常被稱為權重。如果當這個因素是子力時,在中國象棋或國際象棋中,還是比較容易給出一個相對準確的值,而當這個因素是某些局面性的優勢時,如何準確地估價這些優勢,可能令有經驗的大師都會感到煩惱。
    雖然大師們很難對於一個孤立的局面因素給出具有普遍性的估計,例如在中國象棋中,一個處於巡河位置的車具有多大的分值,但對於一些特定的局面,大師們還是可以較為準確地給出綜合評價。這為學習形勢判斷函數提供了可能。
    一個很簡單的方法就是找出許多局面,然後請大師為每一個局面作出自己的形勢判斷。然後把大師們給出的形勢判斷作為標準答案,訓練形勢判斷函數。這種學習方式被稱為監督學習(或稱有師學習),因為這種學習就如在老師的監督指導下進行。
    例如現在有k個局面G1, G2, …, Gk。第j個局面Gj的n個特徵用x1(j),x2(j),…,xn(j)表示。對這k個局面,大師給出的形勢判斷為h1, h2, …, hk。現在的任務是找出合適的權重w1, w2, …, wn,使得以下的方程組儘可能地得到滿足:

| w1x1(1)+w2x2(1)+…+wnxn(1)=h1
| w1x1(2)+w2x2(2)+…+wnxn(2)=h2
<…                           
|                             
| w1x1(k)+w2x2(k)+…+wnxn(k)=hk

    注意,之所以說是儘可能得到滿足,是因為以上關於w1, w2, …, wn的方程組不一定有解,我們所希望的是實際形勢判斷結果f1, f2, …, fk與大師給出的結果h1, h2, …, hk儘可能接近。
    當形勢判斷函數非常複雜時,這個問題實際上是一個最佳化問題。解決這個問題的通用方法是梯度下降法(有興趣的讀者可以參閱有關最佳化的書籍)。由於現在的形勢判斷函數非常簡單,也可以應用許多其它方法(如最小二乘)。下面僅僅給出梯度下降方法在這個簡單的實際問題上的應用。
    首先對所有的權重w1, w2, …, wn賦以隨機的數值。然後反覆進行以下的迭代:在時刻t,對局面G1, G2, …, Gk計算形勢判斷結果f1, f2, …, fk,依照下式得到下一時刻(即t +1時刻)的權重為

wi(t+1)=wi(t)+nn(j=1..k)求和(hj-fj)xi(j)

    以上對權重的更新過程反覆進行,直到形勢判斷的結果不能再改善為止。式子中的h被稱為學習速率,當取值較大時,學習速度較快(即需要迭代的次數變少),但學習的精度較低(準確地說,在最後階段會產生振蕩),當取值較小時精度提高,但學習速度變慢。
    如果哪位讀者對人工神經網路有一定的瞭解,也可以將以上的過程看作是一個連續型感知器的學習過程。
4.2 強化學習
    監督學習並不是一個令人滿意的學習方法(雖然在某些情況下是不可替代的)。畢竟,當這樣的“老師”也是很累的,很難想像去請一個大師對數百個甚至數千個局面給出自己的形勢判斷。
    強化學習是監督學習的一個特例。這時,“老師”不再每次都給出準確的答案,他(她、它)只是對電腦的計算結果給出一個好或不好的評價,或者是告訴電腦究竟好到何種程度,作為一個帶有模糊性的判斷。在下棋中,這種“老師”是隨處可得的。電腦棋手和每一個對手的對局都有可能成為這種“老師”,對局的勝負就可以看作是“老師”對電腦棋手的評價。當然,如何有效地利用這種評價是學習技術的關鍵。
    以中國象棋或國際象棋為例,在一局棋的進行過程中,一個形勢判斷函數的結果往往時好時差。這是因為在形勢判斷函數中的權重w1, w2, …, wn中,有些比較準確(比如子力因素的權重),而其它的一些並不準確(如一些表示局面優勢因素的權重)。在棋局的進行中,經常出現的狀況是一方首先取得了局面優勢,隨後轉化成了子力的優勢,最後取勝,或者更一般地說,一方首先取得了一些潛在的優勢,隨後將這些潛在的優勢轉化為實在的優勢。一般地說,電腦棋手對潛在的優勢往往不能給出準確的判斷,而對較為實在的優勢(例如子力優勢或者直接構成的殺局)則判斷正確。於是我們可以得到一個基本準確的結論,電腦棋手在其對局的後期(更特殊的狀況是對局結束的時刻),得到的形勢判斷往往是比較正確的。同時,我們可以設想,在對局的前面的一些時刻,正確的形勢判斷應該和對局後期的形勢判斷較為接近。如果電腦能夠有效地參考對局後期正確的形勢判斷,就有可能自行給出對局前期的一些局面的相對準確的形勢判斷,作為在前一節所提到的監督訓練中的標準答案h1, h2, …, hk。
    TD(λ)就是一個實用的強化學習技術。TD(Temporal Difference)即瞬時差異,就是指在一個對局中相鄰兩個時刻的局面的形勢判斷之差。如果這個形勢判斷函數比較準確,則這個差(即瞬時差異)應該接近於0。假設G1, G2, …, Gk, Gk+1是在一個對局中,從某一時刻到對局結束的連續的k+1個局面。這時根據前面的假設,在對局結束時的形勢判斷是準確的,即對於第k+1個局面,形勢判斷的標準答案hk+1=f(Gk+1)。現在我們利用這個值來形成前k個局面的形勢判斷標準答案:從對局結束開始,向前一步步倒退,在每一個時刻,其形勢判斷標準答案為

hi=(1-λ)f(G(i+1))+λh(i+1)

    從這個式子中可以看到,當λ=0時,第i個局面的形勢判斷標準答案應該接近於在此之後的局面的形勢判斷;當λ=1時,所有局面的形勢判斷標準答案都接近於hk+1,即對局結束時刻的形勢判斷。於是,當λ取介於0和1之間的某一個數值時,形勢判斷的標準答案將成為以上兩者的折中。經過了學習之後的形勢判斷函數將在對局中的一系列連續的局面中,相鄰局面的判斷結果相似,並逐漸逼近終局時的結果。
    TD(λ)被應用於多個電腦博弈程式之中。在文獻[8]中,一個應用了該技術(稍作了一些改變,有興趣的讀者請自行查閱文獻)的國際象棋程式在國際互連網上進行了300多局對局後,其等級分從1650分(一般水平)上漲到了2110分(美國大師水平)。
5. 智能與否
    當深藍首次在對局中戰勝卡斯帕羅夫的時候(1996年的對抗賽中),當時的國際象棋世界冠軍(我姑且這麼稱呼他,雖然這個稱呼的合法性早在卡斯帕羅夫和國際棋聯決裂時就遭到了懷疑)曾經在《時代》雜誌上說:“我可以感受、可以嗅察到來自棋盤對面的一種新的智能。”
    他的話中闡述了兩個觀點。首先,不論哲學家們如何看待這個問題,至少在卡斯帕羅夫看來,深藍具有智能。在此,我將一如既往地迴避這個哲學性質的討論,而將精力集中到他的第二個觀點——這是一種新的智能,即不同於人的智能。
    卡斯帕羅夫也許並不瞭解電腦棋手的“思維”方式,但他還是可以從對局中感受到電腦棋手和人類的差別所在。回顧第1部分中所提及的“電腦棋手遇到不符合常規的棋就會不知所措”的論調。在第3部分中,我們已經完全瞭解了電腦下棋的原理,事實上,開局階段電腦的確照著開局書背譜,一旦遇到不常規的著法,或是譜已經背到了盡頭之後,電腦棋手就進入了搜尋過程。此刻,任何不符合棋理的走法毋庸置疑地將遭到最嚴厲打擊。因為電腦棋手並不懂得多少棋理,它所知道的僅僅在於哪些是對它有利的,哪些是對它不利的。現在看來,這種論調不屬於電腦棋手,倒好像是在描述一個理論水平頗高、但實戰經驗不足的棋手。當一個熟讀棋書的人在面對來自對手的明顯不如理論上推薦的走法高明的棋步時,缺乏取得優勢的足夠的功力的他完全可能在諸多複雜的變化之中茫然不知所措,而最終敗下陣來。
    事實上,潛在的模式、規律或是理念完全屬於人類智能(當然,這並不等於人類智能),而這種東西正是當前的電腦棋手所不完備的。雖然深藍可能比大多數的人類都厲害,但它只是在依靠它那強大的計算能力。人類在下棋時也的確會向後多算幾個回合,但人類更懂得選擇,而不是一個簡單的對變化的窮盡。在每一個回合的搜尋中,人類不會顧及所有符合規則的下法,而是從中挑選出最可能的幾種進行考慮(這種選擇並不總是正確的,完全有可能忽略了最佳的著法)。水平較高的人都懂得在對局的過程中要有一個計劃,這個計劃貫串於對局的始終,而深藍只是依靠搜尋的深度來代替這個計劃而已。

6. 新的挑戰
    深藍同卡斯帕羅夫的對抗並非完全公平。原因是深藍的設計者可以獲得卡斯帕羅夫的大量實戰棋局,而卡斯帕羅夫對深藍的對局卻幾乎無所知曉。如果卡斯帕羅夫同樣能得到深藍的實戰對局,以他的敏銳,是否能從中找到深藍的形勢判斷函數中固有的弱點呢?
    如果說電腦在國際象棋競技中的出色戰績掩蓋了它的不足,那麼圍棋就成為了全新的挑戰。
    對於圍棋,至少在目前的研究狀況下不太適合用全域的深度搜尋來補償形勢判斷函數的不準確。原因在於圍棋每一步棋有兩三百種選擇,而在很多狀況下(如涉及到死活),數十著棋的搜尋完全必要。這個運算量大得驚人。
    而形勢判斷同樣存在著困難。在國際象棋的形勢判斷函數中,較為準確的子力優勢估價相對於可能不太精確的局面優勢估價幾乎是壓倒性的,即真正的誤差不會太大,哪怕是一個僅僅計運算元力優勢而忽略局面優勢的形勢判斷函數依靠深度的搜尋也可以獲得馬馬虎虎的結果。那麼在圍棋之中,幾乎無法找到一個簡明的形勢判斷函數。通常的形勢判斷函數首先要找出局面中相連的串,然後用一個局部搜尋計算出每一個串的死活(此時的估價不再是一個分值,而是三個結果死、活、死活不明之一,同時搜尋的範圍也縮小了),在此基礎上,再使用一些如同數學公式般的手段判斷棋局上每一個點的歸屬。
    即使不置疑那種數學公式般的手段的正確性,我們也可以找到 一個簡單的問題。下面兩個圖中的白棋顯然都不是淨死的棋。左圖白1補一手即可活棋,所以是白先活,而右圖中黑1是先手,白已經是活棋。相信現在的電腦圍棋對弈程式都能夠輕鬆地判斷出

    當上面兩塊棋出現在同一個局面中,白方無論如何下棋,左右都必死一塊。也就是說,局部不是死棋,但一旦作全域性的考慮,問題就完全不同了。但是在電腦程式的形勢判斷中,左邊的棋被當成了白先活,而右邊被當成了活棋,這就產生了謬誤。上面只是一個典型的特例而已,在實戰中可以找到很多類似的問題。這能不能使用一些綜合的技術來解決呢?至少到目前為止,我沒有看到這個可能。
    幾乎可以肯定的是,目前所有的電腦圍棋對弈程式都存在著一些致命的弱點。清楚了這個弱點之後,即便是業餘高手也足以讓電腦十來個子。
    一旦依靠搜尋佔主導地位的形態被動搖,電腦棋手的表現就不再令人滿意。這不僅僅是提高電腦的運算速度就可以解決的。這個格局何時才能改變?電腦棋手的未來之路何在?一切都等待著實踐去證明。

參考文獻
    [1] A.Reinefeld, An Improvement of the Scout Tree Search Algorithm, ICCA Journal, Vol. 6, No. 4, 1983
    [2] J. Schaeffer, Distributed Game-tree Searching, Journal of Parallel and Distributed Computing, Vol. 6, 1989
    [3] A. Plaat, J. Schaeffer, W. Pijls, A. de Bruin, Best-first Fixed-depth Minimax Algorithms, Aritificial Intelligence, 1996
    [4] G. C. Stockman, A Minimax Algorithm Better than Alphabeta? Aritificial Intelligence, Vol. 12, No. 2, 1979
    [5] H. J. Berliner, C. McConnell, B* Probability Based Search, Artificial Intelligence, Vol. 86, No. 1, 1996
    [6] M. Buro, ProbCut: An Efficient Selective Extension of the Alpha-beta Algorithm, ICCA Journal, Vol. 18, No. 2, 1995
    [7] J. Furnkranz, Machine Learning in Computer Chess: The Next Generation, ICCA Journal, Vol 19, No.3, 1996
    [8] J. Baxter, A. Tridgell, L. Weaver, TDLeaf(λ): Combining Temporal Difference Learning with Game-tree Search, Australian Journal of Intelligent Information Processing, 1998
 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.