神經演化法和第十章曾提到過的增強式學習法,這兩者之間有許多相似之處。增強式學習將機器學習融入模擬環境中,讓具備類神經網路的智慧體(agent)透過與環境的互動來學習。在與環境互動的過程中,智慧體會因其決策結果的好壞而得到獎勵或懲罰;結果好的決策會得到獎勵,而結果不好的決策則會得到懲罰。透過這種棒子與胡蘿蔔恩威並施的方式,智慧體就會學到最佳的策略。
在增強式學習法的術語中,「觀察結果」(observation)指的是,智慧體從環境中所接收到的,用於進行決策的資訊;而增強式學習法,基本上就是一種建立在觀察結果上的學習方式。設想有一隻正在走迷宮的老鼠,當牠左轉時會得到一塊乳酪,而當牠右轉時,卻會被電擊。隨著時間過去,想必這隻老鼠最後會學到要左轉而不要右轉。在這過程中,老鼠的神經網路會決定是要右轉還是左轉,並看看結果是嚐到甜頭或吃到苦頭;這甜頭、苦頭,就是老鼠的觀察結果。如果結果是負面的,那老鼠的神經網路可以調整它的權重,以便下次做出不一樣的決策。增強式學習法通常會用來開發機器人。在某個時間,機器人做一件事並看看結果如何。會撞牆嗎?會從桌子上掉下去嗎?還是一點事都沒有?隨著時間過去,機器人會學會以最好的方式來解讀來自環境中的種種資訊,以便能在不受到傷害的情況下完成任務。
在真實世界中的機器人可以裝上類神經網路,然後自己學會做決策,那何不也把類神經網路裝到walker、mover、particle、vehicle等這些先前我們所製作的虛擬世界物件上?這樣這些物件就能學會自己做決策,而不需我們事先幫它們寫好決策演算法。例如,物件可以從虛擬世界的環境中,取得如離障礙物有多遠等資料,並將其輸入類神經網路,然後類神經網路就根據這些輸入資料,輸出如向左移動、向右移動、轉向力大小及方向等決策資料。這樣子,虛擬世界中的物件,就可以視所處環境的變化,自己決定要怎麼做。
上述訓練虛擬世界物件的方式,就是增強式學習法和監督式學習法最大的不同點。監督式學習法利用資料集來訓練類神經網路;而增強式學習法並沒有使用資料集,而是不斷從環境中取得觀察結果來訓練類神經網路。接下來,我們就用《Flappy Bird》這個大家應該比較熟悉也比較容易理解的遊戲,好好的來看看增強式學習法是怎麼個訓練法。
遊戲的玩法很簡單:遊戲開始之後,會有中間有缺口的水管不斷由右至左移動;玩家的任務就是按一下滑鼠或點一下手機畫面,讓小鳥往上飛並順利穿過水管缺口。小鳥順利穿過越多水管缺口分數越高,撞到水管或掉落地面就結束遊戲。想挑戰一下的話,這個網站可以免費玩:《Flappy Bird》
假設我們想讓類神經網路取代人類來玩這個遊戲,那模型應該怎麼設計?類神經網路的輸入、輸出資料又會是什麼呢?
在輸入資料方面,哪些資料可以用來訓練類神經網路玩《Flappy Bird》,其實並沒有很確切的答案;因為看起來這個可以,那個也不錯。既然如此,那最簡單、直截了當的做法,就是把畫面的所有像素都當作輸入資料,一股腦兒全餵給模型,讓模型自己去處理。
把整個畫面的所有像素都當作輸入資料,雖然這做法可行,但卻會讓模型需要處理的資料量大幅增加。例如,如果畫面是800×600,那就會有480000個像素,而模型的輸入,就會有將近50萬個;這可不是個小數目。
所幸,《Flappy Bird》這個遊戲的玩法其實挺簡單的,我們應該可以找出一些輸入的資料點,這些資料點就足以讓模型能夠做出良好的預測。在機器學習中,能夠讓模型做出良好預測的資料點稱為「特徵」(feature)。特徵所代表的,是資料中最能讓模型用來進行預測工作的獨特特性。例如,以水果來說,味道、口感、顏色等,就是能夠讓我們識別出這水果是蘋果的特徵。對於《Flappy Bird》而言,最關鍵的特徵有:
- 小鳥的y軸位置。
- 小鳥的y軸速度。
- 下一個水管缺口頂部的y軸位置。
- 下一個水管缺口底部的y軸位置。
- 小鳥距下一根水管的x方向距離。
畫張圖來看會更清楚一些:

這五個特徵,每一個就是類神經網路的一個輸入。
在輸出方面,那就和遊戲的控制方式有關了。如果遊戲的控制方式是點擊螢幕或按滑鼠,或者是用鍵盤控制,那類神經網路要處理的,顯然是個分類的問題;輸出會是點擊或不點擊螢幕、按下或不按下滑鼠,或者是按下哪個鍵盤按鍵。不過,如果遊戲是用像搖桿這種類比式的控制器來控制,因為輸出值可以是連續的,所以類神經網路要處理的,會比較傾向是個迴歸的問題。對於《Flappy Bird》而言,小鳥就只有拍翅膀和不拍翅膀兩種動作,所以不管是用哪種控制方式,類神經網路所要處理的,會是個分類的問題;它的輸出,就只會是拍翅膀和不拍翅膀兩者之一。
輸入有了、輸出有了,模型要處理的問題類型也知道了,根據第十章介紹過的分類用模型的設計訣竅,模型的輸入層需要五個神經元、輸出層需要兩個神經元,至於隱藏層,因為沒有規則可循,那就先用七個神經元好了;程式這樣寫:
model = keras.models.Sequential()
model.add(keras.Input(shape=(5,)))
model.add(keras.layers.Dense(units=7, activation='relu'))
model.add(keras.layers.Dense(2, activation='softmax'))
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
這裡要注意一下,因為小鳥就只有拍翅膀和不拍翅膀兩種動作,所以類神經網路要處理的,是分類問題中的二元分類(binary classification)問題。要處理二元分類問題,輸出層其實只要一個神經元就夠了。不過,這個神經元的啟動函數要用sigmoid,而損失函數則要用categorical_crossentropy。所以,建造模型時,輸出層的程式要改成這樣:
model.add(keras.layers.Dense(1, activation='sigmoid'))
至於compile()的loss參數設定,擇要改成
loss='binary_crossentropy'
模型有了,那訓練資料從哪來?有個辦法就是廣發英雄帖,找來玩《Flappy Bird》的高手,然後記錄下他們玩遊戲時的數據。利用這些數據,我們就可以訓練模型了。
利用從高手那裡取得的數據來訓練模型,想必這訓練出來的模型智慧體也會是個高手。不過,這種做法卻有些問題。首先,智慧體是真的自己在玩遊戲,還是就只是鸚鵡學舌般地模仿高手的玩法?不管再高的高手都有弱點,如果智慧體只是模仿高手的玩法,那同樣也會有那些弱點。再者,這樣子的訓練方式,其實是監督式學習法,而不是增強式學習法。增強式學習法會讓智慧體和環境互動,並藉由嘗試錯誤的方式,從和環境互動的回饋中學得最佳策略。以玩《Flappy Bird》這個遊戲來說,每次智慧體讓小鳥順利通過水管缺口時,都會得到獎勵;但如果智慧體讓小鳥撞到水管,或者跌落到地面時,則會被懲罰。對於智慧體來說,它的目標就是要搞清楚,在一次又一次不斷嘗試的過程中,到底哪種做法能夠讓它累積最多的獎勵。
在一開始玩《Flappy Bird》時,因為智慧體並不知道拍動翅膀的最佳時機,所以常常會讓小鳥撞上水管或掉落地面。然而,隨著智慧體藉由一次又一次的嘗試而累積越來越多的回饋,它會開始微調做法,並發展出能夠讓小鳥順利通過水管缺口的最佳策略,以此來讓所獲得的獎勵總量最大化。這種透過做中學以及根據回饋來進行最佳化的學習過程,正是增強式學習法的精髓之所在。
在本章後續的章節中,我們會繼續探討在這裡所描繪出來的原理,不過會稍微改變一下方向,不去研究增強式學習法中,包括訂定稱之為「政策」(policy)的策略,以及相應用於提供調整政策所需回饋的獎勵函數(reward function)等傳統技術,而是轉向探討本章的主題:神經演化。













