OpenAI UniverseでするAtari Pongの強化学習

オリィ研究所([http://orylab.com/](http://orylab.com/))の畑中です。
今回は2016年12月にOpenAIがリリースしたAI学習プラットフォームUniverseでAIエージェントを育ててみました。

## Universeとは
[公式ブログ](https://openai.com/blog/universe/)の説明が詳しいですが、UniverseはAIの知能を測定・訓練するためのプラットフォームです。汎用人工知能を作ることを目標として作られた環境とのことです。

Universe上でAIエージェントは人間と同じようにコンピュータを利用することで学習を行います。具体的にはエージェントはVNCクライアントとしてピクセルを観察して、キーボード、マウスコマンドを生成することでリモートデスクトップを操作します。キーボード、マウスコマンドを使って制御を行うところがポイントで、これによって既存のプログラムの内部情報を把握していなくとも制御が可能になって、別のタスクにも適用できる汎用性のあるデータが手に入るということのようです。ブラウザ上でのタスクも学習可能で、将来的には[Khan Academy](https://ja.khanacademy.org/)のレッスンなんかも行えるようになるとのことです。



- [OpenAI Universe](https://universe.openai.com/)
- [OpenAI ブログ](https://openai.com/blog/universe/)
- [イーロン・マスクの人工知能研究機関OpenAIがAI学習プラットフォーム「Universe」をリリース](http://gigazine.net/news/20161206-openai-universe/)

## 使ってみる
OpenAIが公開しているUniverse関連のレポジトリです。１つ目のレポジトリだと必要最低限の環境構築をするだけですが、２つ目の方ではTensorFlowで実装されたA3Cアルゴリズムが最初から使えるのでこちらの環境を構築していきます。

- [universe](https://github.com/openai/universe)
- [universe-starter-agent](https://github.com/openai/universe-starter-agent)

## 環境
- macOS Sierra 10.12.2

## 準備
[README](https://github.com/openai/universe-starter-agent)を参考に諸々のパッケージをインストールします。

```
$ conda create --name universe-starter-agent python=3.5
$ source activate universe-starter-agent

$ brew install tmux htop      

$ pip install gym[atari]
$ pip install universe
$ pip install six
$ pip install tensorflow
$ conda install -y -c https://conda.binstar.org/menpo opencv3
$ conda install -y numpy
$ conda install -y scipy
```

pyenv環境下だと２つ目のコマンドの`source activate <env-name>`がシェルごと落ちるというエラーが発生する場合があるので、その場合は

```
$ source $PYENV_ROOT/versions/<version>/bin/activate
```
とactivateをフルパス指定することで回避できます。
こちらを参考にさせていただきました。
[pyenvとanacondaを共存させる時のactivate衝突問題の回避策3種類](http://qiita.com/y__sama/items/f732bb7bec2bff355b69)

他には自分の環境だと、universeのインストールの箇所で

```
Failed building wheel for fastzbarlight
```
とエラーが出たので、

[イーロン・マスク氏が関わるOpenAIの人工知能プラットフォーム「Universe」を動かしてみる](http://blog.morizotter.com/2016/12/29/%E3%82%A4%E3%83%BC%E3%83%AD%E3%83%B3%E3%83%BB%E3%83%9E%E3%82%B9%E3%82%AF%E6%B0%8F%E3%81%8C%E9%96%A2%E3%82%8F%E3%82%8Bopenai%E3%81%AE%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD%E3%83%97%E3%83%A9%E3%83%83/)
<br> こちらのページを参考に[XQuartz](https://www.xquartz.org/)をインストールして、

```
$ brew install Caskroom/cask/xquartz
```
[fastzbarlight](https://pypi.python.org/pypi/fastzbarlight/0.0.14)の手動インストールを行って無事インストールできました。

```python:fastzbarlight/setup.py
# extra_link_args=[os.path.join(os.path.dirname(__file__), 'src/fastzbarlight/vendor/zbar-0.10/zbar/.libs/libzbar.a')],
extra_link_args=[os.path.join(os.path.dirname(__file__), '/usr/local/Cellar/zbar/0.10_3/lib/libzbar.a')],
```

```
$ cd path/to/fastzbarlight
$ python setup.py install
```

それと、VNCサーバとWebSocketサーバを動かすためのコンテナが要るので、Dockerが入ってない方は[Docker for Mac](https://docs.docker.com/docker-for-mac/)から取ってきてインストールしましょう。

これで環境構築は終了です。

## 動作確認
```
$ cd path/to/universe-starter-agent
$ python train.py --num-workers 2 --env-id gym-core.PongDeterministic-v3 --log-dir /tmp/vncpong
```
上記のコードでエージェントに学習させます。フラグは以下のようになってます。

```
--num-workers      並列で学習するワーカの数
--env-id           学習用の環境
--log-dir          学習の中間結果を吐き出すディレクトリ
```

READMEによるとワーカの数はコア数を超えないようにするのがパフォーマンス的に良いようです。


上記のコマンドで以下の４つのプロセスが起動します。

   - 方策勾配法で強化学習を行うプロセス
   - 環境から受け取ったランダムなノイズを利用するプロセス
   - 別々のワーカ間でパラメータを同期させるパラメータサーバ
   - TensorBoardのプロセス

tmuxのセッションも同時に生成されるのでそれぞれのプロセスの状況をウィンドウから確認できます。

```
$ tmux a
$ ctrl-b <window-number>
```


ではMacに標準でインストールされているVNCクライアントソフトを使ってエージェントが学習する様子を見てみましょう。ちなみに何らかの理由ですでに5900ポートが埋まっている場合は、自動でインクリメンタルにポート番号が増えていくので注意です。

```
$ open vnc://localhost:5900
```

以下のような表示になります。左側はtmuxのウィンドウです。
右側のプレイヤがエージェントです。学習開始直後の様子なのでべらぼうに弱いですが動いてはいますね。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="in" dir="ltr">Atari Pong using OpenAI Universe. <a href="https://t.co/pIp14lQaQ5">pic.twitter.com/pIp14lQaQ5</a></p>&mdash; Tatsuya (@thht11) <a href="https://twitter.com/thht11/status/822321904748875776">2017年1月20日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


学習が進むとこんな具合になるようです。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Highly trained AI agent playing Pong on OpenAI Gym. <a href="https://t.co/jQ6zlpZuJR">pic.twitter.com/jQ6zlpZuJR</a></p>&mdash; Tatsuya (@thht11) <a href="https://twitter.com/thht11/status/822364508467249152">2017年1月20日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

ちなみに、`--env-id`を別のもの(e.g. "flashgames.NeonRace-v0")に変えた場合はこんな感じです。デフォルトのA3CアルゴリズムはPong用にチューニングされたもので、おそらく望ましい結果は得られないと思われます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">NeonRace using <a href="https://twitter.com/OpenAI">@OpenAI</a> Universe. <a href="https://twitter.com/hashtag/OpenAI?src=hash">#OpenAI</a> <a href="https://twitter.com/hashtag/DeepLearning?src=hash">#DeepLearning</a> <a href="https://t.co/NfAxBhHxta">pic.twitter.com/NfAxBhHxta</a></p>&mdash; Tatsuya (@thht11) <a href="https://twitter.com/thht11/status/822330654746476545">2017年1月20日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>



## TensorBoardで結果を見る
VNC版だとレイテンシの影響で観測と行動に遅延が生じて学習が難しくなるとのことだったんですが、とりあえず結果をみてみます。
![スクリーンショット 2017-01-20 18.19.40.png](https://qiita-image-store.s3.amazonaws.com/0/59997/ab6ae333-37db-e348-1b91-3a7b303062ff.png)
最初に降下したのが若干気になりますが(おそらく開発機で試したせい)、徐々に報酬(reward)の値が増えていますね。

## A3Cアルゴリズムについて
チューニング等についてはまた別に書きます。
こちらが詳しいです。
[A3Cという強化学習アルゴリズムで遊んでみた話](http://www.slideshare.net/mooopan/a3c-62170605)


## ※補足
ローカルにGPUを使える環境が無いなら、大人しく環境とエージェントの両方を同一リージョンのEC2に置くなどしないとパフォーマンス的に厳しいです。