天天看點

使用神經網絡和遺傳算法玩轉 Flappy Bird

我們建立一個人工智能機器人,它能夠學習如何把flappy bird這個遊戲玩出最高分。這樣,我們的小鳥就能安全地飛過一些障礙物了。在最好的情況下,它永遠不會死。

歡迎閱讀這篇完整的html5教程,本文展示了針對flappy bird遊戲設計的機器學習算法。本實驗的目标是使用神經網絡和遺傳算法編寫一個人工智能遊戲控制器。

是以,我們打算建立一個人工智能機器人,它能夠學習如何把flappy bird這個遊戲玩出最高分。這樣,我們的小鳥就能安全地飛過一些障礙物了。在最好的情況下,它永遠不會死。

首先,讓我們從示範程式開始,看一下遊戲過程中的算法:

使用神經網絡和遺傳算法玩轉 Flappy Bird

除了上面的示範程式之外,你還可以觀看這部簡單展示了算法的視訊短片。這對那些喜歡快進的人來說簡直太棒了!

根據1959年亞瑟·塞缪爾(arthur samuel)的說法,機器學習是讓計算機在不顯式程式設計的情況下行動的科學。一般來說,這是一個循序漸進地改進初始随機系統的學習過程。

是以,實作人工智能的目标是通過對一個差的系統進行模型參數的微調來找到一個适當的解決方案。為此,機器學習算法使用了許多不同的方法。

對于本項目,機器學習算法(ml,machine learning)的主要方法是基于神經演化的。這種機器學習在形式上使用了遺傳算法(ga,genetic algorithm)等進化算法來訓練人工神經網絡(ann,artificial neural network)。

是以,在這個例子中,我們可以說:機器學習 = 遺傳算法 + 人工神經網絡(ml = ga + ann)。

人工神經網絡是機器學習算法的一個子集。它的誕生受到了生物神經網絡結構和功能的啟發。這些網絡由許多發送信号的神經元組成。

是以,要建立一個人造大腦,我們需要模拟出神經元并将它們連接配接成一個神經網絡。

通用人造神經網絡是由輸入層、一個或多個隐藏層,以及輸出層組成。每一層都有一定數量的神經元。輸入和輸出神經元直接與外部環境相連,而隐藏的神經元則将以上兩者連接配接起來。

在本項目中,每個單元(小鳥)都有自己的神經網絡作為ai大腦來玩遊戲。它由以下三層組成:

一個具有2個神經元的輸入層,表示一隻小鳥看到的東西:

   - 與最近間隙的水準距離

   - 與最近間隙的高度差

具有6個神經元的隐藏層

具有1個神經元的輸出層,提供如下動作:

   - 如果 輸出 > 0.5,則扇動翅膀,否則什麼也不做

下圖顯示了本示範程式的神經網絡架構:

使用神經網絡和遺傳算法玩轉 Flappy Bird

在談論到機器學習算法的時候,可以說,遺傳算法可以用來訓練和改進神經網絡。

遺傳算法是一種基于搜尋的優化技術,其靈感來自于自然選擇和遺傳過程。它采用選擇、交叉和變異相結合的方法來進化初始随機種群。

以下是遺傳算法實作的主要步驟:

用随機神經網絡建立10個單元(小鳥)的初始鳥群

讓所有的單元同時使用自己的神經網絡進行遊戲。

對于每個單元,計算其适應度函數來衡量其品質(詳情請參閱下面的“适應度函數”章節)

當所有的單元都死亡時,使用遺傳算子來評估目前鳥群以生成下一個鳥群(詳情請參閱下面的“替換政策”章節)

傳回到步驟2

除了遺傳算法(步驟3)之外,下面我們将了解一下有關适應度函數的一些細節,例如,适應度函數是什麼,如何定義。

因為我們希望通過使用最好的小鳥來進化鳥群,是以需要定義一個适應度函數。

通常來說,适應度函數是衡量對象品質的名額。我們會度量每隻鳥的品質,然後選擇最适合的小鳥,并用它來重新生成下一批小鳥。

在本項目中,我們會根據小鳥飛行的距離來進行獎勵。同時,根據小鳥目前到最近間隙的距離進行懲罰。是以,在這過程中,飛行了相同距離的小鳥之間就會産生差别。

是以,适應度函數是“小鳥飛行的總距離”和“與最近間隙的距離”之間的差。

使用神經網絡和遺傳算法玩轉 Flappy Bird

除了遺傳算法(步驟4)之外,以下是将自然進化應用于小鳥死亡的步驟。最好的小鳥生存下來,然後他們的孩子就以下面這種方式來替代最糟糕的小鳥:

按照适應度對目前所有的小鳥進行排序

選擇前4名(勝利者),并将他們直接傳遞給下一個鳥群

建立一個後代作為兩個最佳勝利者的交叉産品

建立3個後代作為兩個随機勝利者的交叉産品

建立2個後代作為兩個随機勝利者的直接副本

對每個後代應用随機突變,以增加一些變異

phaser.min.js

synaptic.min.js

整個遊戲邏輯在gameplay.js檔案中實作。它由以下類組成:

<code>app.main</code>,主程式,包含以下基本功能:

<code>_preload()_</code> 預加載所有資源

<code>_create()_</code> 建立所有對象并初始化一個新的遺傳算法對象

<code>_update()_</code> 運作遊戲的主循環,并使用遺傳算法進化鳥群

<code>_drawstatus()_</code> 顯示所有小鳥的資訊

<code>treegroup 類</code>,擴充了phaser group類,用于移動障礙物,包含頂部和底部的樹。

<code>tree 類</code>,擴充了phaser sprite類,用來表示一棵樹。

<code>bird 類</code>,擴充了phaser sprite類,用來表示一隻鳥。

<code>text 類</code>,用于繪制文本的phaser bitmaptext類。

遺傳算法在genetic.js檔案中實作,該檔案由以下類組成:

<code>geneticalgorithm 類</code>,處理所有遺傳算法操作的主類。它需要兩個參數:max_units用于設定小鳥的總數量,top_units用于設定獲勝者的數量。以下是其基本函數:

    - <code>_reset()_</code> 重置遺傳算法參數

    - <code>_createpopulation()_</code> 建立新的鳥群

    - <code>_activatebrain()_</code> 激活小鳥的ai神經網絡,并根據輸入擷取其輸出動作

    - <code>_evolvepopulation()_</code> 通過使用遺傳算子(選擇、交叉和突變)來讓鳥群進化

    - <code>_selection()_</code> 從目前鳥群中選擇最佳小鳥

    - <code>_crossover()_</code> 執行在兩個父節點之間的單點交叉

    - <code>_mutation()_</code> 對後代進行随機突變

在本教程中,我們成功實作了一個會學習如何玩flappy bird遊戲的ai機器人。經過幾次疊代,可以得到一個幾乎無敵的玩家。為了達到這一目标,采用了兩種機器學習算法:人工神經網絡和遺傳算法。

你可以嘗試更改代碼中的一些參數,看看會發生什麼。例如,你可以更改隐藏層中的神經元數量或小鳥的數量。此外,你還可以嘗試以某種方式修改适應度函數,修改一些實體參數,比如障礙物之間的距離、重力等等!

試着将這裡的進化理念應用到其他遊戲中去吧!

文章原标題《machine learning algorithm for flappy bird using neural network and genetic algorithm》,作者:srdjan,譯者:夏天,審校:主題曲哥哥。

繼續閱讀