強化學習的基本概念與程式碼實現

機器之心發表於2019-02-21

從 AlphaGo 到自動駕駛汽車,我們能在很多最先進的人工智慧應用中找到強化學習的身影。這種技術是如何從零開始慢慢學會完成任務,成長為「超越人類水平」的專家的?本文將會進行一番簡要介紹。選自DeepLearning4j,機器之心編譯。

神經網路造就了最近我們在計算機視覺、機器翻譯和時間序列預測等領域上的突破—同時它也可以和強化學習演算法結合來建立一些驚人的成果,例如 AlphaGo(參閱:無需人類知識,DeepMind 新一代圍棋程式 AlphaGo Zero 再次登上 Nature)。

強化學習指的是面向目標的演算法,這種演算法學習如何在一些具體的步驟中達到一個目標或者最大化;例如,最大化一個遊戲中通過一些行動而獲得的得分。它們可以從一個空白狀態開始,然後在合適的條件下達到超越人類水平的效能。就像被糖果和體罰刺激的小孩子一樣,當它們做出錯誤的預測時,這些演算法會受到懲罰,當它們做出正確的預測時,它們會得到獎勵—這便是強化的意義所在。

結合深度學習的強化演算法可以在圍棋和 Atari 遊戲中打敗人類冠軍。儘管這聽起來還不具有足夠的說服力,但是這已經遠遠優於它們之前的成就了,而且目前最先進的進步是很迅速的。

兩個強化學習的演算法 Deep-Q learning 和 A3C 已經在 Deeplearning4j 庫上實現了,現在,它已經可以玩《毀滅戰士(Doom)》了。

強化學習解決了對即刻行動和與之相關的延遲響應之間的關聯的問題。就像人類一樣,強化學習演算法必須等待一會,看看它們決策的結果如何。它們執行在延遲響應的環境之中,在這種環境中理解哪些行動在多個步驟後導致哪些結果是很困難的。

我們可以期望強化學習演算法在更加模糊的現實環境中表現得更好,它可以在真實環境下從任意多個可能的行動中進行選擇,而不是從有限個電子遊戲動作選項中進行選擇。也就是說,隨著時間的推移,我們希望它們(強化學習演算法)能夠在現實世界中有著實現目標的價值。

強化學習入門(docs.skymind.ai/docs?__hstc…

強化學習定義

我們可以通過了解智慧體、環境、狀態、行動以及獎勵等概念來理解強化學習,我們會在一下的內容裡解釋這些概念。大寫字母表示事物的集合,小寫字母代表事物的例項;例如,A 是所有可能存在的行動的集合,而 a 是這個集合中包含的一個例項。

  • 智慧體(Agent):可以採取行動的智慧個體;例如,可以完成投遞的無人機,或者在視訊遊戲中朝目標行動的超級馬里奧。強化學習演算法就是一個智慧體。而在現實生活中,那個智慧體就是你。

  • 行動(Action):A 是智慧體可以採取的行動的集合。一個行動(action)幾乎是一目瞭然的,但是應該注意的是智慧體是在從可能的行動列表中進行選擇。在電子遊戲中,這個行動列表可能包括向右奔跑或者向左奔跑,向高出處跳或者向低處跳,下蹲或者站住不動。在股市中,這個行動列表可能包括買入,賣出或者持有任何有價證券或者它們的變體。在處理空中飛行的無人機時,行動選項包含三維空間中的很多速度和加速度。

  • 環境(Environment):指的就是智慧體行走於其中的世界。這個環境將智慧體當前的狀態和行動作為輸入,輸出是智慧體的獎勵和下一步的狀態。如果你是一個智慧體,那麼你所處的環境就是能夠處理行動和決定你一系列行動的結果的物理規律和社會規則。

  • 狀態(State,S):一個狀態就是智慧體所處的具體即時狀態;也就是說,一個具體的地方和時刻,這是一個具體的即時配置,它能夠將智慧體和其他重要的失事物關聯起來,例如工具、敵人和或者獎勵。它是由環境返回的當前形勢。你是否曾在錯誤的時間出現在錯誤的地點?那無疑就是一個狀態了。

  • 獎勵(Reward,R):獎勵是我們衡量某個智慧體的行動成敗的反饋。例如,在視訊遊戲中,當馬里奧碰到金幣的時候,它就會贏得分數。面對任何既定的狀態,智慧體要以行動的形式向環境輸出,然後環境會返回這個智慧體的一個新狀態(這個新狀態會受到基於之前狀態的行動的影響)和獎勵(如果有任何獎勵的話)。獎勵可能是即時的,也可能是遲滯的。它們可以有效地評估該智慧體的行動。

  • 策略(policy,π):policy 是智慧體基於當前的狀態做出下一步行動所用的策略。

  • 價值(value,V):期望的具有折扣的長期收益,而不是短期回報 R。我們定義 Vπ(s) 為當前狀態為 s 時基於策略π的長期回報。

  • Q 價值或者行動價值(Q):Q 價值(Q-Value)和上述的價值類似,不同的是它還使用了另一個引數–當前的行動 a。Vπ(s) 指的是基於當前狀態 s,行動 a 和策略π,得到的長期回報。

所以,環境就是能夠將當前狀態下采取的動作轉換成下一個狀態和獎勵的函式;智慧體是將新的狀態和獎勵轉換成下一個行動的函式。我們可以知悉智慧體的函式,但是我們無法知悉環境的函式。環境是一個我們只能看到輸入輸出的黑盒子。強化學習相當於智慧體在嘗試逼近這個環境的函式,這樣我們就能夠向黑盒子環境傳送最大化獎勵的行動了。

強化學習的基本概念與程式碼實現

在上圖的反饋迴路中,每一個代表時間步驟的下標 t 和 t+1 都指的是一個不同的狀態:在 t 時刻和 t+1 時刻的狀態。與其他諸如監督學習和非監督學習形式不同—強化學習僅可以被認為是一系列先後發生的狀態-行動(state-action)對。

強化學習通過行動產生的結果來判斷行動。它是面向目標的,它的目標是習得能夠讓智慧體達到目標的一些行動序列。這裡有一些例子。

  • 在電子遊戲中,這個目標是以最高的分數完成遊戲,所以遊戲過程中每一次得到的額外分數都會影響智慧體隨後的行動;也就是說,智慧體可能學會:為了最大化它的得分,他應該射擊戰艦,觸碰硬幣或者躲避流星。

  • 在現實世界中,一個機器人的目標可能是從 A 點移動到 B 點,機器人從 A 點向 B 點移動的每一英寸都算作得分。

可以通過對輸入的解釋將強化學習與監督學習和非監督學習區分開來。我們可以通過描述它們學習的「東西」來說明它們的不同之處。

  • 無監督學習:那東西就是這個樣子的。(無監督學習演算法學到了沒有名字的事物之間的相似性,通過進一步的擴充套件,它們可以通過識別不尋常或者不相似的例項來發現相反或者執行異常檢測)

  • 監督學習:那個東西是一塊「雙層吉士漢堡」。(標籤,聯絡名字和麵孔……)這些監督學習演算法學到了資料實體例項和它們的標籤之間的關聯;也就是說,監督學習演算法需要有一個有標籤的資料集。那些標籤被用來「監督」和矯正演算法,因為演算法在預測標籤的時候可能會做出錯誤的猜測。

  • 強化學習:吃了這個東西,因為它味道蠻不錯,而且可以讓你活得更久。(基於短期和回報和長期回報的獎勵,就相當於你攝入的卡路里或者你生存的時間一樣。)強化學習可以被看做是在一個具有稀疏反饋的環境中的監督學習。

強化學習的域選擇

可以將一個自動強化學習的智慧體想象為一個盲人,這個盲人智慧依靠耳朵和手中的白手杖來嘗試在這個世界中導航。智慧體有一些允許它們感知所處環境的小窗,但是那些小窗甚至是最不適合它們感知周遭環境的最不適合的方式。

事實上,決定你的智慧體的輸入和反饋型別是一個需要解決的複雜問題。這就是所謂的域選擇問題。學習玩電子遊戲的演算法可以忽略這個問題,因為它們的環境是人為設定的,而且是受到嚴格限制的。因此,電子遊戲提供了無菌的實驗室環境,可以在裡面測試強化學習的想法。域選擇需要人為決定,通常是基於需要解決的問題的知識或理論來進行的;例如,在無人車的演算法中輸入域的選擇可能包括雷達感測器、相機以及 GPS 資料的資訊。

強化學習的基本概念與程式碼實現

狀態-動作對(state-action pair)& 複雜的獎勵概率分佈

強化學習演算法的目標是習得針對任意給定狀態的最佳行動,這意味著行動必須被排序,並逐個賦值。由於那些行動都是依賴於狀態的,所以我們實際上測量的是狀態-行動對(state-action pairs)的價值;也就是說,您在某個狀態下采取的行動,也就是你在某地方所做的某件事情。這裡有幾個例子,可以描述一下一個行動的價值和意義取決於智慧體在採取這個行動時所面對的狀態。

  • 如果這裡的行動指的是和某人結婚,那麼您在 18 歲的時候和一位 35 歲的結婚可能會與您在 90 歲的時候與一位 35 歲的結婚大有不同,這兩個結果可能會有著不同的動機,而且會進一步導致不同的結果。

  • 如果這裡的行動時大喊一聲「Fire」,那麼在一個人群密集的影院和在一眾持槍者旁邊大喊這句話則有不同的意義。如果不瞭解具體的語境,我們就不能預測行動會導致的結果。

我們用上述的 Q 函式將狀態-行動對對映到我們希望它能夠產生的價值上。Q 函式將智慧體的狀態和行動作為輸入,將它們對映到可能的獎勵上。

強化學習是通過一系列狀態-行動對來執行智慧體的過程,觀察狀態-行動對所導致的結果,調整 Q 函式的預測,直到它能夠準確地預測出智慧體應該採取的最佳行動。這種預測被稱作策略。

強化學習是一種嘗試,它對於大量的狀態-行動對以及與之關聯的獎勵的複雜概率分佈進行建模。這是強化學習與馬爾科夫決策過程(https://deeplearning4j.org/markovchainmontecarlo)配合使用的一個原因,馬爾科夫決策過程是一個從複雜的分佈中進行取樣,以推斷它的屬性的一種方法。這和啟發 Stan Ulam 來發明蒙特卡羅方法的問題是很相似的;即在紙牌遊戲中通過給定的手牌嘗試推斷獲勝的機會。

任何統計方法,其本質上都是無知的。有些現象(例如生物學、政治學或者與棋類遊戲有關的現象)的巨大複雜性使得從最初原則去推斷是不可能的。唯一的方法就是通過統計去研究它們,從表面去衡量事件,並嘗試建立它們之間的關聯,即便我們不懂得它們相關聯的機制。就像深度神經網路一樣,強化學習就是這樣的方法,依靠取樣來從資料中抽取資訊。

強化學習是迭代的。在大多數有趣的應用中,它起始的時候都並不明白當前的狀態-行動對會產生怎樣的獎勵。強化學習演算法通過在一次又一次的狀態中執行以學到這些關聯,就像運動員或者音樂家在一次又一次的狀態迭代中提升他們的水平一樣。

機器學習與時間之間的關係

也許你會認為強化學習演算法與實踐的關係與人類有所不同。我們可以在相同的狀態下采取不同的行動執行演算法,直至我們可以可以推斷哪個行動是狀態對應的最佳行動。事實上,我們給演算法設定了它們自己的土撥鼠日(http://www.imdb.com/title/tt0107048/0),它們從一個蠢蛋開始,然後慢慢獲得智慧。

由於人類從來不會經歷電影之外的那種土撥鼠日,所以強化學習有可能比人類學到更多、更好。你可能會說,與人類相比,這些強化學習演算法的真正優勢並不在於它們的固有本質,而在於它們能夠並行地存在於很多晶片上的能力,然後夜以繼日不知疲倦地進行訓練,因此能夠學到更多。一個在圍棋遊戲上訓練的演算法,例如 AlphaGo,它能夠玩的遊戲比任何人類有望在 100 個有生之年玩得還要多。

深度神經網路和深度強化學習

神經網路適合用在什麼地方呢?神經網路是能夠學會對映狀態-行動對和獎勵的智慧體。就像所有的神經網路一樣,它們使用引數來逼近與輸入輸出相關的函式,它們的學習通過沿著錯誤降低的方向迭代地調整引數或者權重構成。

在強化學習中,卷積網路可以被用來識別智慧體的狀態;例如,馬里奧所在的螢幕,或者無人機前面的地形。也就是說,它們起到了典型的影像識別的作用。

但是卷積網路在強化學習中能夠得到比在監督學習中更多的解釋。在監督學習中,網路給一副圖片賦予一個標籤;也就是說,它將名稱對映到畫素上。

強化學習的基本概念與程式碼實現

事實上,卷積網路會根據概率對最適合圖片的標籤進行排序。給定一張驢子的圖片時,卷積網路可能會以 80% 的可能性將其判斷為驢子,以 50% 的概率將其判斷為馬,以 30% 的概率將其判斷為狗。

在強化學習中,給定代表一個狀態的圖片,卷積網路可以給出一個在這個狀態下可以採取的行動的排序;例如,它可能預測執行向右跑的動作會得 5 分,跳躍的動作會得 7 分,向左跑會得 0 分。

強化學習的基本概念與程式碼實現

給期望的獎勵賦予價值之後,Q 函式就會簡單地選擇具有最高的 Q 價值的狀態-行動對。

在強化學習的起始階段,神經網路的引數可能會被隨機初始化。利用從環境中獲得的反饋,神經網路可以使用期望獎勵和實際獎勵之間的差距來調整網路引數,以提升狀態-行動對的解釋性。

這種反饋迴路與監督學習中的誤差反向傳播類似。然而,監督學習開始的時候就已經含有神經網路嘗試預測的真實標籤。它的目標就是去建立能夠對映不同的圖片與對應的名字的模型。

強化學習依靠環境來為演算法提供與每個新行動對應的標量數字。環境返回的獎勵可以使變化的、延遲的或者受已知變數影響的,這會給反饋迴路引入噪聲。

這會得到關於 Q 函式的更完整的表達,它不僅僅考慮由一個行動產生的即時獎勵,而且還能夠將獎勵順序地延遲到幾個時間步長的深度。

就像人類一樣,Q 函式也是遞迴的。就像呼叫溼體函式 human() 一樣,human() 函式自身又包含另一個 human() 函式,我們是裡面的所有結果,給一個給定的狀態-行動對呼叫 Q 函式,需要我們呼叫一個巢狀的 Q 函式來預測下一個狀態的價值,它反過來又要依賴之後的狀態的 Q 函式,以此類推。

程式碼

RL4J 的例子在這裡可以獲得(github.com/deeplearnin…)。 

package org.deeplearning4j.examples.rl4j;

import java.io.IOException;
import org.deeplearning4j.rl4j.learning.HistoryProcessor;
import org.deeplearning4j.rl4j.learning.async.a3c.discrete.A3CDiscrete;
import org.deeplearning4j.rl4j.learning.async.a3c.discrete.A3CDiscreteConv;
import org.deeplearning4j.rl4j.mdp.ale.ALEMDP;
import org.deeplearning4j.rl4j.network.ac.ActorCriticFactoryCompGraphStdConv;
import org.deeplearning4j.rl4j.util.DataManager;

/**
 * @author saudet
 *
 * Main example for A3C with The Arcade Learning Environment (ALE)
 *
 */
public class A3CALE {

    public static HistoryProcessor.Configuration ALE_HP =
            new HistoryProcessor.Configuration(
                    4,       //History length
                    84,      //resize width
                    110,     //resize height
                    84,      //crop width
                    84,      //crop height
                    0,       //cropping x offset
                    0,       //cropping y offset
                    4        //skip mod (one frame is picked every x
            );

    public static A3CDiscrete.A3CConfiguration ALE_A3C =
            new A3CDiscrete.A3CConfiguration(
                    123,            //Random seed
                    10000,          //Max step By epoch
                    8000000,        //Max step
                    8,              //Number of threads
                    32,             //t_max
                    500,            //num step noop warmup
                    0.1,            //reward scaling
                    0.99,           //gamma
                    10.0            //td-error clipping
            );

    public static final ActorCriticFactoryCompGraphStdConv.Configuration ALE_NET_A3C =
            new ActorCriticFactoryCompGraphStdConv.Configuration(
                    0.00025, //learning rate
                    0.000,   //l2 regularization
                    null, null, false
            );

    public static void main(String[] args) throws IOException {

        //record the training data in rl4j-data in a new folder
        DataManager manager = new DataManager(true);

        //setup the emulation environment through ALE, you will need a ROM file
        ALEMDP mdp = null;
        try {
            mdp = new ALEMDP("pong.bin");
        } catch (UnsatisfiedLinkError e) {
            System.out.println("To run this example, uncomment the "ale-platform" dependency in the pom.xml file.");
        }

        //setup the training
        A3CDiscreteConv<ALEMDP.GameScreen> a3c = new A3CDiscreteConv(mdp, ALE_NET_A3C, ALE_HP, ALE_A3C, manager);

        //start the training
        a3c.train();

        //save the model at the end
        a3c.getPolicy().save("ale-a3c.model");

        //close the ALE env
        mdp.close();
    }
}

複製程式碼
原文連結:

相關文章