天天看點

星際争霸2 AI 開發探索與展望

星際争霸2 AI 開發探索與展望

     《星際争霸》的國服重置版正在預售中,将在暑假期間登陸戰網。今年是星際争霸發行20周年,這20年間RTS即時戰略遊戲從興起到沒落,在遊戲屆的地位已經大不如前。這其中的一個原因是它的高度複雜性,從宏觀的戰略,到微觀的操作,需要考慮并迅速做出反應的點太多太多。這樣的特點使得星際看的人多玩的人少,但卻恰恰适合征服圍棋後的AI來一展身手。當2016年AlphaGo擊敗李世石後DeepMind宣布進軍星際2,衆多媒體紛紛發文:既圍棋之後,電子競技也要被AI征服了。而到了2017年,DeepMind聯合暴雪釋出了星際2的機器學習環境SC2LE和PySC2,使得廣大研究者都可以參與到這項挑戰中來,但另一方面也說明了AI征服星際絕非易事。

      SC2LE,即StarCraft II Learning Environment(位址附于文末),星際争霸2學習環境,它提供了完整的API接口來從外部對一局星際2遊戲進行控制。并且還包含錄像分析工具,可以把一局比賽中玩家的指令集依次提取出來。在windows、mac、linux上,SC2LE都有相應用戶端。而PySC2,則是DeepMind基于SC2LE開發出的python元件,使得研究者可以更友善的使用python編寫星際2的強化學習程式。并且PySC2中還額外包含7個小遊戲(地圖),分别是坐标尋路、尋找收集礦物、尋找消滅跳蟲、槍兵vs蟑螂、槍兵vs毒爆跳蟲、采集礦物和瓦斯、建造槍兵,以降低學習的難度。PySC2的安裝很簡單,安好星際2遊戲後使用pip工具運作pip install pysc2就行了,詳見文末連結。

星際争霸2 AI 開發探索與展望

      AlphaGo在圍棋上之是以能表現的如此完美,根本原因自然是近年來卷積神經網絡的進步和計算機性能的不斷提升。但另一方面,圍棋本身的簡潔也很重要。雖然所需計算量很大,可圍棋的規則和輸入輸出卻非常簡單。而星際2的輸入輸出呢?讓我們來看看PySC2中是怎麼定義的。輸入共12種,可分為4類:

1. 遊戲資訊。

      遊戲畫面資訊。這類似圍棋的棋盤輸入,是最主要的輸入資訊。畫面大小預設為84*84,分為13個子項。分别為:地形高度,地圖可見性,是否有蟲族菌毯,是否在己方神族水晶塔範圍内,機關所屬玩家ID,機關所屬玩家與己方關系,機關類型,機關是否被選中,機關剩餘生命值,機關剩餘護盾值,機關剩餘能量值,機關密度(部隊有可能堆疊在一起),機關密度精細值。

      小地圖資訊。與遊戲畫面資訊類似,大小預設為64*64,隻有7個子項:地形高度,地圖可見性,是否有蟲族菌毯,目前小地圖位置,機關所屬玩家ID,機關所屬玩家與己方關系,機關是否被選中。

      己方玩家資訊。分為11個子項,包括:玩家ID,礦物數,瓦斯數,目前人口,目前人口上限,部隊所占人口,農民所占人口,閑置農民數,部隊數量,傳送門數量(神族),幼蟲數量(蟲族)。

2. 機關資訊。

      單個機關資訊。選擇單個機關時提供,包括:機關類型,機關所屬玩家與己方關系,機關剩餘生命值,機關剩餘護盾值,機關剩餘能量值,運輸機關(所選機關為運輸機時),傳送百分比(所選機關為正在傳送的神族部隊時)。

      多個機關資訊。選擇多個機關時提供,每個機關的具體資訊與上面一緻。

      運輸機中所有機關資訊。選擇運輸機時提供,每個機關的具體資訊與上面一緻。

      建築中所生産機關資訊。選擇産兵建築時提供,每個機關的具體資訊與上面一緻。

      運輸機中可用空位。選擇運輸機時提供,代表運輸機中還剩下多少位置。

      編組資訊。提供玩家各個編組的機關資訊,最多10組,每組提供本組的機關數量和第一個機關的類型。

3. 環境資訊。

      遊戲循環。代表目前遊戲是第幾局。

      累計得分。提供目前遊戲己方玩家的多項得分,以作為獎勵進行強化學習。

4. 可用指令集資訊。給出目前所有的可用指令,也就是對輸出範圍進行了指定。

星際争霸2 AI 開發探索與展望

      可以看到,PySC2的輸入擁有衆多類别,複雜性遠遠超過圍棋,當然玩過即時戰略遊戲的玩家對這些應該還是比較熟悉的哈哈。另一方面,以這樣的形式給出輸入,使得AI和人類玩家所獲得的資訊是一模一樣的,嚴格保證了遊戲公平性。而在輸出時,PySC2還可以對AI的APM進行限制,預設為180,和中等水準人類玩家相當。所有的輸出指令共計524個,每個指令又有各自的參數,所有的參數類型共13種。常用的指令比如:

      ·移動小地圖位置。參數類型為小地圖的坐标,顯示這個坐标的畫面。

      ·框選機關。參數類型為兩個遊戲畫面的坐标,代表遊戲畫面中一個矩形的左上角和右下角,對這個矩形中的已方機關進行框選。

      ·基于遊戲畫面的移動攻擊。參數類型為遊戲畫面的坐标,控制所選機關平A到遊戲畫面中的指定位置。

      ·建造建築。參數類型為建築類型,控制所選農民建造指定建築物。

      了解了輸入輸出,接下來我們就可以編寫AI了。PySC2提供了一個在MoveToBeacon小遊戲中的簡單訓練腳本AI。MoveToBeacon小遊戲,類似各種即時戰略遊戲新手教程的第一關,就是控制一個機槍兵不停的移動到指定位置。

class MoveToBeacon(base_agent.BaseAgent):
    """An agent specifically for solving the MoveToBeacon map."""

    def step(self, obs):
      super(MoveToBeacon, self).step(obs)
      if _MOVE_SCREEN in obs.observation["available_actions"]:
         player_relative = obs.observation["screen"][_PLAYER_RELATIVE]
         neutral_y, neutral_x = (player_relative == _PLAYER_NEUTRAL).nonzero()
         if not neutral_y.any():
            return actions.FunctionCall(_NO_OP, [])
         target = [int(neutral_x.mean()), int(neutral_y.mean())]
         return actions.FunctionCall(_MOVE_SCREEN, [_NOT_QUEUED, target])
      else:
         return actions.FunctionCall(_SELECT_ARMY, [_SELECT_ALL])
           

      代碼結構為:繼承BaseAgent定義一個類,實作step函數,參數obs包含了所有的輸入資訊。首先判斷_MOVE_SCREEN控制機關移動指定是否可用,如果不可用則說明還沒有選中機槍兵,那麼就傳回帶_SELECT_ALL的_SELECT_ARMY指令(F2)選中所有部隊。在可以調用_MOVE_SCREEN時,則檢視輸入中screen遊戲畫面中的_PLAYER_RELATIVE部隊歸屬子項,統計出所有部隊歸屬為_PLAYER_NEUTRAL中立機關的位置。再計算這些位置的平均值,得到需要移動到的Beacon的中心點target。最後調用帶[_NOT_QUEUED, target]的_MOVE_SCREEN指令,讓所選機槍兵立即移動到target位置。

      我也編寫了一個不帶學習能力的腳本AI,在Simple64地圖上用人族擊敗了各族的瘋狂電腦。Simple64地圖是一個比較小的雙人對戰地圖,為正常的采礦造兵模式。這個腳本選的戰術和當初我剛打星際2時所選的一樣,6BB(表鄙視我- -)...流程相當簡潔粗暴,就是不停造農民造滿16個,要卡人口了就造房子,有錢了就造兵營直到6個,兵營不停出機槍兵,機槍兵夠24個了就神聖的F2A(全部選中進攻敵人基地)。具體效果怎麼樣,相信用過的人都知道哈哈。而用腳本來實作的話,除了編寫上述流程外,還有一些細節需要注意:基地與兵營集結點的設定,建築位置的選擇,讓造完建築的農民回來采礦,對人口增長速度的預判。通過這個腳本,我充分熟悉了PySC2環境,也清楚了強化學習AI在正常對戰中的具體訓練目标(代碼位址見文末)。

星際争霸2 AI 開發探索與展望

      那麼對于一個強化學習的AI,每回合需要進行的操作流程是哪些呢:

      ·對輸入的遊戲資訊進行資料處理,轉換成自己模型所需的形式。

      ·搜尋模型對于本輪輸入,權值最大的輸出。

      ·根據本輪的得分變化和最大權值,對模型的參數進行更新。

      我用深度強化學習先後訓練了MoveToBeacon移動到指定位置、CollectMineralShards收集礦物、DefeatRoaches機槍兵vs蟑螂、DefeatZerglingsAndBanelings機槍兵vs跳蟲毒爆這四個小遊戲。為了降低訓練難度,每次都先選中所有部隊,之後進行的指令限定為移動或移動攻擊,通過卷積神經網絡來學習指令參數中的坐标。那麼在MoveToBeacon中,需求其實就是在screen中選出相應的_PLAYER_RELATIVE;在CollectMineralShards中,需求是選出距離槍兵最近的礦物;在DefeatRoaches中,則是選出血量最少的蟑螂進行攻擊;在DefeatZerglingsAndBanelings中,需求是識别出最近的毒爆進行優先攻擊。在這四個任務中,所需的輸入資訊其實有限,我也就隻從screen遊戲畫面資訊中選取了一部分,包括:unit_type機關類型、player_relative機關歸屬、unit_hit_points機關剩餘生命值、selected選中機關。為了加速訓練速度提升訓練效果,我對這幾個輸入進行了進一步增強,把unit_type、player_relative、unit_hit_points按是否被選中又各分為了selected和unselected兩部分。并且統計出了所有選中機關的平均坐标,計算了地圖上各個點到這個坐标的距離作為又一個輸入,進而讓網絡更容易學習到離機槍兵最近的礦物或者毒爆。最後,我為了程式又添加了基于錄像的學習方式。相比于自主強化學習,從錄像中學習的step函數中多了一個action參數,進而告訴程式在本輪中錄像裡玩家如何選擇。使用從錄像中學習時,AI可以通過一個幾十秒的replay訓練一遍就可以對MoveToBeacon、CollectMineralShards和DefeatRoaches學習完畢(github位址見文末)。

星際争霸2 AI 開發探索與展望

      雖然這樣的訓練速度堪稱光速,但畢竟不夠通用,而且效果也隻能算一般。最近DeepMind倒是又發了一篇PySC2的論文,提出了用Relational Deep Reinforcement Learning關系性深度強化學習來訓練這7個小遊戲,進而提升模型的泛化能力并更容易使用背景知識。通過RDRL,DeepMind在6個小遊戲上達到了目前的最高水準,訓練效果的視訊位址見:http://bit.ly/2kQWMzE(需翻牆)。可以看到,在機槍兵vs跳蟲毒爆的小遊戲中,AI學會了用一兩個機槍兵頂在前面吸引毒爆,用大部隊在後面點毒爆瘋狂輸出,取到了很好的效果。當然,在這背後也仍然需要海量的模型疊代計算量,我們一般還是很難玩得起的。

      PySC2已釋出近一年之久,對于其中的7個小遊戲,可以通過錄像來迅速訓練好模型,可以通過更先進的模型來取得超越人類的效果。這能讓我們感到一些慰藉,看到一絲光亮,但真正能與人類玩家對戰的星際2 AI仍舊遙遠。相信在之後的研究中,從錄像中學習、對輸入的人為增強處理以及背景知識的錄入在很長一段時間内仍然是必要的。另一方面,AlphaGo可以通過蒙特卡洛樹、價值網絡和快速走子來對棋局的發展做出預測,可星際2的AI呢?是通過暴雪的SC2LE來提前模拟比賽的發展,還是在AI中自己儲存各機關的詳細資料以對遊戲進行粗略預測,這也是一個至關重要的問題。最後,上個月中國剛成年的智障人皇李中堂time宣布暫時離開星際,在此緬懷一下他在《中國好星際》第四季中的音容笑貌,期待他可能的回歸,祝一切順利~

星際争霸2 AI 開發探索與展望

相關連結

SC2LE:https://github.com/Blizzard/s2client-proto

PySC2:https://github.com/deepmind/pysc2

環境搭建:https://yq.aliyun.com/articles/176617

本文代碼:https://github.com/wlkdb/SC2AI

DeepMind關系深度學習論文:https://arxiv.org/pdf/1806.01830.pdf

繼續閱讀