原文地址:https://www.hhyz.me/2018/08/05/2018-08-05-RL/
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 從此成為深度學習領域的前沿研究方向。
智能體 Agent 來表示一個具備行為能力的物體,比如機器人,無人車,人等等。
那么增強學習考慮的問題就是智能體Agent和 環境 Environment 之間交互的任務。
比如一個機械臂要拿起一個手機,那么機械臂周圍的物體包括手機就是環境,機械臂通過外部的比如攝像頭來感知環境,然后機械臂需要輸出動作來實現拿起手機這個任務。再舉玩游戲的例子,比如我們玩極品飛車游戲,我們只看到屏幕,這就是環境,然后我們輸出動作(鍵盤操作)來控制車的運動。
那么,不管是什么樣的任務,
都包含了一系列的:
- 動作 Action
- 觀察 Observation
- 反饋值 Reward
所謂的Reward就是Agent執行了動作與環境進行交互后,環境會發生變化,變化的好與壞就用Reward來表示。
接下來這里用了Observation觀察一詞而不是環境那是因為Agent不一定能得到環境的所有信息,比如機械臂上的攝像頭就只能得到某個特定角度的畫面。因此,只能用Observation來表示Agent獲取的感知信息。
只能用 Observation 來表示 Agent 獲取的感知信息
每個時間片,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的算法。
- 狀態價值函數 \(V\) :從狀態 \(x_0\) 開始, 所有的動作 \(a\) ,都是執行某個策略 \(π\) 的結果,最后求每個動作帶來累積獎賞
- 動作價值函數 \(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網絡訓練的損失函數就是:

既然確定了損失函數,也就是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 到達了目標狀態,程序就會進入到下一個場景中。
- 初始化 Q 矩陣,並將初始值設置成 0
- 設置好參數 γ 和得分矩陣 R
-
循環遍歷場景(episode):
- 隨機初始化一個狀態 s
-
如果未達到目標狀態,則循環執行以下幾步:
- 在當前狀態 s 下,隨機選擇一個行為 a
- 執行行為 a 得到下一個狀態 s`
- 使用 \(\text{Q(state, action) = R(state, action) +} \gamma\text{ Max[Q(next state, all actions)]}\) 公式計算 \(\text{Q(state, action)}\)
- 將當前狀態 s 更新為 s`
參考