強化学習フレームワーク Google Dopamine をつかってみた。

# はじめに
Google Brainチームが突如公開した強化学習フレームワークGoogle Dopamineをためしにつかってみよう！

- http://tensorflow.classcat.com/2018/08/30/tensorflow-dopamine-readme/
- https://www.publickey1.jp/blog/18/googletensorflowdopamine.html
- https://mag.osdn.jp/18/08/29/163000

# Dopamineとは
## 特長
Dopamineとは、Google 2018/08/27に公開した強化学習アルゴリズムのフレームワーク。以下の4つの特長を有する。

- Easy experimentation  
  ユーザーがベンチマーク実験を簡単に実行できる。
- Flexible development  
  ユーザーが研究のアイデアを簡単に試すことができる。
- Compact and reliable  
  いくつかのテスト済みアルゴリズムの実装を提供する。
- Reproducible  
  結果の再現性を促進する。 

## ファイル構成
Dopamineのファイル構成は以下の通り。

- agents  
  エージェントの実装が含まれる。
- atari  
  実験や前処理コードを実行するコードを含むAtari固有のコードが含まれる。
- common  
  ロギングとチェックポイントを含む追加の便利機能が含まれる。
- replay_memory  
  ドーパミンで使用される再生メモリスキームが含まれる。
- colab  
  実験の結果を検査するためのコードと、サンプルのcolabノートが含まれる。
- tests  
  すべてのテストファイルが含まれる。 

# Dopamineのインストール
## コンテナ実行
nvidia-dockerでtensorflowのコンテナを実行する。

```sh
nvidia-docker run -it tensorflow/tensorflow:latest-gpu-py3 /bin/bash
```

## インストール

次にGoogle大先生の[README.md](https://github.com/google/dopamine#ubuntu)にしたがってインストール。

```sh
apt-get update
apt-get install -y cmake
pip install dopamine-rl
pip install atari-py
```

# 動作確認

Google大先生の[README.md](https://github.com/google/dopamine#ubuntu)を参考に動作確認しよう。

## 準備

まず、ソースをクローンする。

```sh
apt-get install -y git
git clone https://github.com/google/dopamine.git
cd dopamine
```

## テスト

テストスクリプトを実行する。

```sh
# python tests/atari_init_test.py
Traceback (most recent call last):
  File "tests/atari_init_test.py", line 23, in <module>
    from dopamine.atari import train
  File "/usr/local/lib/python3.5/dist-packages/dopamine/atari/train.py", line 29, in <module>
    from dopamine.atari import run_experiment
  File "/usr/local/lib/python3.5/dist-packages/dopamine/atari/run_experiment.py", line 26, in <module>
    from dopamine.atari import preprocessing
  File "/usr/local/lib/python3.5/dist-packages/dopamine/atari/preprocessing.py", line 29, in <module>
    import cv2
  File "/usr/local/lib/python3.5/dist-packages/cv2/__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: libSM.so.6: cannot open shared object file: No such file or directory
```

当然のようにエラー・・・解せぬ。
エラーが出てるcv2はopencv-python関係。有名なライブラリだけど依存関係めんどいよな・・・。
足りないライブラリをインストール。

```sh
apt install -y libsm6
```

再実行。

```sh
# python tests/atari_init_test.py 
Traceback (most recent call last):
  File "tests/atari_init_test.py", line 23, in <module>
    from dopamine.atari import train
  File "/usr/local/lib/python3.5/dist-packages/dopamine/atari/train.py", line 29, in <module>
    from dopamine.atari import run_experiment
  File "/usr/local/lib/python3.5/dist-packages/dopamine/atari/run_experiment.py", line 26, in <module>
    from dopamine.atari import preprocessing
  File "/usr/local/lib/python3.5/dist-packages/dopamine/atari/preprocessing.py", line 29, in <module>
    import cv2
  File "/usr/local/lib/python3.5/dist-packages/cv2/__init__.py", line 3, in <module>
    from .cv2 import *
ImportError: libXrender.so.1: cannot open shared object file: No such file or directory
```

当然のようにエラー・・・解せぬ。
足りないライブラリをインストール。

```sh
apt install -y libxrender1
```

再実行。

```sh
# python tests/atari_init_test.py 
/usr/local/lib/python3.5/dist-packages/gym/envs/registration.py:14: DeprecationWarning: Parameters to load are deprecated.  Call .resolve and .require separately.
  result = entry_point.load(False)
2018-09-01 23:25:27.437013: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
I0901 23:25:27.438280 140230154077952 tf_logging.py:115] Creating DQNAgent agent with the following parameters:
I0901 23:25:27.438604 140230154077952 tf_logging.py:115] 	 gamma: 0.990000
I0901 23:25:27.438693 140230154077952 tf_logging.py:115] 	 update_horizon: 1.000000
I0901 23:25:27.438756 140230154077952 tf_logging.py:115] 	 min_replay_history: 20000
I0901 23:25:27.438801 140230154077952 tf_logging.py:115] 	 update_period: 4
I0901 23:25:27.438845 140230154077952 tf_logging.py:115] 	 target_update_period: 8000
I0901 23:25:27.438887 140230154077952 tf_logging.py:115] 	 epsilon_train: 0.010000
I0901 23:25:27.438936 140230154077952 tf_logging.py:115] 	 epsilon_eval: 0.001000
I0901 23:25:27.438985 140230154077952 tf_logging.py:115] 	 epsilon_decay_period: 250000
I0901 23:25:27.439033 140230154077952 tf_logging.py:115] 	 tf_device: /gpu:0
I0901 23:25:27.439080 140230154077952 tf_logging.py:115] 	 use_staging: True
I0901 23:25:27.439127 140230154077952 tf_logging.py:115] 	 optimizer: <tensorflow.python.training.rmsprop.RMSPropOptimizer object at 0x7f89a0e27eb8>
I0901 23:25:27.440419 140230154077952 tf_logging.py:115] Creating a OutOfGraphReplayBuffer replay memory with the following parameters:
I0901 23:25:27.440495 140230154077952 tf_logging.py:115] 	 observation_shape: 84
I0901 23:25:27.440555 140230154077952 tf_logging.py:115] 	 stack_size: 4
I0901 23:25:27.440608 140230154077952 tf_logging.py:115] 	 replay_capacity: 100
I0901 23:25:27.440658 140230154077952 tf_logging.py:115] 	 batch_size: 32
I0901 23:25:27.440706 140230154077952 tf_logging.py:115] 	 update_horizon: 1
I0901 23:25:27.440754 140230154077952 tf_logging.py:115] 	 gamma: 0.990000
I0901 23:25:28.310365 140230154077952 tf_logging.py:115] Beginning training...
W0901 23:25:28.310532 140230154077952 tf_logging.py:125] num_iterations (0) < start_iteration(0)
..
----------------------------------------------------------------------
Ran 2 tests in 1.024s

OK
```

成功した。
・・・ん！なぜCPU使っている？GPUサポートのはず・・・。

tensorflowが認識しているデバイスを確認。

```python
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from tensorflow.python.client import device_lib
>>> device_lib.list_local_devices()
2018-09-02 00:15:41.382144: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 11600111376506808747
]
```

GPUがなくなってる。解せぬ・・・。
最初はこうだったはずなんや。

```python
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 17574043989876159965
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 1403781120
locality {
  bus_id: 1
  links {
  }
}
incarnation: 3799542003315464865
physical_device_desc: "device: 0, name: Quadro K620, pci bus id: 0000:01:00.0, compute capability: 5.0"
]
```

どうもdopamineをインストールするときに依存関係のあるtensorflowが自動でインストールされてtensorflow-gpuがつかわれなくなるらしい。

```sh
# pip install dopamine-rl
Collecting dopamine-rl
  Downloading https://files.pythonhosted.org/packages/a3/60/ce40162119275f8961b79ee16d98038f4ca85c2b449daced3b5900952c27/dopamine_rl-1.0.2-py3-none-any.whl (65kB)
    100% |################################| 71kB 7.3MB/s 
Requirement already satisfied: absl-py>=0.2.2 in /usr/local/lib/python3.5/dist-packages (from dopamine-rl) (0.4.0)
（中略）
Collecting tensorflow (from dopamine-rl)
  Downloading https://files.pythonhosted.org/packages/50/83/4b61843f9438b4f27eb16b277e6320e38698144d8608f6281abbdd45532b/tensorflow-1.10.1-cp35-cp35m-manylinux1_x86_64.whl (58.4MB)
    100% |################################| 58.4MB 1.2MB/s 
（中略）
```

そこで、tensorflowをアンインストールしてtensorflow-gpuを再インストールする。

```sh
pip uninstall tensorflow tensorflow-gpu
pip install tensorflow-gpu
```

再度実行する。

```sh
# python tests/atari_init_test.py 
/usr/local/lib/python3.5/dist-packages/gym/envs/registration.py:14: DeprecationWarning: Parameters to load are deprecated.  Call .resolve and .require separately.
  result = entry_point.load(False)
2018-09-02 00:29:59.540394: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2018-09-02 00:29:59.597419: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:897] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2018-09-02 00:29:59.597877: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1405] Found device 0 with properties: 
name: Quadro K620 major: 5 minor: 0 memoryClockRate(GHz): 1.124
pciBusID: 0000:01:00.0
totalMemory: 1.95GiB freeMemory: 1.59GiB
2018-09-02 00:29:59.597894: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1484] Adding visible gpu devices: 0
2018-09-02 00:30:00.129133: I tensorflow/core/common_runtime/gpu/gpu_device.cc:965] Device interconnect StreamExecutor with strength 1 edge matrix:
2018-09-02 00:30:00.129164: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971]      0 
2018-09-02 00:30:00.129187: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] 0:   N 
2018-09-02 00:30:00.129377: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1097] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1339 MB memory) -> physical GPU (device: 0, name: Quadro K620, pci bus id: 0000:01:00.0, compute capability: 5.0)
I0902 00:30:00.144526 140558848235264 tf_logging.py:115] Creating DQNAgent agent with the following parameters:
I0902 00:30:00.144884 140558848235264 tf_logging.py:115] 	 gamma: 0.990000
I0902 00:30:00.144986 140558848235264 tf_logging.py:115] 	 update_horizon: 1.000000
I0902 00:30:00.145088 140558848235264 tf_logging.py:115] 	 min_replay_history: 20000
I0902 00:30:00.145177 140558848235264 tf_logging.py:115] 	 update_period: 4
I0902 00:30:00.145226 140558848235264 tf_logging.py:115] 	 target_update_period: 8000
I0902 00:30:00.145297 140558848235264 tf_logging.py:115] 	 epsilon_train: 0.010000
I0902 00:30:00.145355 140558848235264 tf_logging.py:115] 	 epsilon_eval: 0.001000
I0902 00:30:00.145411 140558848235264 tf_logging.py:115] 	 epsilon_decay_period: 250000
I0902 00:30:00.145462 140558848235264 tf_logging.py:115] 	 tf_device: /gpu:0
I0902 00:30:00.145518 140558848235264 tf_logging.py:115] 	 use_staging: True
I0902 00:30:00.145569 140558848235264 tf_logging.py:115] 	 optimizer: <tensorflow.python.training.rmsprop.RMSPropOptimizer object at 0x7fd5d63d9ba8>
I0902 00:30:00.147667 140558848235264 tf_logging.py:115] Creating a OutOfGraphReplayBuffer replay memory with the following parameters:
I0902 00:30:00.147766 140558848235264 tf_logging.py:115] 	 observation_shape: 84
I0902 00:30:00.147877 140558848235264 tf_logging.py:115] 	 stack_size: 4
I0902 00:30:00.147933 140558848235264 tf_logging.py:115] 	 replay_capacity: 100
I0902 00:30:00.147994 140558848235264 tf_logging.py:115] 	 batch_size: 32
I0902 00:30:00.148046 140558848235264 tf_logging.py:115] 	 update_horizon: 1
I0902 00:30:00.148096 140558848235264 tf_logging.py:115] 	 gamma: 0.990000
I0902 00:30:01.003550 140558848235264 tf_logging.py:115] Beginning training...
W0902 00:30:01.003716 140558848235264 tf_logging.py:125] num_iterations (0) < start_iteration(0)
..
----------------------------------------------------------------------
Ran 2 tests in 1.632s

OK
```

GPUで実行できた。

## 学習

学習させてみる。

```sh
python -um dopamine.atari.train --agent_name=dqn --base_dir=/tmp/dopamine --gin_files='dopamine/agents/dqn/configs/dqn.gin'
```

一応、GPUが働いてるかどうかnvidiaのコマンドで確認する。

```sh
# nvidia-smi 
Sun Sep  2 09:37:18 2018       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130                Driver Version: 384.130                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Quadro K620         Off  | 00000000:01:00.0  On |                  N/A |
| 60%   72C    P0    15W /  30W |   1898MiB /  1997MiB |     73%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      4481      C   python                                      1542MiB |
（中略）
+-----------------------------------------------------------------------------+
```

はたらいてるじゃねぇか。しかし、時間はかかる・・・。
ここで朝ごはんタイム:fork_and_knife:

# 参考サイト
- 強化学習フレームワークgoogle dopamineインストール、テストまで https://qiita.com/uni-3/items/643e25027981adc5b201
- Google製の強化学習フレームワークDopamineを使ってみる(途中) https://qiita.com/t-Asai/items/6f2a55c1f408f88aef36