程序員帶你一步步分析AI如何玩Flappy Bird

       如下內容來源於一次部門內部的分享,主要針對AI初學者,介紹包括CNN、Deep Q Network以及TensorFlow平臺等內容。因爲筆者並不是深度學習算法研究者,所以如下更多從應用的角度對整個系統進行介紹,而不會進行詳細的公式推導。ios

 

       關於Flappy Bird Flappy Bird(非官方譯名:笨鳥先飛)是一款2013年鳥飛類遊戲,由越南河內獨立遊戲開發者阮哈東(Dong Nguyen)開發,另外一個獨立遊戲開發商GEARS Studios發佈。—— 以上內來自《維基百科》 Flappy Bird操做簡單,經過點擊手機屏幕使Bird上升,穿過柱狀障礙物以後得分,碰到則遊戲結束。因爲障礙物高低不等,控制Bird上升和降低須要反應快而且靈活,要獲得較高的分數並不容易,筆者目前最多得過10分。算法

       本文主要介紹如何經過AI(人工智能)的方式玩Flappy Bird遊戲,分爲如下四個部份內容: Flappy Bird 遊戲展現 模型:卷積神經網絡 算法:Deep Q Network 代碼:TensorFlow實現 1、Flappy Bird 遊戲展現 在介紹模型、算法前先來直接看下效果,上圖是剛開始訓練的時候,畫面中的小鳥就像無頭蒼蠅同樣亂飛,下圖展現的是在本機(後面會給出配置)訓練超過10小時後(訓練步數超過2000000)的狀況,其最好成績已經超過200分,人類玩家已基本不可能超越。網絡


訓練數小於10000步(剛開始訓練)app

 

訓練步數大於2000000步(10小時後)dom

 

        因爲本機配置了CUDA以及cuDNN,採用了NVIDIA的顯卡進行並行計算,因此這裏提早貼一下運行時的日誌輸出。機器學習

        關於CUDA以及cuDNN的配置,其中有一些坑包括:安裝CUDA以後循環登陸,屏幕分辨率沒法正常調節等等,都是因爲NVIDIA驅動安裝的問題,這不是本文要討論的主要內容,讀者可自行Google。分佈式

 

  • 加載CUDA運算庫
  • 加載CUDA運算庫函數

  • TensorFlow運行設備 /gpu:0
  • TensorFlow運行設備/gpu:0學習

  • /gpu:0 這是TensorFlow平臺默認的配置方法,表示使用系統中的第一塊顯卡。 本機軟硬件配置: 系統:Ubuntu 16.04 顯卡:NVIDIA GeForce GTX 745 4G 版本:TensorFlow 1.0 軟件包:OpenCV 3.2.0、Pygame、Numpy、… 細心的朋友可能發現,筆者的顯卡配置並不高,GeForce GTX 745,顯存3.94G,可用3.77G(桌面佔用了一部分),屬於入門中的入門。對於專業作深度學習算法的朋友,這個顯卡必然是不夠的。知乎上有帖子教你們怎麼配置更專業的顯卡,有興趣的能夠移步。人工智能

 

2、模型:卷積神經網絡

神經網絡算法是由衆多的神經元可調的鏈接權值鏈接而成,具備大規模並行處理、分佈式信息存儲、良好的自組織自學習能力等特色。人工神經元與生物神經元結構相似,其結構對好比下圖所示。

生物神經元

 

人工神經元

       人工神經元的輸入(x1,x2...xm)相似於生物神經元的樹突,輸入通過不一樣的權值(wk1, wk2, ....wkn),加上偏置,通過激活函數獲得輸出,最後將輸出傳輸到下一層神經元進行處理。 單神經元輸出函數 激活函數爲整個網絡引入了非線性特性,這也是神經網絡相比於迴歸等算法擬合能力更強的緣由。經常使用的激活函數包括sigmoid、tanh等,它們的函數表達式以下:

sigmoid函數

tanh雙曲正切函數

這裏能夠看出,sigmoid函數的值域是(0,1),tanh函數的值域是(-1,1)。

卷積神經網絡起源於動物的視覺系統,主要包含的技術是:

  1. 局部感知域(稀疏鏈接);
  2. 參數共享;
  3. 多卷積核;
  4. 池化。

1. 局部感知域(稀疏鏈接) 全鏈接網絡的問題在於:

  1. 須要訓練的參數過多,容器致使結果不收斂(梯度消失),且訓練難度極大;
  2. 實際上對於某個局部的神經元來說,它更加敏感的是小範圍內的輸入,換句話說,對於較遠的輸入,其相關性很低,權值也就很是小。 人類的視覺系統決定了人在觀察外界的時候,老是從局部到全局。

       好比,咱們看到一個美女,可能最早觀察到的是美女身上的某些部位(本身體會)。

       所以,卷積神經網絡與人類的視覺相似,採用局部感知,低層的神經元只負責感知局部的信息,在向後傳輸的過程當中,高層的神經元將局部信息綜合起來獲得全局信息。

全鏈接與局部鏈接的對比(圖片來自互聯網)

       從上圖中能夠看出,採用局部鏈接以後,能夠大大的下降訓練參數的量級。

   2. 參數共享

       雖然經過局部感知下降了訓練參數的量級,但整個網絡須要訓練的參數依然不少。

        參數共享就是將多個具備相同統計特徵的參數設置爲相同,其依據是圖像中一部分的統計特徵與其它部分是同樣的。其實現是經過對圖像進行卷積(卷積神經網絡命名的來源)。

       能夠理解爲,好比從一張圖像中的某個局部(卷積核大小)提取了某種特徵,而後以這種特徵爲探測器,應用到整個圖像中,對整個圖像順序進行卷積,獲得不一樣的特徵。
 

卷積過程(圖片來自互聯網)

       每一個卷積都是一種特徵提取方式,就像一個篩子,將圖像中符合條件(激活值越大越符合條件)的部分篩選出來,經過這種卷積就進一步下降訓練參數的量級。

  • 3. 多卷積核

       如上,每一個卷積都是一種特徵提取方式,那麼對於整幅圖像來說,單個卷積核提取的特徵確定是不夠的,那麼對同一幅圖像使用多種卷積核進行特徵提取,就能獲得多幅特徵圖(feature map)

不一樣的卷積核提取不一樣的特徵(圖片來自互聯網)

多幅特徵圖能夠當作是同一張圖像的不一樣通道,這個概念在後面代碼實現的時候用得上。

  • 4. 池化

         獲得特徵圖以後,可使用提取到的特徵去訓練分類器,但依然會面臨特徵維度過多,難以計算,而且可能過擬合的問題。從圖像識別的角度來說,圖像可能存在偏移、旋轉等,但圖像的主體卻相同的狀況。也就是不一樣的特徵向量可能對應着相同的結果,那麼池化就是解決這個問題的。

        池化就是將池化核範圍內(好比2*2範圍)的訓練參數採用平均值(平均值池化)或最大值(最大值池化)來進行替代。

        終於到了展現模型的時候,下面這幅圖是筆者手畫的(用電腦畫太費時,將就看吧),這幅圖展現了本文中用於訓練遊戲所用的卷積神經網絡模型。

卷積神經網絡模型

圖像的處理過程

  1. 初始輸入四幅圖像80×80×4(4表明輸入通道,初始時四幅圖像是徹底一致的),通過卷積核8×8×4×32(輸入通道4,輸出通道32),步距爲4(每步卷積走4個像素點),獲得32幅特徵圖(feature map),大小爲20×20;
  2. 將20×20的圖像進行池化,池化核爲2×2,獲得圖像大小爲10×10;
  3. 再次卷積,卷積核爲4×4×32×64,步距爲2,獲得圖像5×5×64;
  4. 再次卷積,卷積核爲3×3×64*64,步距爲2,獲得圖像5×5×64,雖然與上一步獲得的圖像規模一致,但再次卷積以後的圖像信息更爲抽象,也更接近全局信息;
  5. Reshape,即將多維特徵圖轉換爲特徵向量,獲得1600維的特徵向量;
  6. 通過全鏈接1600×512,獲得512維特徵向量;
  7. 再次全鏈接512×2,獲得最終的2維向量[0,1]和[1,0],分別表明遊戲屏幕上的是否點擊事件。

 

        能夠看出,該模型實現了端到端的學習,輸入的是遊戲屏幕的截圖信息(代碼中通過opencv處理),輸出的是遊戲的動做,便是否點擊屏幕。深度學習的強大在於其數據擬合能力,不須要傳統機器學習中複雜的特徵提取過程,而是依靠模型發現數據內部的關係。

        不過這也帶來另外一方面的問題,那就是深度學習高度依賴大量的標籤數據,而這些數據獲取成本極高。

3、算法:Deep Q Network

 

        有了卷積神經網絡模型,那麼怎樣訓練模型?使得模型收斂,從而可以指導遊戲動做呢?機器學習分爲監督學習、非監督學習和強化學習,這裏要介紹的Q Network屬於強化學習(Reinforcement Learning)的範疇。在正式介紹Q Network以前,先簡單說下它的光榮歷史。

        2014年Google 4億美金收購DeepMind的橋段,你們可能據說過。那麼,DeepMind是如何被Google給盯上的呢?最終緣由能夠歸咎爲這篇論文:

Playing Atari with Deep Reinforcement Learning

 

        DeepMind團隊經過強化學習,完成了20多種遊戲,實現了端到端的學習。其用到的算法就是Q Network。2015年,DeepMind團隊在《Nature》上發表了一篇升級版:

Human-level control through deep reinforcement learning

 

        自此,在這類遊戲領域,人已經沒法超過機器了。後來又有了AlphaGo,以及Master,固然,這都是後話了。其實本文也屬於上述論文的範疇,只不過基於TensorFlow平臺進行了實現,加入了一些筆者本身的理解而已。

        回到正題,Q Network屬於強化學習,那麼先介紹下強化學習。

強化學習模型    

這張圖是從UCL的課程中拷出來的,課程連接地址(YouTube):
https://www.youtube.com/watch?v=2pWv7GOvuf0

        強化學習過程有兩個組成部分:

  • 智能代理(學習系統)
  • 環境

        如圖所示,在每步迭代過程當中,首先智能代理(學習系統)接收環境的狀態st,而後產生動做at做用於環境,環境接收動做at,而且對其進行評價,反饋給智能代理rt。不斷的循環這個過程,就會產生一個狀態/動做/反饋的序列:(s1, a1, r1, s2, a2, r2.....,sn, an, rn),而這個序列讓咱們很天然的想起了:

  • 馬爾科夫決策過程

MDP:馬爾科夫決策過程

    馬爾科夫決策過程與著名的HMM(隱馬爾科夫模型)相同的是,它們都具備馬爾科夫特性。那麼什麼是馬爾科夫特性呢?簡單來講,就是將來的狀態只取決於當前的狀態,與過去的狀態無關。

HMM(馬爾科夫模型)在語音識別,行爲識別等機器學習領域有較爲普遍的應用。條件隨機場模型(Conditional Random Field)則用於天然語言處理。兩大模型是語音識別、天然語言處理領域的基石。

 

        上圖能夠用一個很形象的例子來講明。好比你畢業進入了一個公司,你的初始職級是T1(對應圖中的 s1),你在工做上刻苦努力,追求上進(對應圖中的a1),而後領導以爲你不錯,準備給你升職(對應圖中的r1),因而,你升到了T2;你繼續刻苦努力,追求上進......不斷的努力,不斷的升職,最後升到了sn。固然,你也有可能不努力上進,這也是一種動做,換句話說,該動做a也屬於動做集合A,而後獲得的反饋r就是沒有升職加薪的機會。

        這裏注意下,咱們固然但願獲取最多的升職,那麼問題轉換爲:如何根據當前狀態s(s屬於狀態集S),從A中選取動做a執行於環境,從而獲取最多的r,即r1 + r2 ……+rn的和最大 ?這裏必需要引入一個數學公式:狀態值函數。
 

狀態值函數模型

 

        公式中有個摺合因子γ,其取值範圍爲[0,1],當其爲0時,表示只考慮當前動做對當前的影響,不考慮對後續步驟的影響,當其爲1時,表示當前動做對後續每步都有均等的影響。固然,實際狀況一般是當前動做對後續得分有必定的影響,但隨着步數增長,其影響減少。

         從公式中能夠看出,狀態值函數能夠經過迭代的方式來求解。加強學習的目的就是求解馬爾可夫決策過程(MDP)的最優策略。

        策略就是如何根據環境選取動做來執行的依據。策略分爲穩定的策略和不穩定的策略,穩定的策略在相同的環境下,老是會給出相同的動做,不穩定的策略則反之,這裏咱們主要討論穩定的策略。

        求解上述狀態函數須要採用動態規劃的方法,而具體到公式,不得不提:

  • 貝爾曼方程

貝爾曼方程

 

        其中,π表明上述提到的策略,Q π (s, a)相比於V π (s),引入了動做,被稱做動做值函數。對貝爾曼方程求最優解,就獲得了貝爾曼最優性方程

狀態值函數最優解

動做值函數最優解

        求解該方程有兩種方法:策略迭代值迭代

  • 策略迭代

策略迭代分爲兩個步驟:策略評估策略改進,即首先評估策略,獲得狀態值函數,其次,改進策略,若是新的策略比以前好,就替代老的策略。

策略迭代

  • 值迭代

從上面咱們能夠看到,策略迭代算法包含了一個策略估計的過程,而策略估計則須要掃描(sweep)全部的狀態若干次,其中巨大的計算量直接影響了策略迭代算法的效率。而值迭代每次只掃描一次,更新過程以下:

值迭代

即在值迭代的第k+1次迭代時,直接將能得到的最大的Vπ(s)值賦給Vk+1。

  • Q-Learning

Q-Learning是根據值迭代的思路來進行學習的。該算法中,Q值更新的方法以下:

Q值更新方法

        雖然根據值迭代計算出目標Q值,可是這裏並無直接將這個Q值(是估計值)直接賦予新的Q,而是採用漸進的方式相似梯度降低,朝目標邁近一小步,取決於α,這就可以減小估計偏差形成的影響。相似隨機梯度降低,最後能夠收斂到最優的Q值。具體算法以下:

Q-Learning算法

若是沒有接觸過動態規劃的童鞋看上述公式可能有點頭大,下面經過表格來演示下Q值更新的過程,你們就明白了。

 

狀態 a1 a2 a3 a4
S1 Q(1, 1) Q(1, 2) Q(1, 3) Q(1, 4)
S2 Q(2, 1) Q(2, 2) Q(2, 3) Q(2, 4)
S3 Q(3, 1) Q(3, 2) Q(3, 3) Q(3, 4)
S4 Q(4, 1) Q(4, 2) Q(4, 3) Q(4, 4)

        Q-Learning算法的過程就是存儲Q值的過程。上表中,橫列爲狀態s,縱列爲Action a,s和a決定了表中的Q值。

  • 第一步:初始化,將表中的Q值所有置0;
  • 第二步:根據策略及狀態s,選擇a執行。假定當前狀態爲s1,因爲初始值都爲0,因此任意選取a執行,假定這裏選取了a2執行,獲得了reward爲1,而且進入了狀態s3。根據Q值更新公式:

Q值更新公式

        來更新Q值,這裏咱們假設α是1,λ也等於1,也就是每一次都把目標Q值賦給Q。那麼這裏公式變成:

Q值更新公式

因此在這裏,就是

本次Q值更新

那麼對應的s3狀態,最大值是0,因此

Q值

Q表格就變成:

狀態 a1 a2 a3 a4
S1 0 1 0 0
S2 0 0 0 0
S3 0 0 0 0
S4 0 0 0 0

 

而後置位當前狀態s爲s3。

  • 第三步:繼續循環操做,進入下一次動做,當前狀態是s3,假設選擇動做a3,而後獲得reward爲2,狀態變成s1,那麼咱們一樣進行更新:

Q值更新

因此Q的表格就變成:

狀態 a1 a2 a3 a4
S1 0 1 0 0
S2 0 0 0 0
S3 0 0 3 0
S4 0 0 0 0
  • 第四步: 繼續循環,Q值在試驗的同時反覆更新,直到收斂。
相關文章
相關標籤/搜索