2017年9月1日 星期五

遊戲開發中的AI - 入門

作者:Arthur Juliani 原文
潤稿:Kelvin Lo


Unity正朝著AI的方向潛心探索著。本文是Unity發佈的首篇AI相關文章,為大家介紹AI的一些概念及術語,詳細介紹機器學習相關理論與方法,並講解在使用Unity開發遊戲的過程中如何應用AI。未來我們還將為大家分享更多AI的內容。在過去幾年,Machine Learning(機器學習,ML)的進步,在檢查物件、翻譯、辨識語言,甚至玩遊戲等等都有突破性發展。值得一提的是,ML和玩遊戲之間的關係在Unity上很像是我們人類的心態。我們相信繼續鑽研能在製作遊戲這塊有突破性的發展,從改變貼圖和3D建模、動畫、人物動作或場景照明的製作方式,到自動產生NPC(非玩家角色)的程式碼。


這篇文章適合的讀者

我們想和Unity的開發者們一起探討關於AI和ML在遊戲開發過程中能發揮的力量,同時也想討論AI用在美術製程的可能性。藉由這次機會剛好可以對ML研究者展現以Unity作為AI研究/開發平台的潛力。像是機器人和自動駕駛等等的模擬平台,讓有興趣的人或研究學生透入研究Unity和ML。


何謂ML(機器學習)

首先來介紹下Machine Learning(機器學習,下文簡稱ML)和遊戲Artificial Intelligence(人工智慧,下文簡稱AI)間的關係。現在大部分遊戲裡的AI都是手動硬寫的,由大量判斷式組成,有時會包含多達數千條規則。而且必須由人工維護和測試。而ML所依賴的演算法可以自動從原始資料尋找規律,無需專業人員預先定義資料的解讀邏輯。

以圖片內容分類這個電腦視覺問題為例。直到幾年前,科學家們仍採用人工編寫篩檢程式,辨識圖像上的特徵,用來分辨某個圖像中包含的是貓還是狗。而ML,特別是最新的深度學習方法,只需圖像和類型標籤,就可以自動學習有用特徵。我們相信這種自動化學習不僅可以拓展Unity平台的應用範圍,例如用於ML場景模擬,還可以幫助所有開發者簡化和加速遊戲的開發過程。

這種自動化學習尤其可以應用在非玩家角色(NPC)的行為。我們可以使用Reinforcement Learning(增強學習,簡稱RL ) 來訓練NPC,預估某一環境中施行特定行為的價值。一旦訓練完成,NPC即可以最佳行為模式做出反應,不用程式對它們的行為進行篩選。後面的文章我們會介紹RL的應用,所有的範例專案也都會公開放在Github上面,你也可以透過WebGL看看整個專案展示。

用RL演算法學習的吃角子老虎

RL背後的一個核心概念是價值估計,並依照此進行對應動作。在繼續深入之前,最好先瞭解一些術語。

在RL裡執行動作的個體稱為agent(代理),它使用policy(策略)進行動作決策。一個代理通常嵌於一個environment(環境)中,並在任意給定的時刻都處於某個特定的state(狀態)。從那個狀態,它可以進行一系列actions(動作)。某個給定狀態的value(值)指的是處於該狀態的最終回報價值。在某個狀態執行一個動作可以讓代理進入另一個新的狀態,獲得一個reward(回報),或者同時擁有兩者。所有RL代理都在盡可能最大化累計回報。



這個RL 範例專案有個問題,技術上稱為multi-armed bandit(或稱為N-armed bandit problem)。這名字源自於為了平衡多台老虎機的回報產生最優化的結果而生,也稱作"Single-arm bandits",設計用來一點一滴的從玩家身上回收錢。在這樣的設定下,環境只包含一種狀態,代理能採取n個動作中的一個。每個動作都會立即為代理提供一個回報。而代理的目地是找出能提供最多回報的動作。

為了更好理解,可以想成一個迷宮遊戲。代理進入一個房間,發現牆邊放著一排寶箱。每個寶箱都有一定的機率開到一顆鑽石(回報+1)或一個敵人惡魂(回報-1)。

代理的目標就是學習思考哪個寶箱最有可能出鑽石。(比如判斷結果為從右屬過來第三個箱子)。要找出回報最高的寶箱最簡單的方法就是逐一嘗試。在代理獲得足夠的資訊並採取最佳行動之前,大部分RL的工作就是簡單的不斷嘗試錯誤。上面這個例子用RL的術語來描述就是,"嘗試"對應的是採取一系列動作(多次打開每個寶箱),學習對應的是更新每個動作的估計值。一旦有了足夠的樣本,就可以讓代理總是選擇那個具有最高估計值的寶箱。

三個寶箱,每個都有機率開出鑽石或敵人



這些估計值可以透過一個反覆運算過程獲得。這個過程從最初的一系列估計V(a)開始,並根據每次動作的結果進行調整。運算式如下:


α對應我們的學習率,V(a)是給定動作的價值估計,r是採取動作後馬上可以獲得的回報。


上面的算式很直覺,它表示出我們將當下的價值估計向獲得回報的方向做了一些微調。這樣就能確保變化的估計值能更好的反應環境中的真實動態。如此一來,還能確保估計不會變得過大,如果我們只計算正向結果就可能會發生這種情況。要完成相應程式,我們可以使用一組值估計向量,並透過代理動作對應的索引來引用它們。



三個寶箱上方顯示的是代理的估計值(綠色球體),以及真實的概率值(中間的半透明球體)。在這個例子中,三個寶箱的潛在正向回報概率分別是 10%(左),20%(中),80%(右)。隨著訓練進行,代理的估計值會變得越來越精確。



情境吃角子老虎(Contextual Bandits)

上述所描述的情況缺少了真實環境中有的一個要素,它只有一個狀態。在現實或遊戲世界裡,一個環境可能會處於幾十(房子裡的房間)到數十億(一個螢幕上的圖元)種可能狀態中的一種。每個狀態都有它們自己獨特的動態特性,即動作如何提供新的回報或者允許狀態間的轉移。

因此,我們需要對動作與估計值以及狀態設定條件。用符號表示,現在將用Q(s,a)取代V(a)。它的抽象意思是,現在期望獲得的回報,是我們所採取的動作以及採取該動作時所處狀態的一個函數。

在迷宮遊戲中,狀態的概念使我們可以在不同的房間中擁有不同的寶箱組。每個房間可以有不同的最理想寶箱,因此,代理需要學習在不同房間中採取不同的動作。用程式來實現的話就是使用一個價值估計的matrix來取代一個簡單的array。這個matrix可以用[state, action]來索引。



探索(Exploring)和利用(Exploiting)

讓RL能運作還需要一個重要的因素。在代理學得採用最佳回報動作的策略之前,需要有另一個策略使它可以充分瞭解世界,以確保它知道什麼是最佳策略。這會引出了一個經典問題,如何平衡探索(exploration)(通過不斷試錯學習環境的價值結構)和利用(exploitation )(基於環境習得的價值結構採取動作)。雖然有時這兩個目標會一致,但大多數狀況它們都會相左。有一系列策略可以平衡這兩個目標。下面列出了其中一部分:

  • 一個簡單卻強大的策略是遵循“optimism in the face of uncertainty”的原則。它的做法是,代理每個動作都從高值估計V(a)開始,這樣它就會貪婪地(利用最大值)採取動作,使它將每個動作都至少執行一次。
  • 如果動作沒有獲得好的回報,就降低對應的價值估計,反之則保持高價值估計,因為該操作可以作為後續好操作的候選。但是僅靠這種自身啟發式演算法通常仍然不夠,因為我們可能需要持續探索某個特定狀態以找到一個低頻率,卻有巨大的回報。
  • 另一個策略是為每個動作的價值估計添加隨機亂數,隨後根據新的亂數估計進行貪婪行為(act greedily)。使用這種方式,只要亂數值小於真實最優動作與其他動作間的差異值,就能收斂至最優的價值估計。
  • 也可以進一步利用估計值本身的特性,將它們進行歸一化(Normalize),依據概率採取動作。這種情況下,如果每個動作的價值估計大致相等,將會以相同概率採取動作。反之,如果一個動作的價值估計要大得多,我們將會更多的選擇這個動作。這樣就能通過遞減選擇無回報動作,慢慢將它們淘汰。這也是在範例專案中所採用的策略。



結語

有了這篇文章以及相關程式碼,你現在也可以嘗試在Unity中使用文章描述的演算法了。但這僅僅是入門而已,在後面的文章我們將通過Q-Learning來講解一個完整的RL問題,並以此為基礎,開始探討深度神經網路,解決視覺豐富遊戲環境中,愈趨複雜的代理行為的學習策略問題。使用這些進階的方法來訓練代理成為我們遊戲中的同伴或對手,適用的遊戲類型可以是格鬥遊戲、賽車、第一人稱射擊,或甚至即時策略遊戲等等。不需要編寫任何規則,只需專注於你希望代理達成的狀態,而非它如何達成的過程。

後續我們還會提供一些工具的早期版本,讓對使用Unity進行深度RL研究感興趣的開發者,可以將諸如Tensorflow或PyTorch等框架編寫的模型連接到Unity製作的環境中。一起探索未來可能是新的遊戲製作方式領域!

沒有留言:

張貼留言

著作人