1. 前言

雖然將深度學習和加強學習結合的想法在幾年前就有人嘗試,但真正成功的開端就是DeepMind在NIPS 2013上發表的 Playing Atari with Deep Reinforcement Learning 一文,在該文中第一次提出Deep Reinforcement Learning 這個名稱,而且提出DQN(Deep Q-Network)算法,實現從純圖像輸入徹底經過學習來玩Atari遊戲的成果。以後DeepMind在Nature上發表了改進版的DQN文章Human-level Control through Deep Reinforcement Learning,引發了普遍的關注,Deep Reinfocement Learning 今後成爲深度學習領域的前沿研究方向。github

智能體 Agent 來表示一個具有行爲能力的物體,好比機器人,無人車,人等等。算法

那麼加強學習考慮的問題就是智能體Agent和 環境 Environment 之間交互的任務。網絡

好比一個機械臂要拿起一個手機,那麼機械臂周圍的物體包括手機就是環境,機械臂經過外部的好比攝像頭來感知環境,而後機械臂須要輸出動做來實現拿起手機這個任務。再舉玩遊戲的例子,好比咱們玩極品飛車遊戲,咱們只看到屏幕,這就是環境,而後咱們輸出動做(鍵盤操做)來控制車的運動。app

那麼,無論是什麼樣的任務,
都包含了一系列的:dom

  • 動做 Action
  • 觀察 Observation
  • 反饋值 Reward

所謂的Reward就是Agent執行了動做與環境進行交互後,環境會發生變化,變化的好與壞就用Reward來表示。函數

接下來這裏用了Observation觀察一詞而不是環境那是由於Agent不必定能獲得環境的全部信息,好比機械臂上的攝像頭就只能獲得某個特定角度的畫面。所以,只能用Observation來表示Agent獲取的感知信息。oop

只能用 Observation 來表示 Agent 獲取的感知信息post

每一個時間片,Agent 都是根據當前的觀察來肯定下一步的動做。觀察 Observation 的集合就做爲Agent的所處的 狀態 State,所以,狀態 State動做 Action 存在映射關係,也就是一個 state 能夠對應一個 action,或者對應不一樣動做的機率(經常用機率來表示,機率最高的就是最值得執行的動做)。狀態與動做的關係其實就是輸入與輸出的關係,而狀態 State 到動做 Action 的過程就稱之爲一個策略 Policy,通常用 \(\pi\) 表示,也就是須要找到如下關係: 學習

$$a=\pi(s)$$

或者

$$\pi(a|s)$$

其中 a 是 action,s 是 state
第一種是一一對應的表示,第二種是機率的表示。

加強學習的任務就是找到一個最優的策略Policy從而使Reward最多

咱們一開始並不知道最優的策略是什麼,所以每每從隨機的策略開始,使用隨機的策略進行試驗,就能夠獲得一系列的狀態,動做和反饋:

$$\{s_1,a_1,r_1,s_2,a_2,r_2,…s_t,a_t,r_t\}$$

這就是一系列的 樣本 Sample。加強學習的算法就是須要根據這些樣原本改進 Policy,從而使得獲得的樣本中的 Reward 更好。因爲這種讓 Reward 愈來愈好的特性,因此這種算法就叫作加強學習Reinforcement Learning。

 

2. 馬爾科夫決策過程

MDP只須要用一句話就能夠說明白,就是 「將來只取決於當前」,專業點說就是下一步的狀態只取決於當前的狀態,與過去的狀態沒有關係。

一個狀態 \(S_t\) 是Markov當且僅當:

$$P(s_{t+1}|s_t)=P(s_{t+1}|s_t,s_{t-1},…s_1,s_0)$$

P爲機率。簡單的說就是下一個狀態僅取決於當前的狀態和當前的動做。
加強學習的問題均可以模型化爲MDP的問題

所以 MDP 能夠表示爲一個元組 \((S, A, P_{sa}, R)\) :

  • \(S\) :全部可能狀態的集合, \(s \in S\),\(s\) 表示某個特定狀態
  • \(A\) :針對每一個狀態,咱們都要作出動做,這些動做的集合就是 \(A\); \(a \in A\),有限動做 action 集合, \(a\) 表示某個特定動做
  • \(P_{sa}\) :狀態轉換分佈(statetransition distribution),若是咱們在狀態 \(s\) 中採起了動做 \(a\) ,系統會轉移到一個新的狀態,狀態轉換分佈描述了轉移到哪一個狀態的機率分佈。
  • \(R\) :回饋函數(rewardfunction),加強學習的核心概念,描述了動做可以產生的回報。好比 \(R_π(s,a)\) 描述了在狀態 \(s\) 下采用策略 \(\pi\) 所對應的動做 \(a\) 的回報,也叫作當即回報,回饋函數能夠有不一樣的表達形式。
  • \(\pi(s)\rightarrow a\): 策略 policy,根據當前 state 來產生 action,可表現爲 \(a=\pi(s) \) 或 \( \pi(a|s) = P[a|s]\),後者表示某種狀態下執行某個動做的機率

一個基本的 MDP 能夠用 \((S,A,P)\) 來表示, \(S \) 表示狀態, \(A\) 表示動做, \(P \) 表示狀態轉移機率,也就是根據當前的狀態 \(s_t\) 和 \(a_t\) 轉移到 \(s_{t+1}\) 的機率。

若是咱們知道了轉移機率 P,也就是稱爲咱們得到了 模型 Model,有了模型,將來就能夠求解,那麼獲取最優的動做也就有可能,這種經過模型來獲取最優動做的方法也就稱爲 Model-based 的方法。可是現實狀況下,不少問題是很可貴到準確的模型的,所以就有 Model-free 的方法來尋找最優的動做。

 

3. 價值函數

既然一個狀態對應一個動做,或者動做的機率,而有了動做,下一個狀態也就肯定了。這就意味着每一個狀態能夠用一個肯定的值來進行描述。能夠由此判斷一個狀態是好的狀態仍是很差的狀態。

可是在選取最優策略的過程當中,咱們只看當即回報並不能斷定哪一種策略更優,咱們但願的是在採起了策略 \(\pi\) 之後,可使得整個狀態序列的折扣回饋最大。

狀態的好壞其實等價於對將來回報的指望,回報 Return 來表示某個時刻 t 的狀態將具有的回報:

$$G_t = R_{t+1} + \lambda R_{t+2} + … = \sum_{k=0}^\infty\lambda^kR_{t+k+1}$$
  • R 是 Reward 反饋
  • \(λ\) 是 discount factor 折扣因子,通常小於 1,就是說通常當下的反饋是比較重要的,時間越久,影響越小。

其中 \(λ\) 被稱爲折扣因子,在經濟學上的解釋叫作無風險折現率(risk-freeinterest rate),意思是立刻獲得的錢(回饋)比將來獲得錢更有價值。

以上概念就組成了加強學習的完整描述:找到一種策略,使得咱們可以根據狀態 \(s_0, s_1, s_2, …\) 採起策略中對應的動做 \(a_0, a1, a2…,\) 並使 \(G_t\) 的指望值最大化

引出價值函數,對於獲取最優的策略Policy這個目標,咱們就會有兩種方法:

  • 直接優化策略 \(\pi(a|s)\) 或者 \(a = \pi(s)\) 使得回報更高
  • 經過估計 value function 來間接得到優化的策略。道理很簡單,既然我知道每一種狀態的優劣,那麼我就知道我應該怎麼選擇了,而這種選擇就是咱們想要的策略。

可是如今爲了理解DQN,咱們將只關注第二種作法,就是估計value function的作法,由於DQN就是基於value function的算法。

  1. 狀態價值函數 \(V\) :從狀態 \(x_0\) 開始, 全部的動做 \(a\) ,都是執行某個策略 \(π\) 的結果,最後求每一個動做帶來累積獎賞
  2. 動做價值函數 \(Q\) :從狀態 \(x_0\) 開始,先執行動做 \(a_0\) , 而後再執行某個策略 \(π\) ,再求相應的積累獎賞

 

3.1 State-Value function 狀態價值函數

那麼實際上除非整個過程結束,不然顯然咱們沒法獲取全部的 reward 來計算出每一個狀態的Return,所以,再引入一個 概念價值函數 Value Function,用 value function \(v(s)\) 來表示一個狀態將來的潛在價值。

從定義上看,value function 就是回報的指望:

$$v(s) = \mathbb E[G_t|S_t = s]$$

$$V^{\pi}(s) =\mathbb E_{\pi}[ R(s_0, a_0) + γR(s_1, a_1)+ γ^2R(s_2, a_2) + … | s_0= s ]$$

這個函數也被稱爲狀態價值函數(statevalue function),記爲 \(V_{\pi}(s)\)。 由於初始狀態 \(s\) 和策略 \(\pi\) 是咱們給定的,動做 \(a = \pi(s)\) 。

 

3.2 Action-Value function 動做價值函數

咱們更關心在某個狀態下的不一樣動做的價值。顯然。若是知道了每一個動做的價值,那麼就能夠選擇價值最大的一個動做去執行了。

這就是 Action-Value function \(Q^\pi(s,a)\) 。那麼一樣的道理,也是使用 reward 來表示,只是這裏的 reward 和以前的 reward 不同:

這裏是執行完動做 action 以後獲得的 reward,以前 state 對應的 reward 則是多種動做對應的 reward 的指望值。顯然,動做以後的 reward 更容易理解。

那麼,有了上面的定義,動做價值函數就爲以下表示:

$$ Q^{\pi}(s,a) = \mathbb E[R_{t+1}+\lambda R_{t+2} + \lambda ^2R_{t+3} + …|S_t = s,A_t=a]$$

$$
\begin{align}
Q^\pi(s,a) & = \mathbb E[r_{t+1} + \lambda r_{t+2} + \lambda^2r_{t+3} + … |s,a] \\
& = \mathbb E_{s^\prime}[r+\lambda Q^\pi(s^\prime,a^\prime)|s,a]
\end{align}
$$

這裏要說明的是動做價值函數的定義,加了 \(\pi\) ,也就是說是在策略下的動做價值。由於對於每個動做而已,都須要由策略根據當前的狀態生成,所以必須有策略的支撐。而前面的價值函數則不必定依賴於策略。固然,若是定義 \(v^\pi(s)\) 則表示在策略 \(\pi\) 下的價值。

那麼事實上咱們會更多的使用動做價值函數而不是價值函數,由於動做價值函數更直觀,更方便應用於算法當中。

 

4. Bellman 方程

在上文咱們介紹了 Value Function 價值函數,因此爲了解決加強學習的問題,一個顯而易見的作法就是咱們須要估算 Value Function。是的,只要咱們可以計算出價值函數,那麼最優決策也就獲得了。所以,問題就變成了如何計算 Value Function?

$$P^a_{ss\prime} = P(S_{t+1}=s\prime|S_t =s, A_t =a)$$

還記得回報 Result 的基本定義嗎?就是全部 Reward 的累加(帶衰減係數 discount factor)

$$G_t = R_{t+1} + \lambda R_{t+2} + … = \sum_{k=0}^\infty\lambda^kR_{t+k+1}$$

那麼 Value Function 該如何定義?也很簡單,就是指望的回報啊!指望的回報越高,價值顯然也就越大,也就越值得去選擇。用數學來定義就是以下:

$$v(s) = \mathbb E[G_t|S_t = s]$$

$$v_{\pi}=\sum_{a\in A}P(a|s)\left(R^a_s+\lambda\sum_{s\prime \in S}P^a_{ss\prime}v_{\pi}(s\prime)\right)$$

接下來,咱們把上式展開以下:

$$
\begin{align}
v(s) & = \mathbb E[G_t|S_t = s] \\
& = \mathbb E[R_{t+1}+\lambda R_{t+2} + \lambda ^2R_{t+3} + …|S_t = s] \\
& = \mathbb E[R_{t+1}+\lambda (R_{t+2} + \lambda R_{t+3} + …)|S_t = s] \\
& = \mathbb E[R_{t+1} + \lambda G_{t+1}|S_t = s] \\
& = \mathbb E[R_{t+1} + \lambda v(S_{t+1})|S_t = s]
\end{align}
$$

所以,

$$v(s) = \mathbb E[R_{t+1} + \lambda v(S_{t+1})|S_t = s]$$

上面這個公式就是Bellman方程的基本形態。從公式上看,當前狀態的價值和 下一步的價值以及當前的反饋Reward有關。

它代表Value Function是能夠經過迭代來進行計算的!!!

總結一下:

$$v_{\pi}(s) = \mathbb E[R_{t+1} + \lambda v_{\pi}(S_{t+1})|S_t = s]$$

$$ q_{\pi}(s,a) = \mathbb E_{\pi}[R_{t+1} +\lambda q_\pi(S_{t+1},A_{t+1})|S_t =s,A_t = a]$$

 

5. 最優化

動態規劃

先簡單介紹一下動態規劃,由於嚴格來講,值迭代與策略迭代是用來解決動態規劃問題的兩種規劃方法。而強化學習又有另一個暱稱——就是擬動態規劃。說白了強化學習就是模擬動態規劃算法。

用一句話來總結動態規劃就是,對一個複雜問題給出一個通常性的解決辦法。它主要由兩個性質:

  • 最優子結構:最優解法能被分解到多個子問題中
  • 重疊子問題:子問題能重複屢次且解法能被重複利用、

馬爾科夫決策過程(MDP)知足以上兩個性質,因此任何 MDP 均可以用動態規劃來解。動態規劃與強化學習的區別就是動態規劃假設 MDP 模型是全知的(即參數可知) 而 強化學習可使 MDP 未知

MDP須要解決的問題有兩種:

  • 第一種是 prediction,它已知MDP的 \(S,A,P,R,γ\) 以及 policy,目標是算出在每一個狀態下的 value function(值函數其實就是問題的目標,通常都是跟 reward 有關的函數,例如 Atari 小遊戲,通常值函數就是累計的得分的指望。目標通常就是最大化這個值函數。
  • 而第二種是control,它已知 MDP 的 \(S,A,P,R,γ\) 可是 policy 未知(即動做 \(a_t\) 未知),所以它的目標不只是計算出最優的 value function 並且要給出最優的 Policy。

5.1 Optimal value function 最優價值函數

能計算動做價值函數是不夠的,由於咱們須要的是最優策略,如今求解最優策略等價於求解最優的 value function,找到了最優的 value function,天然而然策略也就是找到。(固然,這只是求解最優策略的一種方法,也就是 value-based approach,因爲 DQN 就是 value-based,所以這裏只講這部分,之後咱們會看到還有 policy-based 和 model-based 方法。一個就是直接計算策略函數,一個是估計模型,也就是計算出狀態轉移函數,從而整個MDP過程得解)

首先是最優動做價值函數和通常的動做價值函數的關係:

$$V^*(s,a) = \max_\pi V^\pi(s,a)$$

$$Q^*(s,a) = \max_\pi Q^\pi(s,a)$$

也就是最優的動做價值函數就是全部策略下的動做價值函數的最大值。經過這樣的定義就可使最優的動做價值的惟一性,從而能夠求解整個MDP。

那麼套用上一節獲得的 value function,能夠獲得

$$Q^*(s,a) = \mathbb E_{s^\prime}[r+\lambda \max _{a^\prime}Q^*(s^\prime,a^\prime)|s,a]$$

由於最優的Q值必然爲最大值,因此,等式右側的Q值必然爲使 \(a′\) 取最大的Q值。

下面介紹基於Bellman方程的兩個最基本的算法,策略迭代和值迭代。




5.2 Policy Iteration 策略迭代

策略迭代就是在policy未知的狀況下,根據每次的reward學到最優policy。

對一個具體的 MDP 問題,每次先初始化一個策略,根據這個策略計算值函數 \(v(s)\) , 經過這個re值函數來根據貪心策略更新策略,不斷迭代最終獲得最優策略與最優值函數。總結下來就兩個階段。

  • Policy evaluation :根據每一次的給出策略估計 \(v_π\)
  • Policy improvement:根據 Greedy poilcy 和以前獲得的 \(v_π\) 得到當前策略 \(π′\)

Policy Iteration的目的是經過迭代計算value function 價值函數的方式來使policy收斂到最優。














給一個例子:

下圖是一個叫 Small Gridworld 的例子,左上角和右下角是終點, \(γ=1\) ,移動一步 reward 減小1,起始的 random policy 是朝每一個能走的方向機率相同,先單獨看左邊一列,它表示在第 \(k\) 次迭代每一個 state上value function 的值,這一列始終採用了 random policy,這裏的 value function 就是經過 Bellman Expectation Equation 獲得的,考慮 \(k=2\) 的狀況, \(-1.7 = -1.0 + 2\times (1/3.0)(-1)\),\(-2.0 = -1.0 + 4(1/4.0)\times (-1)\) 。而右邊一列就是在當前的 value function 狀況下經過 greedy 算法找到當前朝哪一個方向走更好。








Policy Iteration 本質上就是直接使用 Bellman 方程而獲得的:



5.3 Value Iteration 價值迭代

Value Iteration 則是使用 Bellman 最優方程獲得:



而後改變成迭代形式:




值迭代就是在已知 policy 和 MDP 模型的狀況下,根據策略得到最優值函數和最優策略。
只不過這是肯定策略,在值函數 \(v_π\) 取得最大值的 \(a_t\) (策略)
經過每次迭代bellman方程得到 \(v_i\) , 知道值函數收斂。圖解以下:




 

6. Q-Value (Quality-Value)

Q Learning的思想徹底根據value iteration獲得。但要明確一點是value iteration每次都對全部的Q值更新一遍,也就是全部的狀態和動做。但事實上在實際狀況下咱們沒辦法遍歷全部的狀態,還有全部的動做,咱們只能獲得有限的系列樣本。所以,只能使用有限的樣本進行操做。那麼,怎麼處理?Q Learning提出了一種更新Q值的辦法:

$$Q(S_{t},A_{t}) \leftarrow Q(S_{t},A_{t})+\alpha({R_{t+1}+\lambda \max _aQ(S_{t+1},a)} - Q(S_t,A_t))$$

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

具體的算法以下:



大體代碼流程以下:

def update():
    # 學習 100 回合
    for episode in range(100):
        # 初始化 state 的觀測值
        observation = env.reset()

        while True:
            # 更新可視化環境
            env.render()

            # RL 大腦根據 state 的觀測值挑選 action
            action = RL.choose_action(str(observation))

            # 探索者在環境中實施這個 action, 並獲得環境返回的下一個 state 觀測值, reward 和 done (是不是掉下地獄或者升上天堂)
            observation_, reward, done = env.step(action)

            # RL 從這個序列 (state, action, reward, state_) 中學習
            RL.learn(str(observation), action, reward, str(observation_))

            # 將下一個 state 的值傳到下一次循環
            observation = observation_

            # 若是掉下地獄或者升上天堂, 這回合就結束了
            if done:
                break

    # 結束遊戲並關閉窗口
    print('game over')
    env.destroy()

if __name__ == "__main__":
    # 定義環境 env 和 RL 方式
    env = Maze()
    RL = QLearningTable(actions=list(range(env.n_actions)))

    # 開始可視化環境 env
    env.after(100, update)
    env.mainloop()
注意:

每一組 (state, action, reward, state_) 爲一次序列



以咱們回到以前的流程, 根據 Q 表的估計, 由於在 s1 中, a2 的值比較大, 經過以前的決策方法, 咱們在 s1 採起了 a2, 併到達 s2, 這時咱們開始更新用於決策的 Q 表, 接着咱們並無在實際中採起任何行爲, 而是再想象本身在 s2 上採起了每種行爲, 分別看看兩種行爲哪個的 Q 值大, 好比說 Q(s2, a2) 的值比 Q(s2, a1) 的大, 因此咱們把大的 Q(s2, a2) 乘上一個衰減值 gamma (好比是0.9) 並加上到達s2時所獲取的獎勵 R (這裏尚未獲取到咱們的棒棒糖, 因此獎勵爲 0), 由於會獲取實實在在的獎勵 R , 咱們將這個做爲我現實中 Q(s1, a2) 的值, 可是咱們以前是根據 Q 表估計 Q(s1, a2) 的值. 因此有了現實和估計值, 咱們就能更新Q(s1, a2) , 根據 估計與現實的差距, 將這個差距乘以一個學習效率 alpha 累加上老的 Q(s1, a2) 的值 變成新的值.

但時刻記住, 咱們雖然用 maxQ(s2) 估算了一下 s2 狀態, 但尚未在 s2 作出任何的行爲, s2 的行爲決策要等到更新完了之後再從新另外作. 這就是 off-policy 的 Q learning 是如何決策和學習優化決策的過程.



$$\text{update = learing_rate * (q_target - q_predict)}$$

$$\text{學習率 * (真實值 - 預測值)}$$

咱們想象 Qlearning 的機器人天生近視眼, \(\gamma= 1\) 時, 機器人有了一副合適的眼鏡, 在 s1 看到的 Q 是將來沒有任何衰變的獎勵, 也就是機器人能清清楚楚地看到以後全部步的所有價值, 可是當 \(\gamma= 0\) , 近視機器人沒了眼鏡, 只能摸到眼前的 reward, 一樣也就只在意最近的大獎勵, 若是 \(\gamma\) 從 0 變到 1, 眼鏡的度數由淺變深, 對遠處的價值看得越清楚, 因此機器人漸漸變得有遠見, 不只僅只看眼前的利益, 也爲本身的將來着想.

 

7. Exploration and Exploitation 探索與利用

在上面的算法中,咱們能夠看到須要使用某一個policy來生成動做,也就是說這個policy不是優化的那個policy,因此Q-Learning算法叫作Off-policy的算法。另外一方面,由於Q-Learning徹底不考慮model模型也就是環境的具體狀況,只考慮看到的環境及reward,所以是model-free的方法。

回到policy的問題,那麼要選擇怎樣的 policy 來生成 action 呢?有兩種作法:

  • 隨機的生成一個動做
  • 根據當前的Q值計算出一個最優的動做,這個 policy \(\pi\) 稱之爲 greedy policy 貪婪策略。也就是 \(\pi(S_{t+1}) = arg\max _aQ(S_{t+1},a)\)

使用隨機的動做就是 exploration,也就是探索未知的動做會產生的效果,有利於更新Q值,得到更好的policy。

而使用 greedy policy 也就是 target policy 則是 exploitation,利用policy,這個相對來講就很差更新出更好的Q值,但能夠獲得更好的測試效果用於判斷算法是否有效。

將二者結合起來就是所謂的 \(\epsilon\ greedy\) 策略, \(\epsilon\) 通常是一個很小的值,做爲選取隨機動做的機率值。能夠更改 \(\epsilon\) 的值從而獲得不一樣的 exploration 和 exploitation 的比例。例如 \(\epsilon = 0.1\) 表示 90% 的時間是選擇最優策略, 10% 的時間來探索.

要注意一點就是 egreedy 的 \(\epsilon\) 是不斷變小的,也就是隨機性不斷變小。怎麼理解呢?就是一開始須要更多的探索,因此動做偏隨機,慢慢的咱們須要動做可以有效,所以減小隨機。也就是愈來愈貪婪。
例如:
INITIAL_EPSILON = 0.5 # starting value of epsilon
FINAL_EPSILON = 0.01 # final value of epsilon

這裏須要說明的一點是使用 \(\epsilon-greedy\) 策略是一種極其簡單粗暴的方法,對於一些複雜的任務採用這種方法來探索未知空間是不可取的。所以,最近有愈來愈多的方法來改進這種探索機制。

 

8. 詳解Q-Learning

8.1 Value Function Approximation 價值函數近似

在簡單分析中,咱們使用表格來表示Q(s,a),可是這個在現實的不少問題上是幾乎不可行的,由於狀態實在是太多。使用表格的方式根本存不下。

咱們有必要對狀態的維度進行壓縮,解決辦法就是 價值函數近似 Value Function Approximation

就是用一個函數來表示Q(s,a),即:

$$Q(s,a) = f(s,a)$$

f能夠是任意類型的函數,好比線性函數:

$$Q(s,a) = w_1s + w_2a + b$$
其中 \(w_1,w_2,b\) 是函數 \(f\) 的參數。

經過函數表示,咱們就能夠無所謂 \(s\) 究竟是多大的維度,反正最後都經過矩陣運算降維輸出爲單值的 \(Q\) 。這就是價值函數近似的基本思路。

若是咱們就用 \(w\) 來統一表示函數f的參數,那麼就有

$$Q(s,a) = f(s,a,w)$$

爲何叫近似,由於咱們並不知道 \(Q\) 值的實際分佈狀況,本質上就是用一個函數來近似 \(Q\) 值的分佈,因此,也能夠說是

$$Q(s,a)\approx f(s,a,w)$$

 

8.2 Q值神經網絡化!

用一個深度神經網絡來表示這個函數 \(f\),即咱們能夠將狀態和動做當成神經網絡的輸入, 而後通過神經網絡分析後獲得動做的 Q 值, 這樣咱們就不必在表格中記錄 Q 值, 而是直接使用神經網絡生成 Q 值.還有一種形式的是這樣, 咱們也能只輸入狀態值, 輸出全部的動做值, 而後按照 Q learning 的原則, 直接選擇擁有最大值的動做當作下一步要作的動做。通常使用第二種形式。

以DQN爲例,輸入是通過處理的4個連續的84x84圖像,而後通過兩個卷積層,兩個全鏈接層,最後輸出包含每個動做Q值的向量。

用神經網絡來表示Q值很是簡單,Q值也就是變成用Q網絡(Q-Network)來表示。接下來就到了不少人都會困惑的問題,那就是怎麼訓練Q網絡???

咱們知道,神經網絡的訓練是一個最優化問題,最優化一個損失函數loss function,也就是標籤和網絡輸出的誤差,目標是讓損失函數最小化。爲此,咱們須要有樣本,巨量的有標籤數據,而後經過反向傳播使用梯度降低的方法來更新神經網絡的參數。

因此,要訓練Q網絡,咱們要可以爲Q網絡提供有標籤的樣本。

因此,問題變成:

如何爲 Q 網絡提供有標籤的樣本?
答案就是利用 Q-Learning 算法。

回想一下 Q-Learning 算法,
$$Q(S_{t},A_{t}) \leftarrow Q(S_{t},A_{t})+\alpha({R_{t+1}+\lambda \max _aQ(S_{t+1},a)} - Q(S_t,A_t))$$

Q值的更新依靠什麼?依靠的是利用 Reward 和 Q 計算出來的目標Q值:

$$\text{Target-Q : }\ \ R_{t+1}+\lambda \max _aQ(S_{t+1},a)$$

所以,咱們把目標Q值做爲標籤不就完了?咱們的目標不就是讓Q值趨近於目標Q值嗎?
所以,Q網絡訓練的損失函數就是:



\(s^`,a^`\) 即下一個狀態和動做

既然肯定了損失函數,也就是cost,肯定了獲取樣本的方式。那麼DQN的整個算法也就成型了!接下來就是具體如何訓練的問題了!



前邊提到,每一組 (state, action, reward, state_) 爲一次序列:

  • state (observation) 爲目前狀態,傳遞給 q-eval net 獲得預計值 (即輸入狀態值, 輸出全部的動做值);
  • state_ 爲下一步狀態,傳遞給 q-target net 獲得目標值,以後能夠獲得 \(\max _aQ(S_{t+1},a)\) ,在以後獲得 \(R_{t+1}+\lambda \max _aQ(S_{t+1},a)\)

最終的 \(loss\) 爲:

self.loss = tf.reduce_mean(tf.squared_difference(self.q_target, self.q_eval))

再次注意,q-eval net 和 q-target net 網絡結構徹底同樣,只不過參數更新不一樣!(即 Fixed Q-targets 方法)








最基本的DQN,也就是NIPS 13版本的DQN:



那麼上面的算法看起來那麼長,其實就是反覆試驗,而後存儲數據。接下來數據存到必定程度,就每次隨機採用數據,進行梯度降低!

也就是在DQN中加強學習 Q-Learning 算法和深度學習的 SGD 訓練是同步進行的!
經過 Q-Learning 獲取無限量的訓練樣本,而後對神經網絡進行訓練。

總體代碼結構大體以下:

def run_maze():
    step = 0    # 用來控制何時學習
    for episode in range(300):
        # 初始化環境
        observation = env.reset()

        while True:
            # 刷新環境
            env.render()

            # DQN 根據觀測值選擇行爲
            action = RL.choose_action(observation)

            # 環境根據行爲給出下一個 state, reward, 是否終止
            observation_, reward, done = env.step(action)

            # DQN 存儲記憶
            RL.store_transition(observation, action, reward, observation_)

            # 控制學習起始時間和頻率 (先累積一些記憶再開始學習)
            if (step > 200) and (step % 5 == 0):
                RL.learn()

            # 將下一個 state_ 變爲 下次循環的 state
            observation = observation_

            # 若是終止, 就跳出循環
            if done:
                break
            step += 1   # 總步數

    # end of game
    print('game over')
    env.destroy()


if __name__ == "__main__":
    env = Maze()
    RL = DeepQNetwork(env.n_actions, env.n_features,
                      learning_rate=0.01,
                      reward_decay=0.9,
                      e_greedy=0.9,
                      replace_target_iter=200,  # 每 200 步替換一次 target_net 的參數
                      memory_size=2000, # 記憶上限
                      # output_graph=True   # 是否輸出 tensorboard 文件
                      )
    env.after(100, run_maze)
    env.mainloop()
    RL.plot_cost()  # 觀看神經網絡的偏差曲線

 

8.3 Experience Replay 經驗回放

Q learning 是一種 off-policy 離線學習法, 它能學習當前經歷着的, 也能學習過去經歷過的, 甚至是學習別人的經歷. 因此每次 DQN 更新的時候, 咱們均可以隨機抽取一些以前的經歷進行學習. 隨機抽取這種作法打亂了經歷之間的相關性, 也使得神經網絡更新更有效率。

其將系統探索環境獲得的數據儲存起來,而後隨機採樣樣本更新深度神經網絡的參數(有了一個記憶庫以後再開始學習)。



Experience Replay 的動機是:

  • 深度神經網絡做爲有監督學習模型,要求數據知足獨立同分布,
  • 但 Q Learning 算法獲得的樣本先後是有關係的。爲了打破數據之間的關聯性,Experience Replay 方法經過存儲-採樣的方法將這個關聯性打破了。

之因此加入 experience replay 是由於樣本是從遊戲中的連續幀得到的,這與簡單的 reinforcement learning 問題(好比maze)相比,樣本的關聯性大了不少,若是沒有 experience replay,算法在連續一段時間內基本朝着同一個方向作 gradient descent,那麼一樣的步長下這樣直接計算 gradient 就有可能不收斂。所以 experience replay 是從一個 memory pool 中隨機選取了一些 experience,而後再求梯度,從而避免了這個問題。

原文的實驗中指出mini batch是32,而replay memory存了最近的1000000幀。

 

8.4 Fixed Q-targets

Fixed Q-targets 也是一種打亂相關性的機理, 若是使用 fixed Q-targets, 咱們就會在 DQN 中使用到兩個結構徹底相同但參數不一樣的神經網絡 (有時差), 預測 Q 估計 的神經網絡 (evaluate net) 具有最新的參數, 而預測 Q 現實 的神經網絡 (target net) 使用的參數則是好久之前的

例如一開始有兩個徹底同樣的網絡,一個進行訓練,另外一個不訓練,到了訓練10000次後,把訓練過的網絡參數徹底複製給凍結的網絡,以後還是一個訓練,持續更新參數,一個凍結,每10000次才更新一次。

target_net 用於預測 q_target 目標值, 他不會及時更新參數.

eval_net 用於預測 q_eval 估計值, 這個神經網絡擁有最新的神經網絡參數





 

8.5 總結

在 Q-Learning 算法中,計算經驗得分的公式以下:

$$\text{Q(state, action) = Q(state, action) + }\alpha\text{ (R(state, action) + }\gamma \text{ Max[Q(next state, all actions)] - Q(state, action))}$$

當 \(\alpha\) 的值是 \(1\) 時,公式以下:

$$\text{Q(state, action) = R(state, action) +} \gamma\text{ Max[Q(next state, all actions)]}$$

  • state: 表示 Agent 當前狀態。
  • action: 表示 Agent 在當前狀態下要作的行爲。
  • next state: 表示 Agent 在 state 狀態下執行了 action 行爲後達到的新的狀態。
  • Q(state, action): 表示 Agent 在 state 狀態下執行了 action 行爲後學習到的經驗,也就是經驗分數。
  • R(state, action): 表示 Agent 在 state 狀態下作 action 動做後獲得的即時獎勵分數。
  • Max[Q(next state, all actions)]: 表示 Agent 在 next state 狀態下,自個人經驗中,最有價值的行爲的經驗分數。
  • Gamma: \(\gamma\) ,表示折損率,也就是將來的經驗對當前狀態執行 action 的重要程度。



算法流程:

Agent 經過經驗去學習。Agent將會從一個狀態到另外一個狀態這樣去探索,直到它到達目標狀態。咱們稱每一次這樣的探索爲一個場景(episode)。

每一個場景就是 Agent 從起始狀態到達目標狀態的過程。每次 Agent 到達了目標狀態,程序就會進入到下一個場景中。

  1. 初始化 Q 矩陣,並將初始值設置成 0
  2. 設置好參數 γ 和得分矩陣 R
  3. 循環遍歷場景(episode):

    1. 隨機初始化一個狀態 s
    2. 若是未達到目標狀態,則循環執行如下幾步:

      1. 在當前狀態 s 下,隨機選擇一個行爲 a
      2. 執行行爲 a 獲得下一個狀態 s`
      3. 使用 \(\text{Q(state, action) = R(state, action) +} \gamma\text{ Max[Q(next state, all actions)]}\) 公式計算 \(\text{Q(state, action)}\)
      4. 將當前狀態 s 更新爲 s`

參考

  1. DQN 從入門到放棄
  2. 經驗回放(Experience replay)
  3. 強化學習系列之九:Deep Q Network (DQN)
  4. 莫煩 PYTHON 強化學習 Reinforcement Learning