Deep Reinforcement Learning with Double Q-learning [arXiv:1509.06461]

2016年03月16日

概要

はじめに

今回の論文は Double Q-learning をもとに DQN を改良したものになっています。

Double Q-learningの方は時間がなくてあまり読めていません。

実装

今回も実装にはChainerを使います。

実装と言ってもDQNのコードを数行書き換えるだけなので、前回実装したものをベースにしました。

前処理などは 前回の記事 と全く変わっていません。

具体的な変更点ですが、まずQ学習では以下の更新式により状態行動関数Qを更新します。

\[\begin{align} Q_{\theta}(s,a)\gets Q_{\theta}(s,a)+\alpha(r+\gamma \max_{a'}Q_{\pi}(s',a')-Q_{\theta}(s,a)) \end{align}\]

ここでは状態$s$で行動$s$を取り、報酬$r$と次の状態$s’$を得たとしています。

$Q_{\theta}(s,a)$はパラメータ$\theta$を持つニューラルネット(DQNでは畳み込みニューラルネット+全結合層)です。

$Q_{\pi}(s,a)$は教師信号出力用のニューラルネットで、$Q_{\theta}(s,a)$のコピーになっています。(詳細は前回の記事

式((1))は$Q_{\theta}(s,a)$を\(r+\gamma \max_{a'}Q_{\pi}(s',a')\)に近づける働きがあるため、教師あり学習とみなすことができます。

そこでDQNでは教師信号$target$を以下のように定義します。

\[\begin{align} target\equiv r+\gamma \max_{a'}Q_{\pi}(s',a') \end{align}\]

Double DQNではこの$target$を以下のように変更します。

\[\begin{align} target\equiv r+\gamma Q_{\pi}(s',\argmax_aQ_{\theta}(s',a)) \end{align}\]

DQN(式((2)))では、次状態$s’$のもとで取るべき最善の行動の評価値\(\max_{a'}Q_{\pi}(s',a')\)を用いて$Q_{\theta}$を更新していました。

つまり、次に取るべき行動の選択とその評価を同じ$Q_{\pi}$を用いて行っています。

一方Double DQN(式((3)))では、まず次状態$s’$で取るべき行動$a$を\(argmax_aQ_{\theta}(s',a)\)により決定し、その$a$の評価値$Q_{\pi}(s’,a)$を用いて$Q_{\theta}$を更新します。

こうすることで、次に取るべき行動の選択を$Q_{\theta}$で行い、その評価を$Q_{\pi}$で行うことになります。

この手法はDouble Q-learningの応用ですが、どうやらパラメータの違う2種類のQ関数を用いることで性能が上がるそうです。(まだ読めていないのでなんとも言えませんが)

実際に動かしてみる

必要なもの

  • Arcade Learning Environment(ALE)
    • エミュレータであり、ゲームを起動し後述のRL-Glueと接続してくれます。強化学習で言うところの環境エージェントです。
  • RL-Glue
    • ALEで起動したゲームの操作をプログラムから行えるようにするものです。
    • どうやら.debの方をインストールすると失敗するみたいなのでソース(3.04.tar.gz)を落としてコンパイルする方が良いみたいです。
  • PL-Glue Python codec
    • RL-GlueをPythonで使えるようにするものです。
  • Atari 2600 VCS ROM Collection
    • ブロック崩しやインベーダーなどのROMです。
  • double-dqn
    • 今回実装したDouble DQNのコードです。
  • Chainer 1.6
    • 古いバージョンのChainerで動くかどうかはわかりません。

環境構築に関しては DQN-chainerリポジトリを動かすだけ が参考になります。

実験

今回も例によってDouble DQNにAtari Breakoutをプレイさせます。

ダウンロードしたROMにはBreakoutが2つ入っており、片方は画面サイズがALE非対応のため起動できなくなっています。

起動できる方をbreakout.binにリネームしておいてください。

ターミナルを4つ起動し、以下をそれぞれのターミナルで実行します。

rl_glue
cd path_to_double-dqn
python experiment.py --csv_dir breakout/csv --plot_dir breakout/plot
cd path_to_double-dqn/breakout
python train.py
cd /home/your_name/ALE
./ale -game_controller rlglue -use_starting_actions true -random_seed time -display_screen true -frame_skip 4 -send_rgb true /path_to_rom/breakout.bin

ALEの–send_rgb はtrueで構いません。falseにするとグレースケールのスクリーンを取得できますが、なぜかALEネイティブのグレースケール変換は不自然だったのでDouble DQN側で変換するようになっています。

実験に用いたコンピュータのスペックは以下の通りです。

OS Ubuntu 14.04 LTS
CPU Core i7
RAM 16GB
GPU GTX 970M 6GB

残念ながらメモリが足りず論文通りのReplay Memory Sizeでは動かないので、サイズを10分の1にしました。

Atari Breakout

Breakout

Breakoutはブロック崩しです。

合計46時間の学習(7600プレイ・95世代・479万フレーム)を行い、DQNとDouble DQNでどちらの性能が優れているかを調べました。

プレイ回数とスコアの関係:

Breakout episode-score

途中でとんでもないスコアを叩きだしていますが、おそらく偶然に背面を通す裏技を発見した可能性が高いです。(確認できませんでした)

Breakout episode-score

プレイ回数とハイスコア:

Breakout episode-highscore

また、$\epsilon–greedy$手法の$\epsilon$を$0.05$に固定して評価を行いました。

学習100プレイごとに評価を20プレイ行い、スコアの平均を取りました。

平均スコア:

Breakout episode-average

見た感じDouble DQNのほうが性能が良さそうですが、どの実験もすべて1回しか行っていないのでなんとも言えません。

1回実験を行うのに40時間くらいかかるのですが、DeepMindの発表によると数時間程度でスコア100を超えるそうなので、私の実装に何か不備があるとしか思えません。

関連