在實際應用中DQN會引起高估,進而影響動作的正確選擇。本文介紹的高估問題解決辦法為:Target Network & Double DQN.
11. Target Network & Double DQN
11.1 Bootstraps \ 自舉
自舉通俗來說就是自己把自己舉起來,這在現實物理學中是很荒唐的,但在統計學和強化學習中是可以做到自舉的。
在強化學習中,自舉 的意思是用一個估算去更新同類的估算,即自己把自己舉起來。
之前我們提到:
- 用 transition \((s_t,a_t,r_t,s_{t+1})\) 更新一次 w。
- TD target: \(y_t = {r_t} + \gamma \cdot \mathop{max}\limits_{a} Q({s_{t+1}},{a};w)\)
- TD error: \(\delta_t = Q({s_t},{a_t};w) - y_t\)
- 梯度下降,更新引數: \(w \leftarrow w -\alpha \cdot \delta_t \cdot \frac{\partial Q({s_t},{a_t};w)}{\partial w}\)
我們注意一下TD target,\(y_t\) 中含有部分真實 也含有 部分DQN 在 t+1 時刻的估計。而梯度下降中的 \(\delta_t\) 中含有 \(y_t\) 。
這說明我們為了更新 t 時刻的估計,而用到了 t+1 時刻的預測。
這就是一個估計值更新其本身,也就是自己把自己舉起來,bootstraping.
11.2 Overestimation
用TD演算法訓練DQN,會導致DQN往往高估真實的動作價值;下面來介紹一下 高估問題產生的原因。
- 計算TD target 使用了最大化 max,使得 TD target 比真實的動作價值大。
- Bootstrapping,用自己的估計更新自己,高估引發更離譜的高估;
a. 最大化
舉個例子來說明為什麼使用最大化會產生高估:
假設我們觀測到了任意 n 個實數 \(x_1,x_2,...,x_n\);向其中加入均值是 0 的噪聲,得到 \(Q_1,Q_2,...,Q_n\);
加入噪聲這件事會造成:
- 均值不變,即:\(E[mean_i(Q_i)]=mean_i(x_i)\);
- 最大值的均值更大,即:\(E[max_i(Q_i)]\geq max_i(x_i)\);
- 最小值的均值更小,即:\(E[min_i(Q_i)]\leq min_i(x_i)\)
這些結論可以自己帶入數字驗證,都有相關的定理支撐。
簡單的解釋是,加入噪聲從訊號圖的角度來講,讓上下限更寬,所以有以上結論。
下面來看看這個原理投射在TD 演算法上的:
-
真實的動作價值為(雖然我們不知道,但是其存在):\(x(a_1),...,x(a_n)\)
-
我們用DQN估算真實的動作價值,噪聲就是由 DQN 產生的:\(Q(s,a_1;w),...,Q(s,a_n;w)\);
-
如果 DQN 對於真實價值的估計是 無偏的,那麼 誤差 就相當於上文的均值為0的 噪聲 ;
\(\mathop{mean}\limits_{a} (x(a)) = \mathop{mean}\limits_{a} (Q(s,a;w))\)
-
而根據上面的舉例,\(\mathop{max} \limits_{a} Q(s,a;w)\geq \mathop{max} \limits_{a}(x(a))\);意思就是,DQN的預測q: \(\mathop{max} \limits_{a} Q(s,a;w)\),是對真實情況的高估。
-
那麼,根據 \(y_t = {r_t} + \gamma \cdot q_{t+1}\),\(y_t\) 較真實情況也高估了。
-
TD 演算法本身的思想就是,讓預測接近 TD target,更新之後的 DQN 預測也會高估。
b. 自舉
-
TD target 用到了 t+1 時刻的估計:\(q_{t+1}=\mathop{max}\limits_{a} Q^*({s_{t+1}},{a};w)\);
-
而使用 TD target 在 t+1 時刻的估計 \(q_{t+1}\) 來更新 t 時刻的估計,用DQN 來更新 DQN 自己,這樣 bootstrapping 會導致高估更嚴重:
-
向高估方向連續進行了兩次運算,
\(y_t = {r_t} + \gamma \cdot \mathop{max}\limits_{a} Q({s_{t+1}},{a};w)\),分別是:
- Q 處就是 DQN 對 t+1 時刻的高估
- 在計算 \(y_t\) 的時候,最大化又導致了高估
- 兩次高估是同向的;
- 通過TD 演算法將這種高估傳播回 DQN,DQN的高估更嚴重了
- 迴圈往復,正反饋
-
c. 高估為什麼有害
回顧 DQN / 價值學習 的基本思想:在當前狀態 \(s_t\) 的情況下,通過DQN輸出各個動作的分數,從中挑選分數相對最高的動作執行。
如果高估這個現象對於所有動作是均勻的,那麼不影響本該被選中的動作被選中。所以高估本身沒有問題,有害的是不均勻的高估。
實際上 DQN 的高估就是非均勻的:
- 使用一個transition \((s_t,a_t,r_t,s_{t+1})\) 去更新 w;
- TD target \(y_t\)現在高估了真實情況
- TD 演算法鼓勵 QDN 的預測接近 \(y_t\),
- 那麼更新引數後,TD 演算法把 QDN 對於Q-star的估值推高
- 所以,重點來了,當某組 transition(包含狀態和動作 s&a 的二元組) 每被用來更新一次DQN,就會讓DQN傾向於高估s和a的價值;
- 而這個二元組在 Reply Buffer 中的頻率不均勻,這種不均勻導致高估的不均勻。
11.3 解決方案
介紹高估問題的兩種解決方案:
- 第一種是避免 Bootstrapping ,即不要用 DQN 自己的 TD target 跟新DQN,而是使用另一個神經網路 Target Network。
- 另一種思路是用Double DQN,用來緩解最大化造成的高估;雖然也使用 Target Network,但用法有所不同。
a. Target Network
這裡我們引入 另一個神經網路 Target Network \(Q(s,a,w^-)\),TN 的結構與 DQN 一樣,但是引數 \(w\) 不同。另外兩者的用途也不同,DQN用來收集 transitions,控制 agent 運動,而 TN 只用來 計算 TD target。
將 TN 用在 TD 演算法上:
-
用 Target Network 更新 TD Target:\(y_t = r_t + \gamma\cdot \ \mathop{max}\limits_{a} Q(s_{t+1},a;w^-)\)
-
DQN 計算TD error:\(\delta_t = Q({s_t},{a_t};w) - y_t\)
-
梯度下降更新引數: \(w \leftarrow w -\alpha \cdot \delta_t \cdot \frac{\partial Q({s_t},{a_t};w)}{\partial w}\)
注意這裡更新的是 DQN 的 w,沒有更新 TN 的 \(w^-\)
-
\(w^-\) 每隔一段時間更新,更新方式有很多種:
- 直接: \(w^-\leftarrow w\)
- 加權平均:\(w^-\leftarrow \tau\cdot w + (1-\tau)\cdot w^-\)
由於 TN 還是需要 DQN 的引數,不是完全獨立,所以不能完全避免Bootstrapping.
b. Double DQN
原始演算法:
- 計算TD target 的第一步是選擇:\(a^*=\mathop{argmax}\limits_{a} Q(s_{t+1},a;w)\),這一步是使用 DQN自己;
- 計算 \(y_t = {r_t} + \gamma \cdot \mathop{max}\limits_{a} Q({s_{t+1}},{a^*};w)\)
- 這種演算法最差
使用 TN:
- 計算TD target 的第一步是選擇:\(a^*=\mathop{argmax}\limits_{a} Q(s_{t+1},a;w^-)\),這一步是使用 TN;
- 計算 \(y_t = {r_t} + \gamma \cdot Q({s_{t+1}},{a^*};w^-)\)
- 較於第一種較好,但仍存在高估;
Double DQN:
- 選擇:\(a^*=\mathop{argmax}\limits_{a} Q(s_{t+1},a;w)\),注意這一步是 Double DQN;
- 計算:\(y_t = {r_t} + \gamma \cdot Q({s_{t+1}},{a^*};w^-)\);這一步使用 TN;
- 可見改動非常小,但是改進效果顯著。(沒有消除高估)
為什麼呢?
\(Q(s_{t+1},a^*;w^-)\leq \mathop{max}\limits_{a}Q(s_{t+1},a;w^-)\)
- 因為右邊是求了最大化,所以右邊一定比左邊大;
- 而左邊是 Double DQN作出的估計,右邊是 TN 算出來的;
- 這個式子說明: Double DQN 作出的估計更小,所以緩解了 高估問題;