強化學習(十二) Dueling DQN

    在強化學習(十一) Prioritized Replay DQN中,我們討論了對DQN的經驗回放池按權重採樣來優化DQN算法的方法,本文討論另一種優化方法,Dueling DQN。本章內容主要參考了ICML 2016的deep RL tutorial和Dueling DQN的論文<Dueling Network Architectures for Deep Reinforcement Learning>(ICML 2016)。

1. Dueling DQN的優化點考慮

    在前面講到的DDQN中,我們通過優化目標Q值的計算來優化算法,在Prioritized Replay DQN中,我們通過優化經驗回放池按權重採樣來優化算法。而在Dueling DQN中,我們嘗試通過優化神經網絡的結構來優化算法。

    具體如何優化網絡結構呢?Dueling DQN考慮將Q網絡分成兩部分,第一部分是僅僅與狀態$S$有關,與具體要採用的動作$A$無關,這部分我們叫做價值函數部分,記做$V(S,w,\alpha)$,第二部分同時與狀態狀態$S$和動作$A$有關,這部分叫做優勢函數(Advantage Function)部分,記爲$A(S,A,w,\beta)$,那麼最終我們的價值函數可以重新表示爲:$$Q(S,A, w, \alpha, \beta) = V(S,w,\alpha) + A(S,A,w,\beta)$$

    其中,$w$是公共部分的網絡參數,而$\alpha$是價值函數獨有部分的網絡參數,而$\beta$是優勢函數獨有部分的網絡參數。

2. Dueling DQN網絡結構

    由於Q網絡的價值函數被分爲兩部分,因此Dueling DQN的網絡結構也和之前的DQN不同。爲了簡化算法描述,這裏不使用原論文的CNN網絡結構,而是使用前面文中用到的最簡單的三層神經網絡來描述。是否使用CNN對Dueling DQN算法本身無影響。

    在前面講到的DDQN等DQN算法中,我使用了一個簡單的三層神經網絡:一個輸入層,一個隱藏層和一個輸出層。如下左圖所示:

     而在Dueling DQN中,我們在後面加了兩個子網絡結構,分別對應上面上到價格函數網絡部分和優勢函數網絡部分。對應上面右圖所示。最終Q網絡的輸出由價格函數網絡的輸出和優勢函數網絡的輸出線性組合得到。

    我們可以直接使用上一節的價值函數的組合公式得到我們的動作價值,但是這個式子無法辨識最終輸出裏面$V(S,w,\alpha)$和$A(S,A,w,\beta)$各自的作用,爲了可以體現這種可辨識性(identifiability),實際使用的組合公式如下:$$Q(S,A, w, \alpha, \beta) = V(S,w,\alpha) + (A(S,A,w,\beta) - \frac{1}{\mathcal{A}}\sum\limits_{a' \in \mathcal{A}}A(S,a', w,\beta))$$

    其實就是對優勢函數部分做了中心化的處理。以上就是Duel DQN的主要算法思路。由於它僅僅涉及神經網絡的中間結構的改進,現有的DQN算法可以在使用Duel DQN網絡結構的基礎上繼續使用現有的算法。由於算法主流程和其他算法沒有差異,這裏就單獨講Duel DQN的算法流程了。

3. Dueling DQN實例

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

    這個實例代基於Nature DQN,並將網絡結構改爲上圖中右邊的Dueling DQN網絡結構,完整的代碼參見我的github: https://github.com/ljpzzz/machinelearning/blob/master/reinforcement-learning/duel_dqn.py

     這裏我們重點關注Dueling DQN和Nature DQN的代碼的不同之處。也就是網絡結構定義部分,主要的代碼如下,一共有兩個相同結構的Q網絡,每個Q網絡都有狀態函數和優勢函數的定義,以及組合後的Q網絡輸出,如代碼紅色部分:

  def create_Q_network(self):
    # input layer
    self.state_input = tf.placeholder("float", [None, self.state_dim])
    # network weights
    with tf.variable_scope('current_net'):
        W1 = self.weight_variable([self.state_dim,20])
        b1 = self.bias_variable([20])

        # hidden layer 1
        h_layer_1 = tf.nn.relu(tf.matmul(self.state_input,W1) + b1)

        # hidden layer  for state value
        with tf.variable_scope('Value'):
          W21= self.weight_variable([20,1])
          b21 = self.bias_variable([1])
          self.V = tf.matmul(h_layer_1, W21) + b21

        # hidden layer  for action value
        with tf.variable_scope('Advantage'):
          W22 = self.weight_variable([20,self.action_dim])
          b22 = self.bias_variable([self.action_dim])
          self.A = tf.matmul(h_layer_1, W22) + b22

          # Q Value layer
          self.Q_value = self.V + (self.A - tf.reduce_mean(self.A, axis=1, keep_dims=True))

    with tf.variable_scope('target_net'):
        W1t = self.weight_variable([self.state_dim,20])
        b1t = self.bias_variable([20])

        # hidden layer 1
        h_layer_1t = tf.nn.relu(tf.matmul(self.state_input,W1t) + b1t)

        # hidden layer  for state value
        with tf.variable_scope('Value'):
          W2v = self.weight_variable([20,1])
          b2v = self.bias_variable([1])
          self.VT = tf.matmul(h_layer_1t, W2v) + b2v

        # hidden layer  for action value
        with tf.variable_scope('Advantage'):
          W2a = self.weight_variable([20,self.action_dim])
          b2a = self.bias_variable([self.action_dim])
          self.AT = tf.matmul(h_layer_1t, W2a) + b2a

          # Q Value layer
          self.target_Q_value = self.VT + (self.AT - tf.reduce_mean(self.AT, axis=1, keep_dims=True))

    其餘部分代碼和Nature DQN基本相同。當然,我們可以也在前面DDQN,Prioritized Replay DQN代碼的基礎上,把網絡結構改成上面的定義,這樣Dueling DQN也可以起作用。

4. DQN總結

    DQN系列我花了5篇來講解,一共5個前後有關聯的算法:DQN(NIPS2013), Nature DQN, DDQN, Prioritized Replay DQN和Dueling DQN。目前使用的比較主流的是後面三種算法思路,這三種算法思路也是可以混着一起使用的,相互並不排斥。

    當然DQN家族的算法遠遠不止這些,還有一些其他的DQN算法我沒有詳細介紹,比如使用一些較複雜的CNN和RNN網絡來提高DQN的表達能力,又比如改進探索狀態空間的方法等,主要是在DQN的基礎上持續優化。

    DQN算是深度強化學習的中的主流流派,代表了Value-Based這一大類深度強化學習算法。但是它也有自己的一些問題,就是絕大多數DQN只能處理離散的動作集合,不能處理連續的動作集合。雖然NAF DQN可以解決這個問題,但是方法過於複雜了。而深度強化學習的另一個主流流派Policy-Based而可以較好的解決這個問題,從下一篇我們開始討論Policy-Based深度強化學習。

(歡迎轉載,轉載請註明出處。歡迎溝通交流: [email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章