強化學習(十)Double DQN (DDQN)

    在強化學習(九)Deep Q-Learning進階之Nature DQN中,咱們討論了Nature DQN的算法流程,它經過使用兩個相同的神經網絡,以解決數據樣本和網絡訓練以前的相關性。可是仍是有其餘值得優化的點,文本就關注於Nature DQN的一個改進版本: Double DQN算法(如下簡稱DDQN)。html

    本章內容主要參考了ICML 2016的deep RL tutorial和DDQN的論文<Deep Reinforcement Learning with Double Q-learning>。git

1. DQN的目標Q值計算問題

    在DDQN以前,基本上全部的目標Q值都是經過貪婪法直接獲得的,不管是Q-Learning, DQN(NIPS 2013)仍是 Nature DQN,都是如此。好比對於Nature DQN,雖然用了兩個Q網絡並使用目標Q網絡計算Q值,其第j個樣本的目標Q值的計算仍是貪婪法獲得的,計算入下式:$$y_j= \begin{cases} R_j& {is\_end_j\; is \;true}\\ R_j + \gamma\max_{a'}Q'(\phi(S'_j),A'_j,w') & {is\_end_j \;is\; false} \end{cases}$$github

    使用max雖然能夠快速讓Q值向可能的優化目標靠攏,可是很容易過猶不及,致使過分估計(Over Estimation),所謂過分估計就是最終咱們獲得的算法模型有很大的誤差(bias)。爲了解決這個問題, DDQN經過解耦目標Q值動做的選擇和目標Q值的計算這兩步,來達到消除過分估計的問題。算法

2. DDQN的算法建模

    DDQN和Nature DQN同樣,也有同樣的兩個Q網絡結構。在Nature DQN的基礎上,經過解耦目標Q值動做的選擇和目標Q值的計算這兩步,來消除過分估計的問題。網絡

    在上一節裏,Nature DQN對於非終止狀態,其目標Q值的計算式子是:$$y_j= R_j + \gamma\max_{a'}Q'(\phi(S'_j),A'_j,w')$$app

    在DDQN這裏,再也不是直接在目標Q網絡裏面找各個動做中最大Q值,而是先在當前Q網絡中先找出最大Q值對應的動做,即$$a^{max}(S'_j, w) = \arg\max_{a'}Q(\phi(S'_j),a,w)$$函數

    而後利用這個選擇出來的動做$a^{max}(S'_j, w) $在目標網絡裏面去計算目標Q值。即:$$y_j = R_j + \gamma Q'(\phi(S'_j),a^{max}(S'_j, w),w')$$post

    綜合起來寫就是:$$y_j = R_j + \gamma Q'(\phi(S'_j),\arg\max_{a'}Q(\phi(S'_j),a,w),w')$$學習

    除了目標Q值的計算方式之外,DDQN算法和Nature DQN的算法流程徹底相同。優化

 3. DDQN算法流程

    這裏咱們總結下DDQN的算法流程,和Nature DQN的區別僅僅在步驟2.f中目標Q值的計算。

    算法輸入:迭代輪數$T$,狀態特徵維度$n$, 動做集$A$, 步長$\alpha$,衰減因子$\gamma$, 探索率$\epsilon$, 當前Q網絡$Q$,目標Q網絡$Q'$, 批量梯度降低的樣本數$m$,目標Q網絡參數更新頻率$C$。

    輸出:Q網絡參數

    1. 隨機初始化全部的狀態和動做對應的價值$Q$.  隨機初始化當前Q網絡的全部參數$w$,初始化目標Q網絡$Q'$的參數$w' = w$。清空經驗回放的集合$D$。

    2. for i from 1 to T,進行迭代。

      a) 初始化S爲當前狀態序列的第一個狀態, 拿到其特徵向量$\phi(S)$

      b) 在Q網絡中使用$\phi(S)$做爲輸入,獲得Q網絡的全部動做對應的Q值輸出。用$\epsilon-$貪婪法在當前Q值輸出中選擇對應的動做$A$

      c) 在狀態$S$執行當前動做$A$,獲得新狀態$S'$對應的特徵向量$\phi(S')和獎勵$R$,是否終止狀態is_end

      d) 將$\{\phi(S),A,R,\phi(S'),is\_end\}$這個五元組存入經驗回放集合$D$

      e) $S=S'$

      f)  從經驗回放集合$D$中採樣$m$個樣本$\{\phi(S_j),A_j,R_j,\phi(S'_j),is\_end_j\}, j=1,2.,,,m$,計算當前目標Q值$y_j$:$$y_j= \begin{cases} R_j& {is\_end_j\; is \;true}\\ R_j + \gamma Q'(\phi(S'_j),\arg\max_{a'}Q(\phi(S'_j),a,w),w')& {is\_end_j\; is \;false} \end{cases}$$

      g)  使用均方差損失函數$\frac{1}{m}\sum\limits_{j=1}^m(y_j-Q(\phi(S_j),A_j,w))^2$,經過神經網絡的梯度反向傳播來更新Q網絡的全部參數$w$

      h) 若是T%C=1,則更新目標Q網絡參數$w'=w$

      i) 若是$S'$是終止狀態,當前輪迭代完畢,不然轉到步驟b)

      注意,上述第二步的f步和g步的Q值計算也都須要經過Q網絡計算獲得。另外,實際應用中,爲了算法較好的收斂,探索率$\epsilon$須要隨着迭代的進行而變小。

4. DDQN算法實例 

    下面咱們用一個具體的例子來演示DQN的應用。仍然使用了OpenAI Gym中的CartPole-v0遊戲來做爲咱們算法應用。CartPole-v0遊戲的介紹參見這裏。它比較簡單,基本要求就是控制下面的cart移動使鏈接在上面的pole保持垂直不倒。這個任務只有兩個離散動做,要麼向左用力,要麼向右用力。而state狀態就是這個cart的位置和速度, pole的角度和角速度,4維的特徵。堅持到200分的獎勵則爲過關。

    完整的代碼參見個人github: https://github.com/ljpzzz/machinelearning/blob/master/reinforcement-learning/ddqn.py

    這裏咱們重點關注DDQN和上一節的Nature DQN的代碼的不一樣之處。代碼只有一個地方不同,就是計算目標Q值的時候,以下:

    # Step 2: calculate y
    y_batch = []
    current_Q_batch = self.Q_value.eval(feed_dict={self.state_input: next_state_batch})
    max_action_next = np.argmax(current_Q_batch, axis=1)
    target_Q_batch = self.target_Q_value.eval(feed_dict={self.state_input: next_state_batch})

    for i in range(0,BATCH_SIZE):
      done = minibatch[i][4]
      if done:
        y_batch.append(reward_batch[i])
      else :
        target_Q_value = target_Q_batch[i, max_action_next[i]]
        y_batch.append(reward_batch[i] + GAMMA * target_Q_value)

    而以前的Nature  DQN這裏的目標Q值計算是以下這樣的:

 # Step 2: calculate y
    y_batch = []
    Q_value_batch = self.target_Q_value.eval(feed_dict={self.state_input:next_state_batch})
    for i in range(0,BATCH_SIZE):
      done = minibatch[i][4]
      if done:
        y_batch.append(reward_batch[i])
      else :
        y_batch.append(reward_batch[i] + GAMMA * np.max(Q_value_batch[i]))

    除了上面這部分的區別,兩個算法的代碼徹底相同。

5. DDQN小結

    DDQN算法出來之後,取得了比較好的效果,所以獲得了比較普遍的應用。不過咱們的DQN仍然有其餘能夠優化的點,如上一篇最後講到的: 隨機採樣的方法好嗎?按道理經驗回放裏不一樣樣本的重要性是不同的,TD偏差大的樣本重要程度應該高。針對這個問題,咱們在下一節的Prioritised Replay DQN中討論。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com)

相關文章
相關標籤/搜索