Double DQN

Pythonで学ぶDeep Reinforcement Learning

Timothée Carayol

Principal Machine Learning Engineer, Komment

Double Q-learning

  • Q-learning は Q 値を過大評価し、学習効率を下げる
  • 原因は最大化バイアス
  • Double Q-Learning は行動選択と価値推定を分離してバイアスを除去

2 つの Q テーブル(コース「Gymnasium と Python による強化学習」の図):Double Q-learning は交互に使用

Pythonで学ぶDeep Reinforcement Learning

DDQN の考え方

  • 完成版 DQN(固定 Q ターゲット)から開始
  • DQN の TD 目標:
    • 行動選択: ターゲットネットワーク
    • 価値推定: ターゲットネットワーク
  • DDQN の TD 目標:
    • 行動選択: オンラインネットワーク
    • 価値推定: ターゲットネットワーク
  • 厳密な Double Q-learning ではない(交互の Q ネットなし)
  • 最小の変更で大部分の効果

ベルマン誤差(固定 Q ターゲットの DQN): Q_online(s_t, a_t) - (r_t+1 + gamma max(Q_target(s_t+1, a)))

ベルマン誤差(固定 Q ターゲットの DDQN): Q_online(s_t, a_t) - (r_t+1 + gamma Q_target(s_t+1, tilde a))、ただし tilde a = argmax_a(Q_online(s_t+1, a))

Pythonで学ぶDeep Reinforcement Learning

Double DQN の実装

DQN:

... # instantiate online and target networks
q_values = (online_network(states)
            .gather(1, actions).squeeze(1))

with torch.no_grad():
# # next_q_values = (target_network(next_states) .amax(1))
target_q_values = (rewards + gamma * next_q_values * (1 - dones))
loss = torch.nn.MSELoss()(q_values, target_q_values) ... # gradient descent ... # target network update

DDQN:

... # instantiate online and target networks
q_values = (online_network(states)
            .gather(1, actions).squeeze(1))

with torch.no_grad():

target_q_values = (rewards + gamma * next_q_values * (1 - dones))
loss = torch.nn.MSELoss()(q_values, target_q_values) ... # gradient descent ... # target network update
Pythonで学ぶDeep Reinforcement Learning

Double DQN の実装

DQN:

... # instantiate online and target networks
q_values = (online_network(states)
            .gather(1, actions).squeeze(1))

with torch.no_grad():
next_actions = (target_network(next_states) .argmax(1).unsqueeze(1))
next_q_values = (target_network(next_states) .gather(1, next_actions).squeeze(1))
target_q_values = (rewards + gamma * next_q_values * (1 - dones))
loss = torch.nn.MSELoss()(q_values, target_q_values) ... # gradient descent ... # target network update

DDQN:

... # instantiate online and target networks
q_values = (online_network(states)
            .gather(1, actions).squeeze(1))

with torch.no_grad():
next_actions = (online_network(next_states) .argmax(1).unsqueeze(1))
next_q_values = (target_network(next_states) .gather(1, next_actions).squeeze(1))
target_q_values = (rewards + gamma * next_q_values * (1 - dones))
loss = torch.nn.MSELoss()(q_values, target_q_values) ... # gradient descent ... # target network update
Pythonで学ぶDeep Reinforcement Learning

DDQN の性能

 

  • Atari ゲームで DDQN・DQN・人間の性能を比較
  • DDQN: 元の DQN より高スコア
  • 常に当てはまるとは限らない → 両方試す

棒グラフ: DQN は中央値で人間にほぼ匹敵し平均で超人的、DDQN は中央値・平均ともに人間と DQN を上回る

1 https://arxiv.org/abs/2303.11634
Pythonで学ぶDeep Reinforcement Learning

演習に進みましょう!

Pythonで学ぶDeep Reinforcement Learning

Preparing Video For Download...