Roboschool を ChainerRL で使ってみる

この投稿は、[Chainer/CuPy Advent Calendar 2018](https://qiita.com/advent-calendar/2018/chainer)の22日目の記事です。

ChainerRL良いですよね！ [強化学習ってなんだか難しい](https://qiita.com/ikeyasu/items/67dcddce088849078b85)ですが、ChainerRLを使えば、強化学習できる気分を味わえます。

でも、別にAtariのゲームを学習させても面白くない！どうせなら、強化学習でロボットを動かしたい！ということで、OpenAIが公開しているOSSのMuJoCoライクなロボットシミュレーション環境 Roboschool を ChainerRL から使ってみたいと思います。

TL;DR
=====

* nvidia-docker2を使う場合
  * `$ docker run --runtime=nvidia -it --name robo -p 6080:6080 ikeyasu/reinforcement-learning:latest`
  * 別のターミナルを開く
  * `$ docker exec -it robo git clone https://github.com/ikeyasu/roboschool_chainerrl.git` 
  * `$ docker exec -it robo /bin/bash -c 'cd roboschool_chainerrl && python3 train.py --gpu 0 --steps=2000000 --minibatch-size=8 --env=RoboschoolAnt-v1 --render'`
* CPUの場合
  * `$ docker run -it --name robo -p 6080:6080 ikeyasu/reinforcement-learning:cpu`
  * 別のターミナルを開く
  * `$ docker exec -it robo git clone https://github.com/ikeyasu/roboschool_chainerrl.git` 
  * `$ docker exec -it robo /bin/bash -c 'cd roboschool_chainerrl && python3 train.py --gpu -1 --steps=2000000 --minibatch-size=8 --env=RoboschoolAnt-v1 --render'`
* ブラウザで http://localhost:6080 を見る

![screen.gif](https://qiita-image-store.s3.amazonaws.com/0/38555/c6432828-39d7-8cc2-d653-41ed39d98b88.gif)

Roboschoolとは
============

[Roboschool](https://github.com/openai/roboschool)というのは、[Open AI](http://openai.com/) が公開している強化学習用のロボットシミュレーション環境です。同様のものとしては、MuJoCoが有名で、強化学習の論文は、MuJoCoを使われているものを数多く見かけます。
しかし、MuJoCoはプロプライエタリのソフトで[安くはありません](https://qiita.com/syo_s/items/88ffa540c2822b2a923c)し、ライセンス的に自由ではないです。

そこで、Open AI が、OSSの物理シミュレーターの[PyBullet](https://pybullet.org/)を使って開発したのが、[Roboschool](https://github.com/openai/roboschool)です。

が、このRoboschool、どうも、Roboschool2が開発中のようで、現行のものは開発が止まっています。
Roboschool2がいつ出てくるかも分からないので、気にせず、Roboschoolを使うことにします。

Roboschool を動かしてみる
=======================

Bullet をビルドしていれなければならないので、[Roboschoolのインストールはそこそこ面倒です。](https://github.com/openai/roboschool#installation) 
なので、Dockerのコンテナイメージを用意しました。

一般的に、Dockerで画面を出す（[参考](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105)）のは面倒なのと、OpenGLをその環境で動作させるのは大変なので、VNCを使うことにしました。ついでに、VNC Viewerも面倒だったので、[noVNC](https://novnc.com)を使って、ブラウザで表示するようにしてみました。

Docker ファイル
https://github.com/ikeyasu/docker-reinforcement-learning

Docker hub
https://hub.docker.com/r/ikeyasu/reinforcement-learning

GPUを使う場合は、[nvidia-docker2を入れて](https://qiita.com/ikeyasu/items/6e1069be9304f8342074) 、以下のように実行して下さい

```bash
$ docker run --runtime=nvidia -it --name robo -p 6080:6080 ikeyasu/reinforcement-learning:latest
```

CPUのみ場合は以下のようにしてください

```bash
$ docker run -it --name robo -p 6080:6080 ikeyasu/reinforcement-learning:cpu
```

ブラウザで、http://localhost:6080 にアクセスしてください。（別のサーバなどで動かしている場合は http://(ip address):6080）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/38555/1f53fcb1-bcad-3771-b938-bb440fe462ac.png)


試しにRoboschool付属のサンプルを動かしてみましょう。
上記のVNCのターミナルに、以下を入力して下さい。

```bash
$ python3 $ROBOSCHOOL_PATH/agent_zoo/demo_race2.py
```
コピーアンドペーストは左のクリップボードボタンで貼り付けた後、ターミナル側でも貼り付けして下さい。

![screen.gif](https://qiita-image-store.s3.amazonaws.com/0/38555/89b08cca-ce05-2666-4c3e-77b0ae634ca5.gif)

ChaineRLで動かしてみる
==================

ChainerRL を Roboschool で動かしてみましょう。
ChainerRLのサンプル及び[AI-BS Summer School 2017のリポジトリ](https://github.com/uchibe/ai-bs-summer17/)を参考に作成しました。

https://github.com/ikeyasu/roboschool_chainerrl

とりあえず動かしてみます。

```bash
$ python3 train.py --gpu 0 --steps=2000000 --minibatch-size=8 --env=RoboschoolAnt-v1 --render
```

以下のように、もぞもぞとランダムに動く4本脚の何かが表示されると思います。
余談ですが、このモデル、"Ant"って名前なのですが、どのあたりが蟻なんだ。。4本脚なのでなんらか動物に近い気もしますが、むしろ蜘蛛にも似ている。。

![screen.gif](https://qiita-image-store.s3.amazonaws.com/0/38555/c6432828-39d7-8cc2-d653-41ed39d98b88.gif)

学習済みモデルは、`out/20YYMMDDT00HHMM.SSSSSS/`のようなディレクトリに保存されています。
上記のコマンドですと、ステップ数2000000が終わると`out/20YYMMDDT00HHMM.SSSSSS/2000000_finish/`に学習済みモデルが保存されています。

これは、以下のようにすると、デモ実行できます。（学習せずに実行します）

```bash
$ python3 train.py --demo --out=demo_out --gpu=-1 --render --env=RoboschoolAnt-v1 --load=2000000_finish/
```

ちなみに、2000000ステップが終わるのに、[このPC](https://qiita.com/ikeyasu/items/db16a5d9fc68fa21b3d5)で5時間半かかりました。
一応、学習済みモデルを置いておきます。

https://github.com/ikeyasu/roboschool_chainerrl/releases/tag/v0.1

ダウンロードして実行するのはこんな感じでできます。

```bash
$ wget https://github.com/ikeyasu/roboschool_chainerrl/releases/download/v0.1/RoboschoolAnt-v1_DDPG_2000000_finish.zip
$ unzip RoboschoolAnt-v1_DDPG_2000000_finish.zip
$ python3 train.py --demo --out=debug_out --gpu=-1 --render --env=RoboschoolAnt-v1 --load=2000000_finish/
```

# その他機能

実はこのレポジトリ https://github.com/ikeyasu/roboschool_chainerrl は、そこそこ多機能で以下のような実装があります。（やりかけも多数ですが。。）

* アルゴリズムは、DDPGとTRPO対応
  * --algorithm オプション
  * ChainerRL様々でアルゴリズムの中身は気にせず実装できた
* [URDF](https://qiita.com/srs/items/35bbaadd6c4be1e39bb9) 及び、[Mujoco XML](http://mujoco.org/book/modeling.html)(mjcf)の対応
  * --urdf 及び、--mjcf オプション
* [角度制御のサーボモーター対応](https://github.com/ikeyasu/roboschool_chainerrl/blob/master/env/gym_forward_walker_servo.py)
  * URDFとmjcfでのみ使えます
* 実物のサーボモーターを動かす
  * 絶賛未完成

それぞれ詳しく説明したいですが、Adventカレンダーの時間が来たので、また別記事にします。

なんか、ChainerRLの話しではなく、周辺の話しばかりでしたが、皆さんRoboschoolで遊んでみると面白いと思います！