Stimulator

機械学習とか好きな技術話とかエンジニア的な話とかを書く

DQN-chainerリポジトリを動かすだけ

- はじめに -

こんにちは. @vaaaaanquishです.
この記事はChainer Advent Calender 2015 11日目の記事です.

今回は滑り込みで, 特に何か新しい事をやった訳でもないですが,
一応記事にする事に意味があると思うので投稿しておきます.

今回はただこれを動かすだけです.

完全に備忘録みたいな感じです. ご了承下さい.
多分誰でもできると思います.


- Deep Q-Networkとは -

Ugo-Nama氏の記事は非常に分かりやすく, Deep Q-Networkに至るまでの研究遷移も書かれており, かなり参考になると思います. ここでは一応の概略のみ記述しておきます.

Deep Q-Networkは強化学習(Reinforcement Learning)の一種であるQ学習(Q-learning)に対して, ニューラルネットワーク(Neural Networks)を多層化したDeep Learningを適応したものです.

まずQ学習とは, 「ある状態 sに対する最も良い行動 aの組み合わせ」となるテーブル関数 Q^{*}(s, a)を求める手法です.  Q^{*}(s, a)を作成するため, 様々な状態のエピソードを試行し,  Q(s, a)を更新します.
 Q(s, a) Q^{*}(s, a)に近付ける際は, 以下の様な更新式を用います.

 {\displaystyle
Q(s, a) ← Q(s, a) + \alpha (r + \gamma \  \max_{a^{'}} Q^{'}(s, a)- Q(s, a))
}

 Q^{*}(s,a)は直接的には得られないので, テーブル関数を用いた Q^{'}(s, a)を用います.
 Q^{'}(s, a)は状態sにおいて行動 aをした次のステップでのQ値です.
また,  \gammaは強化信号の割引率,  \alphaは学習を収束させるための学習率となるパラーメタです.

次にDeep Learningに代表されるニューラルネットワークのような手法では, 最適化の際に勾配法を用いるのが一般的です. 教師データを入力し, パラメータ \thetaを持つ学習器の出力と教師の誤差 L_{\theta}を用いて, 以下のように更新していきます.


\theta ← \theta - \alpha \nabla_{\theta} L_{\theta}

誤差 Lをパラメータ \thetaについて微分し, 足し合わせる事で更新する一般的な式です.
ここで誤差 L_{\theta}に対して強化学習における Q(s, a)を適応した場合, 以下のようになります.


\theta ← \theta + \alpha ( r + \gamma \  \max_{a^{'}} Q^{'}(s, a)- Q(s, a) ) \nabla_{\theta} Q_{\theta}(s,a)

前述した通り強化学習では Q^{*}(s,a)を事前に得る事はできないため, 教師信号として Q^{'}(s, a)を使っている形です. ニューラルネットワーク等におけるback propagationの各層の更新式と見比べたりすると分かりやすいかもしれません.

Deep Learningには様々な手法がありますが, 関数近似手法として上記のように強化学習の枠組みに適応する事で, 複雑で高次元な問題設定に対応する事が可能になりつつあります.


- DQN-chainer実行環境をつくる -

私の環境

  • OS : Ubuntu Server 14.04 LTS (GUI欲しいのでXが入っています.)
  • GPU : NVIDIA Tesla K40 (ラボのマシンです.)
  • Driver : CUDA 6.5 (訳あって6.5なだけで7.0以降でも大丈夫だと思います.)
  • Python : 2.7.6

既にインストールされているものもありますが, できる限り書いていきます.

python, numpy, scipy

言わずと知れた言語と数値計算ライブラリです.
私はPythonUbuntuデフォルトのものを用いています. バージョンは2.7.6です.
numpy, scipyは今後の事を考えるとpipでインストールする方が良いかと思います.
私の環境は研究室の他のメンバーが既にapt-getで入れてますがそれでも大丈夫です.

sudo apt-get install python2.7
sudo apt-get install python-numpy
sudo apt-get install python-scipy

 

・chainer

Deep Learning等をサポートする機械学習ライブラリです. 言わずもがなです. いつも使っています.

入ってない人はpipを導入後, インストールします.

sudo -y apt-get install python-pip
pip install chainer

私は入ってるのでアップデートのオプション"-U"をつけて

pip install -U chainer 

でアップデートしておきます.

よくGPUを利用するためにchainer-cuda-depsを別途インストールするような記載がありますが,
chainer 1.5版以降にすれば別途インストールの必要ないようです.

(chainerを最新版にし, import chainer出来るかどうかテストしておくと良いです.
またCUDAにパスが通り, GPUを操作できるか確認しておきます.
今回動かすリポジトリGPUを用いているため, 少し書き換えないとSegmentation Fault等になります.)

・RL-Glue

強化学習で言う所のエージェントと環境を接続するパッケージです.
RL-Glue - Journal of Machine Learning Research
(http://www.jmlr.org/papers/volume10/tanner09a/tanner09a.pdf)

"強化学習の接着剤"との名前の通り, 実験設定, エージェントの行動, 問題環境の3つを用意する事で, それらを接続してくれるものです.
JavaC/C++をサポートしています.
初めて知ったんですが, 強化学習のベンチマークを行う際には多いらしく, めっちゃ便利そうです.

以下のページからダウンロードします.
RL-Glue Core Project - RL-Glue
https://sites.google.com/a/rl-community.org/rl-glue/Home/rl-glue

最初「.debがあるな」と思い, Ubuntuソフトウェアセンター経由で入れましたが, ソフトウェアセンターからだと実行時に上手く動作しなかったので, ファイルを落として来て自前でコンパイルしました.
(後述のALE実行時にALEが認識できず終了してしまう)
上記ページにあるRL-Glue 3.04 (.tar.gz)を用いました.

解凍したらRL-Glue/docs/内にTechnicalManual.pdfがあるのでそれに従います.
RL-Glueのディレクトリ内で

./configure
make
sudo make install

上手くいかなかった場合のアンインストールはManualを参照して下さい.

・PL-Glue Python codec

先ほどのRL-GlueをPythonで扱えるようにするものです.

以下のページからダウンロードします.
RL-Glue Python codec
https://sites.google.com/a/rl-community.org/rl-glue/Home/Extensions/python-codec

解凍するとディレクトリ直下にPythonCodec.pdfというマニュアルがあるので参考にします.

cd /path/to/codecs/Python
python setup.py install

 

・Aecade-Learning-Environment(ALE)

今回は強化学習における"環境"としてATARIのROMを動かします.
ALEは, エミュレータを基盤にし, ROMファイルをRL-Glueと接続するためのライブラリです.

このページからインストールしてもいいですが, RL-Glueの最新版との互換性から最新版を入れた方が良いと思います.
http://www.arcadelearningenvironment.org/

記事内ではALE v0.4.4を用いていますが, 私はv0.5.0を用いました.
gitリポジトリがあるのでcloneします.

git clone https://github.com/mgbellemare/Arcade-Learning-Environment.git

(※2015年に0.5.1が出たらしく上記コマンドだとそっちが入るみたいです。バージョン絡みでコアダンプするといった報告も受けてるので、そういう時はダウンロードページから0.5.0をzipでダウンロードして解凍すると上手く動く場合があるかもしれません。)

こちらは/doc/manual/内にmanual.pdfがあるので参考にします.

ALEをインストールする前に, 今回ALEでROMを動かすためにディスプレイ表示, 音声出力を行いたいのでSDL(Simple DirectMedia Layer)を用います. SDLをインストールしておきます. mixerは必要ないかもしれません.

sudo apt-get install libsdl1.2-dev
sudo apt-get install libsdl-image1.2-dev
sudo apt-get install libsdl-mixer1.2-dev

次にALE直下にあるMakefileを編集しておきます.
元からあるMakefilemacのものである場合があり, 編集用にmakefile.macmakefile.unixが用意されています.
元のMakefileは削除し, makefile.unixを編集します.
USE_SDL, USE_RLGLUEの2つの項目を以下のように編集し,Makefileとして保存しておきます.

USE_SDL := 1
USE_RLGLUE := 1

編集したらcmakeの後makeします.
cmakeが入ってない場合は

sudo apt-get install cmake

ALEディレクトリで以下を実行します.
make の -j の後の数値はコア数です.
自分のコア数はnprocコマンド辺りでよしなに確認します.

sudo cmake -DBUILD_EXAMPLES=ON
sudo make -j 4

ここで最新版を入れてない, 設定を行ってないと, 実行時に

RL-Glue interface unavailable. Please recompile with RL-Glue support.

のようなエラーが出ると思います. 多分バージョンよりMakefileの方を見なおした方が良いと思います.
SDLとRL-Glueを使う設定をしたか確認すると良いです.

DQN-chainer

ATARIのPong!に対してDQNを適応したリポジトリ, DQN-chainerを使用させて頂きます.
リポジトリ内にはRL-GlueからALEを使う問題設計ファイルとなるexperiment_ale.pyに加えて, DQNのnature実装, nips実装が入っています.
詳しくはリポジトリ内のreadme.txtを読むと良いと思います.
Agentは, 元論文にもあるようにConvolutional Neural Network(CNN)モデルを使っています.

git clone https://github.com/ugo-nama-kun/DQN-chainer.git

 

ATARI ROMs

ATARIのROMファイルを用意します.
私はここからダウンロードしました.
Atari 2600 VCS ROM Collection
http://www.atarimania.com/rom_collection_archive_atari_2600_roms.html

/ROMs/内に各ROMファイルがありますが, Pong!は,
「Video Olympics – Pong Sports (Paddle) (1977) (Atari, Joe Decuir – Sears) (CX2621 – 99806, 6-99806, 49-75104) ~.bin」
みたいになってるので, Pong.bin等に適宜変更しておくと良いかと思います.


- 実行 -

リポジトリ内のreadme.txtにもありますが4つのターミナルを用意します.
それぞれ以下を実行します.

rl_glue
python dqn_agent_nature.py
python experiment_ale.py
./[path to ale] -game_controller rlglue -use_starting_actions true -random_seed time -display_screen true -frame_skip 4 [path_to_roms/pong.bin]

真ん中2つは/DQN-chainer内です.
[path to ale]と[path_to_roms/pong.bin]はALEのディレクトリとROMのあるディレクトリに適宜変更します.
多分ALEのディレクトリの中(ALEのMakefileがある場所)にale実行ファイルがあると思うのでそこめがけてPath書きます.
romへのpathも指定するのでALEディレクトリ外からやった方が吉.

これで多分動くと思います.
画面が出て来て学習が始まると良いです.


- 動画 -

ちょっと12月が想像以上に忙しかったのでTwitter動画で勘弁して下さい.
以下はnature実装を130000stepくらい経過した後の動画です.

かなり勝ちます.


- おわりに -

以上です. 多分あとはchainer実装の部分をイジれば他のアルゴリズムやROMで遊べるようになると思います.

本当はその拡張の部分をメインに書くつもりでしたが, 内定者研修とかいう意味不明な文化に生活を圧迫され, とりあえず動かすまでという記事になった次第です.

ただ, Ugo-Nama氏のDQNの記事もコードも美しいのでかなり理解が進みました.
Advent Calendarをケツカッチンになんとか押し進める事が出来て良かったです.
ありがとうございました.

Deep Learning Advent Calendar 2015の方では, DQNを用いた物体認識タスクについてとそのchainer実装なんかの話を(できれば)したいと思ってますので, そちらの方もよろしくお願いします.