深度強化學習理論速成 (1)

文章首發于 huangyz.name, 純屬原創,轉載請注明來源。
歡迎大家 Follow Github: huangyz0918

本文目錄

  • 前言
  • DRL 中的 Policy Gradient
  • 更精準的 Reward Function
    • 改進的 R_{\theta}(\tau)
    • 添加 Baseline
  • On-Policy 到 Off-Policy
    • On-Policy 學習方式
    • Important Sampling
    • Proximal Policy Optimization (PPO)
    • Trust Region Policy Optimization (TRPO)
    • PPO2
  • Q-Learning
    • Monte-Carlo (MC) 和 Temporal-difference (TD)
    • State-action Value Function Q^{\pi}(s, a)
    • Target Network
    • Exploitation 和 Exploration
    • Reply Buffer

前言

最近因為項目和論文的關系需要用到一些 Deep Reinforcement Learning 的知識,于是快速把 DRL 的一些基本算法和思想過了一遍(參考了李宏毅教授的強化學習課程)。之前趕時間寥寥草草地寫了七八頁紙,現在因為 COVID-19 導致各種 DDL 推遲了以后便有了一些空閑時間,覺得還是記錄在博客比較好。個人覺得 RL 這個東西思想是很精妙的,但如果只是要了解一些比較粗淺的東西,學習成本很低,完全可以幾天內掌握個大概。

由于我比較懶,這篇博客主要是寫給自己看的,可能有些地方不會解釋得太清楚 : )

DRL 中的 Policy Gradient

強化學習實際上是一個機器與環境不斷互動和學習的過程,其中包括幾個重要的組成部分:

  • Agent: 與環境互動的智能體
  • Environment: 與智能體交互的環境
  • Reward Function: 環境給予智能體反饋的方式

舉個例子,比如使用強化學習玩游戲,那么理論上的一個流程就是:

  • 初始化一個 agent
  • agent 接收環境所給的第一個界面,也是輸入第一個 state: s_1
  • agent 給出一個對應的反應:a_1
  • 環境接收 a_1 給出對應的 s_2

重復上述流程直到游戲結束。

我們認為從游戲開始到游戲結束是一個 episode,用 \tau 表示。然后在這個玩游戲的過程中,舉個例子:假設這個游戲是我們熟知的雷電(飛機大戰游戲),用戶需要操作飛機左右移動以避開飛來的隕石等障礙,同時又要主動出擊才能獲得比較高的分數。我方戰斗機便可以看作強化學習中的 agent,周圍的隕石,敵機等無法控制(含有隨機性)的東西就是與我們 agent 交互的環境。

為了讓我們的 agent 在玩游戲的過程中逐漸掌握游戲的技巧,我們需要設計 reward function, 也就是設計一個反饋機制。其實游戲本身是含有這樣的反饋機制的,比如擊落一架敵方戰斗機可以獲得多少分,吃到補給可以獲得多少分,被子彈擊中扣多少分這樣。agent 做出的每一步,或多或少都在改變著最終的游戲結果。

我們把整個 episode 最終獲得的分數用 reward function 表示為:

R(\tau) = \{ r_1 + r_2 + r_3 + ... + r_n \}

深度強化學習,之所以稱為深度強化學習,是因為我們的 agent 實際上是一個 DNN,給定某個 state 輸入,針對這個輸入輸出對應的 action,學習的過程實際上就是在 update 這個 DNN 的參數,使得最終一個 episode 下來全局的 reward function R(\tau) 可以達到最大值。

其中,我們把一個 agent 進行玩游戲的策略稱為一個 policy, 用 \theta 表示,不同的 \theta 表示不同的游戲策略(不同的 agent), 我們要做的就是求給定 \thetaR_{\theta} 的最大值, 這里我們可以用梯度增加的方式計算:

\theta \leftarrow \theta + \eta \nabla R

為了準確更新神經網絡的參數,我們需要盡可能多的獲取一些游戲數據,在一個相同的 policy 下,我們可能會進行非常多場游戲,所以計算多場游戲的平均 reward 就是:

\overline{R_{\theta}} = \sum_{\tau} R(\tau) p_{\theta} (\tau)

\theta 求梯度:

\begin{align} \nabla \overline{R_{\theta}} & = \sum_{\tau} R(\tau) \nabla p_{\theta} (\tau) \\ & = \sum_{\tau} R(\tau) p_{\theta}(\tau) \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} \\ & = \sum_{\tau} R(\tau) p_{\theta}(\tau) \nabla \log p_{\theta}(\tau) \\ & = \mathbb{E}_{\tau \sim p_{\theta}(\tau)} \left [ R(\tau) \nabla \log p_{\theta}(\tau) \right ] \\ & \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} R(\tau^{n}) \nabla \log p_{\theta}(a_t^n | s_t^n) \end{align}

為了方便實現最終將式子寫成了上述形式,其中 R(\tau^{n}) 是第 n 個 episode 的 reward 總和,T_n 代表的意思是在第 n 個 episode 里面,總共有 T_n 個 step (一個 step 定義為給定一個 state s, agent 做出一個反應 a)。

這個式子是非常好理解的,為了讓最終的 policy gradient 有最大值,當某個 step 發生的那個 \tau 中有相對較大的 R(\tau),我們就要增加其出現的概率,反之,如果 reward 的值太小我們就要減小這個操作所出現的概率。

上述公式中用了一個近似,在給定分布求期望的過程中:

\mathbb{E}_{x \sim p} \left [ f(x) \right ] \approx \frac{1}{N} \sum_{i=1}^{N} f(x^i)

這里的 N 越大,實際上相當于在 p(x) 分布上 sample 到的值越多,結果也就越接近。

另外一個小技巧是:

\nabla f(x) = f(x) \nabla \log f(x)

我們可以通過分子分母同時乘上一個 p_{\theta}(\tau)p_{\theta}(\tau) 中梯度運算中拿出來:

\sum_{\tau} R(\tau) p_{\theta}(\tau) \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} = \sum_{\tau} R(\tau) p_{\theta}(\tau) \nabla \log p_{\theta}(\tau)

更精準的 Reward Function

改進的 R_{\theta}(\tau)

在上述公式中,實際上存在著一些問題,其中最大的問題就是:該如何定義我們的 reward function R_{\theta}(\tau)?如果僅僅是按照游戲的規則來,R_{\theta}(\tau) 是游戲中的每一步所產生的 reward 在整場游戲中的累加,在式子中:

\nabla \overline{R_{\theta}} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} R(\tau^{n}) \nabla \log p_{\theta}(a_t^n | s_t^n)

有些 action 是好的,有的是不好的,但是所有的 action 的概率前面都會被乘上同樣的 weight: R(\tau^{n}),顯然是不合理的。

那么如果我在給定某個 s_t 后 agent 輸出了 a_t ,實際上它并不會影響到 a_t 之前的那些情況,在 s_t 發生之前的 reward 實際上是和 a_t 無關的。

舉個例子,一個簡單的游戲我們玩了兩場:

State s_a s_b s_c
Action a_1 a_2 a_3
Reward +10 +0 -6

R_1 = +4

State s_a s_b s_c
Action a_2 a_2 a_3
Reward -5 +0 -6

R_2 = -11

那么 (s_b, a_2) 在第一種游戲情況上就會被增加出現的概率 (乘上 4),而在第二種情況下同樣的場景和操作就會被降低概率 (乘上 -11),這是不科學的,第二場游戲之所以不好,是因為在 (s_b, a_2) 之前的 (s_a, a_2) 產生了 -5 的 reward,這個實際上和 (s_b, a_2) 是無關的。但是 (s_b, a_2) 之后的是和它有關的,(s_c, a_3) 可能正是要發生在 (s_b, a_2) 之后才會帶來 -6 的 reward。

所以我們可以使用某個特定的 a_t 之后的所有 reward 總和來代表 a_t 的 reward,而不是全部 reward 的總和。為了表示計算 reward 的方法,我們引入 advantage function: A^{\theta}(s_t, a_t),在此之前 A^{\theta}(s_t, a_t) = R(\tau^{n})

我們把改進的 reward 計算式 A^{\theta}(s_t, a_t) = \sum_{t'=t}^{T_n} r_{t'}^{n} 代入

\nabla \overline{R_{\theta}} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} A^{\theta}(s_t, a_t) \nabla \log p_{\theta}(a_t^n | s_t^n)

得到

\nabla \overline{R_{\theta}} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} \sum_{t'=t}^{T_n} r_{t'}^{n} \nabla \log p_{\theta}(a_t^n | s_t^n)

另外,我們可以給 \sum_{t'=t}^{T_n} r_{t'}^{n} 加上一個影響力衰弱參數 \gamma,因為時間拖得越長,越前面發生的事件對后來的影響就會越小:

A^{\theta}(s_t, a_t) = \sum_{t'=t}^{T_n} \gamma^{t'-t} \cdot r_{t'}^{n} , (0 < \gamma < 1)

添加 Baseline

有些游戲中,游戲者無論采取何種 action,reward 可能的情況全都是正的,這個從理論上來說并不會出現問題。但是在 sample 數據的時候,如果 sample 的數量不夠多,沒被 sample 到的 action 保持不變,但是被 sample 到的所有 action 都會相應的增大,在 normalize 之后未被 sample 到的 action 對應的概率就減小了,但是我們能說沒被 sample 到的 action 就不是好的 action 嗎?

很顯然不能,所以這里又有一個小的 tip:減去一個 baseline 使得 A^{\theta}(s_t, a_t) 的值有正有負 ,一般來說這個 baseline 就是所有 reward 的期望:

b = \mathbb{E}\left [ R(\tau) \right ]

代入得:

\begin{align} \nabla \overline{R_{\theta}} & \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} \left [ R(\tau) - b \right ] \nabla \log p_{\theta}(a_t^n | s_t^n) \\ & = \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} \left [ R(\tau) - \mathbb{E}\left [ R(\tau) \right ] \right ] \nabla \log p_{\theta}(a_t^n | s_t^n) \end{align}

結合上面的優化方法:

\nabla \overline{R_{\theta}} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_n} \sum_{t'=t}^{T_n} (\gamma^{t'-t} \cdot r_{t'}^{n} - \mathbb{E}\left [ R(\tau) \right ]) \nabla \log p_{\theta}(a_t^n | s_t^n)

On-Policy 到 Off-Policy

On-Policy 學習方式

理解了上述原理,之后要做的無非就是更新神經網絡,on-policy 的意思就是:與環境交互學習的 agent 和被動更新的 agent 是同一個。具體的流程可以表示為:

  • agent 先初始化,并且與環境做互動
  • 在互動的過程中我們 sample 一定數量 (m) 的數據
  • 在積累了 m 個 \tau 的數據以后,我們用這么多數據去 update agent policy
  • 把用過的數據扔掉,重新與環境繼續互動生成數據 (因為 policy 更新了,舊的數據沒有參考價值)
  • 繼續用新的數據 update agent policy
  • ...

顯而易見,on-policy 的方式是存在一定問題的,比如進行飛機大戰的游戲,輸入 DNN 的 state 是用 image 表示的,訓練 -> sample -> 訓練 這樣的方式非常耗時,并且一旦原有的 policy 更新了以后,

\nabla \overline{R_{\theta}} = \mathbb{E}_{\tau \sim p_{\theta}(\tau)} \left [ R(\tau) \nabla \log p_{\theta}(\tau) \right ]

上述梯度中分布 p_{\theta}(\tau) 就變了,之前在老的 \tau \sim p_{\theta}(\tau) 上面采樣的數據就沒用了,這意味著每次更新 policy 會浪費大量的數據,并且需要大量的時間進行 sampling。

所以針對這種 on-policy 研究人員希望能夠在不影響 agent 與環境互動的前提下持續地對我們需要的 agent 進行更新,于是便有了 off-policy,這里主要講 PPO/TRPO 和 PPO2 這幾種方法。

Important Sampling

Important Sampling,它并不是 RL 里面獨有的方法,簡要來說就為了實現線下學習我們需要用一個不同的分布 q(x) 去估計我們所需要的分布 p(x)。在 off-policy 中體現為:我們想用另外一個 {\theta}' 去跟環境做互動,使用 {\theta}' 收集到的數據去訓練我們想要的 \theta,這個流程就像你讓一個小朋友去看另外一個小朋友玩游戲,并從中學到游戲的方法。

通過這種方法 {\theta}' 與環境互動獲取到的數據可以被使用多次,并且不需要考慮 \theta 變化時數據就會失效的問題。

具體來說,important sampling 中用一個分布 q(x) 來估計另一個分布 p(x) 可以這樣表示:

\begin{align} \mathbb{E}_{x \sim p} \left [ f(x) \right ] & \approx \frac{1}{N} \sum_{i=1}^{N} f(x^i) \\ & = \int f(x)p(x) dx = \int \frac{f(x)p(x)}{q(x)} \cdot q(x) \\ & = \mathbb{E}_{x \sim q} \left [ \frac{f(x)p(x)}{q(x)} \right ] \\ \end{align}

Proximal Policy Optimization (PPO)

將這種 important sampling 的方式應用到 policy gradient 上面,我們可以得到:

\begin{align} \nabla \overline{R_{\theta}} & = \mathbb{E}_{\tau \sim p_{\theta}(\tau)} \left [ R(\tau) \nabla \log p_{\theta}(\tau) \right ] \\ & = \mathbb{E}_{\tau \sim p_{\theta'}(\tau)} \left [ \frac{p_{\theta}(\tau)}{p_{\theta'}(\tau)} R(\tau) \nabla \log p_{\theta}(\tau) \right ] \\ & \rightarrow \mathbb{E}_{(s_t, a_t) \sim \pi_{\theta}} \left [ A^{\theta}(s_t, a_t) \nabla \log p_{\theta}(\tau) \right ] \\ & = \mathbb{E}_{(s_t, a_t) \sim \pi_{\theta'}} \left [ \frac{p_{\theta}(s_t, a_t)}{p_{\theta'}(s_t, a_t)} A^{\theta}(s_t, a_t) \nabla \log p_{\theta}(\tau) \right ] \\ & = \mathbb{E}_{(s_t, a_t) \sim \pi_{\theta'}} \left [ \frac{p_{\theta}(a_t | s_t)p_{\theta}(s_t)}{p_{\theta'}(a_t | s_t)p_{\theta'}(s_t)} A^{\theta}(s_t, a_t) \nabla \log p_{\theta}(\tau) \right ] \\ \end{align}

假設 p_{\theta'}(s_t) \approx p_{\theta}(s_t),那么上面的式子可以寫成:

\mathbb{E}_{(s_t, a_t) \sim \pi_{\theta'}} \left [ \frac{p_{\theta}(a_t | s_t)}{p_{\theta'}(a_t | s_t)} A^{\theta}(s_t, a_t) \nabla \log p_{\theta}(\tau) \right ]

\pi_{\theta'} 去估計 \pi_{\theta} 的分布,實際上就是用 agent \pi' 去和環境互動,根據其互動的數據去更新我們的 policy。這里 important sampling 其實有一個問題,雖然兩個分布的 mean 是一樣的,但是他們的方差是不同的,在 sample 數量不夠多的話,\pi_{\theta'} 的方差就會變得很大,所以采樣的時候我們應該盡可能的保持多的樣本數據來保證準確率,同時要保證兩個分布不能差別太大。

借助之前的公式 \nabla f(x) = f(x) \nabla \log f(x),我們可以用 gradient 去反推原來的 objective function,得到函數 J^{\theta'}(\theta)

J^{\theta'}(\theta) = \mathbb{E}_{(s_t, a_t) \sim \pi_{\theta'}} \left [ \frac{p_{\theta}(a_t | s_t)}{p_{\theta'}(a_t | s_t)} A^{\theta}(s_t, a_t) \right ]

J^{\theta'}(\theta) 非常的直觀:我們用 \theta' 去做 demonstration 從而優化我們想要的參數 \theta,但是由于這個 objective function J^{\theta'}(\theta) 牽扯到 important sampling,為了保證 important sampling 的效果,我們要讓兩個分布盡可能的相似,所以 PPO 就應運而生了: 在做訓練的時候多加一個 constrain: \beta KL(\theta, \theta') (\beta 為常數),這一項代表著兩個分布 \theta, \theta' 之間的 KL 距離,減去這一項我們可以得到:

J_{PPO}^{\theta'}(\theta) = J^{\theta'}(\theta) - \beta KL(\theta, \theta')

其中如果 KL(\theta, \theta') 越大 (即 \theta\theta' 越不相似),最終的 J_{PPO}^{\theta'}(\theta) 就會越小。通過優化這個式子求其最大值,我們可以達到更好的強化學習效果。

要注意的是,這里的 KL(\theta, \theta') 并不是參數上的距離,而是這些 action 之間的相似度。總的來說,PPO 的算法可以描述為:

  • 初始化一個 policy \theta^{0}
  • 在每次迭代過程中:
    • 使用 \theta' 去與環境交互,收集數據 \{ s_t, a_t \} 并且計算 A^{\theta'}(s_t, a_t)
    • 找到 \theta 去優化 J_{PPO}(\theta), 其中 J_{PPO}^{\theta'}(\theta) = J^{\theta'}(\theta) - \beta KL(\theta, \theta')

那么對于 PPO 約束條件 \beta KL(\theta, \theta') 中的 \beta 要怎么設定呢?實際上可以很直觀地設定一個最大值和最小值,如果兩個分布的 KL 距離已經到了最大值,然后整個式子還是沒有起到明顯的約束作用,就增大 \beta。同理,如果距離小到了最小值,整個式子的值仍然偏大,這時候就需要動態減小 \beta 的值:

  • 如果 KL(\theta', \theta) > KL_{max}, 增加 \beta
  • 如果 KL(\theta', \theta) < KL_{min}, 減小 \beta

Trust Region Policy Optimization (TRPO)

另外一種方法叫做 TRPO: Trust Region Policy Optimization, 它和 PPO 唯一不一樣的地方是這個 constrain 設計的方式有點不一樣,它將約束條件放到了式子外面:

J_{TRPO}^{\theta'}(\theta) = \mathbb{E}_{(s_t, a_t) \sim \pi_{\theta'}} \left [ \frac{p_{\theta}(a_t | s_t)}{p_{\theta'}(a_t | s_t)} A^{\theta}(s_t, a_t) \right ], KL(\theta, \theta') < \delta

但是實際上實現 TRPO 的時候,式子外面的約束條件是非常難處理的,一般不推薦 (因為 PPO 和 TRPO 效果差不多,但是實現起來簡單很多)。

PPO2

PPO2 算法是在 PPO 算法上衍生的另外一種算法,本質也是為了使得兩個分布 \theta, \theta' 的差距不要太大,數學表示為:

J_{PPO2}^{\theta^k}(\theta) \approx \sum_{(s_t, a_t)} min \left [ \frac{p_{\theta}(a_t | s_t)}{p_{\theta^k}(a_t | s_t)} A^{\theta^k}(s_t, a_t), clip(\frac{p_{\theta}(a_t | s_t)}{p_{\theta^k}(a_t | s_t)}, 1 - \varepsilon, 1 + \varepsilon) A^{\theta^k}(s_t, a_t) \right ]

clip \left [f(x), 1 - \varepsilon, 1 + \varepsilon \right ] 的意思是說:

clip \left [f(x), 1 - \varepsilon, 1 + \varepsilon \right ] = \begin{cases} f(x) & 1 - \varepsilon < f(x) < 1 + \varepsilon \\ 1 - \varepsilon & f(x) < 1 - \varepsilon \\ 1 + \varepsilon & f(x) > 1 + \varepsilon \end{cases}

這樣就可以動態地將 f(x) 的值限定在 1 - \varepsilon1 + \varepsilon 之間,達到兩個分布不會相差太多的效果。而取最小值是因為,當 A^{\theta^k}(s_t, a_t) > 0 時,我們希望 objective function 越大越好,但是一旦大過了 1 + \varepsilon,這個式子就不再有 benefit 了,因為不滿足兩個分布差別不要太大的這個約束條件,同理當 A^{\theta^k}(s_t, a_t) < 0 的時候也是一樣。

Q-Learning

除了直接學習一個 policy,我們還可以從另外一個角度出發,去學習一個 critic,這也被稱作是 value-based 的學習方法。Critic 就是一個評價者,去客觀地評價你這個 action 做得好還是不好。

這里需要引入一個 state value function V^{\pi}(s),代表著在 state s 之后所有 reward 累加的期望值。V^{\pi}(s) 越大,意味著給定 state s 開始到游戲結束,這個 agent \pi 可能獲得的 reward 就越多(前景越光明),在某種意義上來說,這就是一個 critic,但是目前的 V^{\pi}(s) 只是一個 scalar function,不能夠給出指導性的意見。

Monte-Carlo (MC) 和 Temporal-difference (TD)

那怎么去估計這樣一個 V^{\pi}(s) 呢?這里一般用兩種方法,MC 和 TD,其中各有優劣。

MC 的方法很簡單,一般來說 MC 會訓練一個 DNN,給定一個 state s_a 輸入,這個網絡返回預測的從 s_a 往后所有 reward 的總和 V^{\pi}(s_a),我們希望它與實際的總和 G_a 越接近越好。

簡要表示就是這個樣子:

s_a \rightarrow network \left [ V^{\pi} \right ] \rightarrow V^{\pi}(s_a) \leftrightarrow G_a

另外一種方法是 TD,和 MC 有所不同的是,TD-based 的方法不用計算積累的所有 reward 和,意味著你必須走完整個流程直到結束才能夠完成 MC-based 的估測,有的游戲非常耗時,使用 MC-based 的方法可能在短時間是無法獲得多少數據的。

TD-based 的方法具體來說是針對每個 step,我們可以得到 ...s_t, a_t, r_t, s_{t + 1}...,那么從這個式子可以看出,對應的 V^{\pi}(s_t) 實際上是滿足:

V^{\pi}(s_t) = V^{\pi}(s_{t + 1}) + r_t

具體的實現我們可以構造兩個一樣的網絡 V^{\pi},分別接收 s_ts_{t+1},之后我們將輸出作差 V^{\pi}(s_{t}) - V^{\pi}(s_{t + 1}) \approx r_t,盡量使得差值和給定的訓練數據 r_t 保持一致。

這樣我們就不需要整場游戲的所有 reward 和進行訓練,能夠通過差分的方式,利用前后步之間的 reward 差估測出 V^{\pi},這就是 TD 的方法。

MC 和 TD 各有優劣,MC 最大的問題就是,因為 G_a 是有隨機性的,這種隨機性來自環境本身和 agent 之后所做的動作的不同,一旦累加以后 G_a 會產生很大的方差,而這個問題在 TD 中并不明顯,在 TD 中具有隨機性的是前后兩步之間的 reward r,而并不是 r 的累加。

但是在 TD 中也存在一個問題,V^{\pi}(s_t) = V^{\pi}(s_{t + 1}) + r_tV^{\pi}(s_{t + 1}) 也是一個估計值,這個值有可能是不準確的,這個不準確會直接造成最終 V^{\pi}(s_{t}) 的不準確。

State-action Value Function Q^{\pi}(s, a)

比起 V^{\pi}(s),我們引入一個進階的版本,也就是我們接下來在 Q Learning 中重點要研究的 Q 函數。與之前的 V^{\pi}(s) 不同的是, V^{\pi}(s) 給定了計算初始的 state ,但是沒有指定初始的 action,初始的 action 完全是由 policy 自己決定的。Q 函數的不同之處在于其不僅給定一個初始狀態,更指定在遇見這個狀態之后應該做出怎么樣的 action:

Q^{\pi}(s_t, a_t)

剩下就是計算 cumulated reward,這個和 V 函數是一樣的。那么如何使用 Q 函數進行強化學習呢?

Q-Learning 的算法可以簡單地用三步來表示:

  • 初始化一個 actor \pi
  • 在一次迭代過程中:
    • actor \pi 與環境做互動,并且收集數據 s, a, r
    • 用上述的數據,TD 或者是 MC 的方法估測出 Q 函數 Q^{\pi}(s, a)
    • 根據 Q 函數,找到一個永遠比 \pi “更好的” \pi'
    • \pi' 去替換原有的 \pi

這里的 “更好” 指的是對任意的 s: V^{\pi'}(s) > V^{\pi}(s)\pi'(s) = arg max_{a} Q^{\pi}(s, a), 即對所有可能的 action a 來說,能夠代入 Q^{\pi}(s, a) 并且獲得最大值的那個 action 就是 \pi' 會采取的 action。這里有個小問題,如果 action 是離散的,那么只要一個一個代進去算就可以得到 arg max_{a} Q^{\pi}(s, a),但是如果 action 是連續的就不容易計算。

證明如果存在 \pi'(s) = arg max_{a} Q^{\pi}(s, a),那么對任意的 s 有 V^{\pi'}(s) > V^{\pi}(s):

V^{\pi}(s) = Q^{\pi}(s, \pi(s)) \leq max_a Q^{\pi}(s, a) = Q^{\pi}(s, \pi'(s))

即針對某一個特定的 s ,\pi' 所采用的 action 一定不比 \pi 采取的有更小的 reward,那么加入每一步都 follow \pi' 給的 action:

\begin{align} V^{\pi}(s) & \leq Q^{\pi}(s, \pi'(s)) \\ & = \mathbb{E} \left [ r_{t+1} + V^{\pi}(s_{t+1})_{|s_t = s, a_t = \pi'(s_t)} \right ] \\ & \leq \mathbb{E} \left [ r_{t+1} + Q^{\pi}(s_{t+1}, \pi'(s_{t+1}))_{|s_t = s, a_t = \pi'(s_t)} \right ] \\ & = \mathbb{E} \left [ r_{t+1} + r_{t+2} + V^{\pi}(s_{t+2})_{| ...} \right ] \\ & \leq \mathbb{E} \left [ r_{t+1} + r_{t+2} + Q^{\pi}(s_{t+2}, \pi'(s_{t+2}))_{| ...} \right ] ... = V^{\pi'}(s) \end{align}

Target Network

如果使用 TD-based 的方式訓練神經網絡來估計 Q 函數的時候,需要初始化兩個一樣的 DNN:

(s_t, a_t) \rightarrow \left [ Q^{\pi} \right ] \rightarrow Q^{\pi}(s_t, a_t) \leftrightarrow r_t + Q^{\pi}(s_{t+1}, \pi(s_{t+1})) \leftarrow \left [ Q^{\pi} \right ] \leftarrow (s_{t+1}, \pi(s_{t+1}))

兩個網絡輸出的差就是 r_t,但是在訓練的過程中輸入 (s_{t+1}, \pi(s_{t+1})) 是負責產生 target 的,如果保持兩個網絡一直一樣,相當于在訓練的過程中目標網絡是會變化的,這是不好的,所以在訓練的時候會現將目標網絡固定住,直到某個固定的跌代次數之后再更新。

Exploitation 和 Exploration

在強化學習中,一直存在著一個 trade-off:就是探索新的 action 還是專注獲得最大的 reward。這里不得不提到一個非常經典的問題:multi-arm bandit,多臂老虎機問題。
具體來說就是 你進了一家賭場,前面有著 K 臺老虎機,每臺老虎機去搖動的時候都有一定概率吐出一定量的錢,也有可能不吐錢,這個你沒法事先知道,現在你有 T 個錢幣,一個錢幣只能搖動一臺老虎機一次,怎樣做你才能夠擁有最大的金錢回報?

這實際上牽扯到一個權衡,你想知道哪臺老虎機吐錢的概率最大,這需要你去嘗試:Exploration。當然,探索是有成本的,因為你可能花了很多錢搖了各種各樣的老虎機,但是收獲的回報微乎其微。你還想獲得最大的收益,如果你發現了一個相對吐錢概率高的老虎機,你得多搖搖才行,這是 Exploitation。

那么在 Q-Learning 中如果一開始在 state s 有三個可能的 action a1, a2, a3,一開始由于這三種 action 都沒有被 sample 到,所以他們的 reward 是不存在的,這時候如果其中某個 action 被 sample 到了并且取得了好的反饋,根據 Q 函數永遠都會選擇最大 reward 的 action 去執行,那么這個 action 就會一直被 sample,而另外兩個得不到被 sample 的機會,這顯然是不合理的。

那么該怎么解決這個問題呢?

一種非常直觀地方法叫 Epsilon Greddy,具體表示為:

a = \begin{cases} arg max_a Q^{\pi}(s, a) & f(x) < 1 - \varepsilon \\ random & otherwise \end{cases}

在一定概率下隨機亂試,起到 exploration 的作用。這個 1 - \varepsilon 一般會隨著時間往后推移而減小,因為越往后可能沒有嘗試過的新 action 就越少,沒必要使用這么大的概率去進行探索。

或者覺得隨機亂試不是一個好方法,那么可以參考 policy gradient 的方法,給 Q 函數構建一個概率分布,假設某個 action 的 Q value 越大,那么采取這個 action 的幾率也就會越大,但是不代表其他 action 不會被 sample 到。這個具體的方法叫做 Boltzmann Exploration:

P(a|s) = \frac{exp(Q(s, a))}{\sum_a exp(Q(s, a))}

之所以要用 Exp,是因為 Q value 可能是有正有負的,之后再做歸一化。

Reply Buffer

在 Q Learning 中,我們有一個 policy 去和環境做互動并且產生數據,reply buffer 指的是我們會把所有的數據放到一個類似于緩沖區的地方,具體的數據含有 ( s_t, a_t, r_t, s_{t+1}),這個 buffer(緩沖區) 里面可能包含非常非常多的數據,隨著互動的 policy 不斷更新,buffer 里面自然也會包含不同的 policy 收集到的數據,并且這個 buffer 只有在轉滿的時候才會把舊的數據丟掉。

實際上當我們有了這個 reply buffer 以后,整個學習過程可以看作是 off-policy 的,其好處就是,DRL 往往會花很多時間與環境做互動,所以使用了 reply bufer 可以增加訓練效率。

并且 reply buffer 里面含有不同的 policy 數據,可以在訓練深度神經網絡的時候起到增加數據多樣性的目的,因為數據并不是一筆筆完整的 episode 而是每一步產生的結果,所以不同的 policy 也可以用來估測 Q^{\pi}(s, a)

綜合上述算法和 tips,一個典型的 Deep Q-Learning 的算法可以描述為:

  • 先初始化兩個 Q function: Q 和 target Q function \hat{Q} = Q
  • 在每個 episode 中:
    • 在每次迭代中:
      • 給定一個輸入 state s_t,根據 Q 采取相應的 action a_t
      • 得到 reward r_t,并且進入下一個 state s_{t+1}
      • 把上面收集到的 ( s_t, a_t, r_t, s_{t+1}) 放到 reply buffer 中
      • 從 reply buffer 中 sample 數據,一般按照 batch 來 sample
      • 訓練,更新 Q 的參數使得 Q(s_i, a_i) 接近于 y = r_i + max_a \hat{Q}(s_{i+1}, a)
    • 每 N 次迭代完成之后更新 \hat{Q} = Q
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容