1. 程式人生 > >強化學習(九)與Deep Q-Learning進階之Nature DQN

強化學習(九)與Deep Q-Learning進階之Nature DQN

cal variable 模型 基礎 討論 比較 .com 回放 均方差

    在強化學習(八)價值函數的近似表示與Deep Q-Learning中,我們講到了Deep Q-Learning(NIPS 2013)的算法和代碼,在這個算法基礎上,有很多Deep Q-Learning(以下簡稱DQN)的改進版,今天我們來討論DQN的第一個改進版Nature DQN(NIPS 2015)。

    本章內容主要參考了ICML 2016的deep RL tutorial和Nature DQN的論文。

1. DQN(NIPS 2013)的問題

    在上一篇我們已經討論了DQN(NIPS 2013)的算法原理和代碼實現,雖然它可以訓練像CartPole這樣的簡單遊戲,但是有很多問題。這裏我們先討論第一個問題。

    註意到DQN(NIPS 2013)裏面,我們使用的目標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}$$

    這裏目標Q值的計算使用到了當前要訓練的Q網絡參數來計算$Q(\phi(S‘_j),A‘_j,w)$,而實際上,我們又希望通過$y_j$來後續更新Q網絡參數。這樣兩者循環依賴,叠代起來兩者的相關性就太強了。不利於算法的收斂。

    因此,一個改進版的DQN: Nature DQN嘗試用兩個Q網絡來減少目標Q值計算和要更新Q網絡參數之間的依賴關系。下面我們來看看Nature DQN是怎麽做的。

2. Nature DQN的建模

    Nature DQN使用了兩個Q網絡,一個當前Q網絡$Q$用來選擇動作,更新模型參數,另一個目標Q網絡$Q‘$用於計算目標Q值。目標Q網絡的網絡參數不需要叠代更新,而是每隔一段時間從當前Q網絡$Q$復制過來,即延時更新,這樣可以減少目標Q值和當前的Q值相關性。

    要註意的是,兩個Q網絡的結構是一模一樣的。這樣才可以復制網絡參數。

    Nature DQN和上一篇的DQN相比,除了用一個新的相同結構的目標Q網絡來計算目標Q值以外,其余部分基本是完全相同的。

3. Nature DQN的算法流程

    下面我們來總結下Nature DQN的算法流程, 基於DQN NIPS 2015:

    算法輸入:叠代輪數$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\max_{a‘}Q‘(\phi(S‘_j),A‘_j,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$

      h) 如果$S‘$是終止狀態,當前輪叠代完畢,否則轉到步驟b)

      註意,上述第二步的f步和g步的Q值計算也都需要通過Q網絡計算得到。另外,實際應用中,為了算法較好的收斂,探索率$\epsilon$需要隨著叠代的進行而變小。

4. Nature DQN算法實例

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

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

    這裏我們重點關註Nature DQN和上一節的NIPS 2013 DQN的代碼的不同之處。

    首先是Q網絡,上一篇的DQN是一個三層的神經網絡,而這裏我們有兩個一樣的三層神經網絡,一個是當前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])
        W2 = self.weight_variable([20,self.action_dim])
        b2 = self.bias_variable([self.action_dim])

        # hidden layers
        h_layer = tf.nn.relu(tf.matmul(self.state_input,W1) + b1)
        # Q Value layer
        self.Q_value = tf.matmul(h_layer,W2) + b2

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

        # hidden layers
        h_layer_t = tf.nn.relu(tf.matmul(self.state_input,W1t) + b1t)
        # Q Value layer
        self.target_Q_value = tf.matmul(h_layer,W2t) + b2t

    對於定期將目標Q網絡的參數更新的代碼如下面兩部分:

    t_params = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=target_net)
    e_params = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=current_net)

    with tf.variable_scope(soft_replacement):
        self.target_replace_op = [tf.assign(t, e) for t, e in zip(t_params, e_params)]
  def update_target_q_network(self, episode):
    # update target Q netowrk
    if episode % REPLACE_TARGET_FREQ == 0:
        self.session.run(self.target_replace_op)
        #print(‘episode ‘+str(episode) +‘, target Q network params replaced!‘)

    此外,註意下我們計算目標Q值的部分,這裏使用的目標Q網絡的參數,而不是當前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]))

    其余部分基本和上一篇DQN的代碼相同。這裏給出我跑的某一次的結果:

episode: 0 Evaluation Average Reward: 9.8
episode: 100 Evaluation Average Reward: 9.8
episode: 200 Evaluation Average Reward: 9.6
episode: 300 Evaluation Average Reward: 10.0
episode: 400 Evaluation Average Reward: 34.8
episode: 500 Evaluation Average Reward: 177.4
episode: 600 Evaluation Average Reward: 200.0
episode: 700 Evaluation Average Reward: 200.0
episode: 800 Evaluation Average Reward: 200.0
episode: 900 Evaluation Average Reward: 198.4
episode: 1000 Evaluation Average Reward: 200.0
episode: 1100 Evaluation Average Reward: 193.2
episode: 1200 Evaluation Average Reward: 200.0
episode: 1300 Evaluation Average Reward: 200.0
episode: 1400 Evaluation Average Reward: 200.0
episode: 1500 Evaluation Average Reward: 200.0
episode: 1600 Evaluation Average Reward: 200.0
episode: 1700 Evaluation Average Reward: 200.0
episode: 1800 Evaluation Average Reward: 200.0
episode: 1900 Evaluation Average Reward: 200.0
episode: 2000 Evaluation Average Reward: 200.0
episode: 2100 Evaluation Average Reward: 200.0
episode: 2200 Evaluation Average Reward: 200.0
episode: 2300 Evaluation Average Reward: 200.0
episode: 2400 Evaluation Average Reward: 200.0
episode: 2500 Evaluation Average Reward: 200.0
episode: 2600 Evaluation Average Reward: 200.0
episode: 2700 Evaluation Average Reward: 200.0
episode: 2800 Evaluation Average Reward: 200.0
episode: 2900 Evaluation Average Reward: 200.0

    註意,由於DQN不保證穩定的收斂,所以每次跑的結果會不同,如果你跑的結果後面仍然收斂的不好,可以把代碼多跑幾次,選擇一個最好的訓練結果。

5. Nature DQN總結

    Nature DQN對DQN NIPS 2013做了相關性方面的改進,這個改進雖然不錯,但是仍然沒有解決DQN的 很多問題,比如:

    1) 目標Q值的計算是否準確?全部通過max Q來計算有沒有問題?

    2) 隨機采樣的方法好嗎?按道理不同樣本的重要性是不一樣的。

    3) Q值代表狀態,動作的價值,那麽單獨動作價值的評估會不會更準確?

    第一個問題對應的改進是Double DQN, 第二個問題的改進是Prioritised Replay DQN,第三個問題的改進是Dueling DQN,這三個DQN的改進版我們在下一篇來討論。

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

強化學習(九)與Deep Q-Learning進階之Nature DQN