Unityでの強化学習が結構たのしい【その１】

#はじめに
「**ねこ品種判定AI**」( https://qiita.com/Gri_Gra/items/e5a507ebae5c4be2be6f ）では、**転移学習**について書きましたが、
今度はUnityで**強化学習**が出来るようになったと知り、早速試して見ました。

Unity ML-Agents自体まだβ版ということもあり、手探り状態でしたが、先人達の知恵を借りながら、なんとか動かすところまではいけたので備忘録も兼ねて。

今回はボールを落とさないように板を動かすというタスクを学習させていきます。学習前はこんな感じ。落ちて来たボールをそのまま受け流してる。
![before_training.gif](https://qiita-image-store.s3.amazonaws.com/0/262969/4e46a782-dde6-4547-b844-cf45c601d50e.gif)
学習後どうなったかは記事の最後でご紹介。

最初はQiita等のページを参考にさせていただいたのですが、どうもうまくいかず。どうやらバージョンアップに伴った仕様変更が原因のようでした。（さすがβ版...）
やはり公式ドキュメントはきちんと読まないとですね...。（英語だからついつい避けてしまう）

#環境
環境は以下の通りです。
**OS**: macOS Sierra(10.12.6)
**Unity**: 17.02.0f3
**Unity ML-Agents**: v0.5

#枠組み
概念の理解は、以下のページが大変参考になりました。
https://qiita.com/dora-gt/items/bacce436de2a3cdb1ef4

今回はgit管理等はとりあえず置いておいて、とりあえず一旦動かすことを目標に実際の作業ベースでメモしていきます。

#インストール
インストールの必要があるのは以下

・**Unity**(2017以降): 
https://store.unity.com/ja
Unityについては多分解説いらないですかね。ページの指示に従ってインストールします。個人利用なら無料で使えます。

・**Unity ML-Agents（強化学習用アセット）**:
https://github.com/Unity-Technologies/ml-agents
Unity ML-Agentsについてはクローンする方法とzipをダウンロードする方法があるようです。私は後者でやりましたが、どちらでも問題ないと思います。
zipをダウンロードする場合は右上にある*'Clone or Download'*の緑のボタンを押して*'Download ZIP'*を選択してください。

・**TensorFlowSharpプラグイン**:
https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Basic-Guide.md
Basic Guide > Setting up the ML-Agents Toolkit within Unity > 文中の Download をクリックしてダウンロード。

・**Python3**（なければ）
以下のコマンドで使っているpythonのバージョンを確認。

```
$ python --version
```

ver=3.X.XX でなければpython3をインストール。

```
$ brew install python3
```

パスを通すのも忘れずに。

ここまででひとまず必要な環境のインストールは完了。

#Unityでシーンを作成
まずはUnityを開いて、新規3Dプロジェクトを作成。

作成したプロジェクトのAssets下にダウンロードした’Unity ML-Agents’のうち、ml-agents-master>UnitySDK>Assets>ML-Agentsの中身をまるごとコピー。
<img width="259" alt="スクリーンショット 2018-09-12 15.59.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/262969/4e50e4f7-937c-74cb-ba5b-60706d00991a.png">

Unityのメニューから Assets > Import Package > Custom Package... でTensorFlowSharpプラグインを選択しインポート。


同様にUnityのメニューから、Edit > Project Settings > Playerで
PlayerSettingタブを開く。そこで以下の設定。
・Resolution and Presentation
　　　　　ーRunin Backgroundをチェック
　　　　　ーDisplay Resolution DialogをDisabled
・Other Settings
　　　　　ーScripting Runtime VersionをExperimental(.NET 4.6 Equivalent) ⇒Unity再起動
　　　　　ーScripting Defined Symbolsに'ENABLE_TENSORFLOW' と記載

先ほどUnityプロジェクトにコピーしてきたフォルダの中からサンプルシーンを開く。（今回は3DBall）
場所は Assets > ML-Agents > Examples > Scenes > 3DBall です。

<img width="1423" alt="スクリーンショット 2018-09-12 16.14.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/262969/0606c1dd-c66c-5c42-3df1-4cd36a336b4e.png">
こんな感じの画面が開けていればOK!

ヒエラルキー（この画面でいうと左上）のBall3DAcademy/Ball3DBrainを選択して右側にインスペクターを表示させる。
Brain.csのところのBrainTypeをExternalに変更。

最後にビルドしてappファイルを作成。具体的にはUnityメニューの File > Build Settingsから 'Add Open Scene'をクリックして先ほど編集した3DBallのシーンを追加。PCを選択し'Build'をクリック。
 
#python側の学習の準備
コマンドライン上でml-agents-master>ml-agentsに移動して以下を打ち込む。必要なパッケージのインストールを行うコマンド。

```
$ pip install .
```

#学習の実行

参考にしていたページのコマンドでは上手くいかず、公式ドキュメントを見てみたらコマンドが変わっていた。
コマンドライン上でml-agents-master>ml-agentsに移動したまま以下を打ち込む。

```
$ mlagents-learn /path/to/config/trainer_config.yaml --env=/path/to/app/[appファイル名].app
```

別画面が立ち上がり、コマンドラインに以下のようなメッセージが表示されて学習の過程が見える。

```
2018-09-XX XX:XX:XX: 
INFO:mlagents.envs:Hyperparameters for the PPO Trainer of brain Ball3DBrain: 
	batch_size:	64
	beta:	0.001
	buffer_size:	12000
　　　　　　　　　　　　　　　　　　　　　　　　　　　・・・
	curiosity_enc_size:	128
INFO:mlagents.trainers: cob_1-0: Ball3DBrain: Step: 1000. Mean Reward: 1.236. Std of Reward: 0.689. Training.
INFO:mlagents.trainers: cob_1-0: Ball3DBrain: Step: 2000. Mean Reward: 1.330. Std of Reward: 0.745. Training.
・・・
```

#学習結果
【学習初期】
![before_training.gif](https://qiita-image-store.s3.amazonaws.com/0/262969/5df4e42e-e3b3-6fc2-0f92-bd93bba6d4f0.gif)
【35000step後】
![after_training.gif](https://qiita-image-store.s3.amazonaws.com/0/262969/ec18f6c7-fb5c-6bbd-d849-f437e35c2398.gif)
待ちきれなくて35000stepで切り上げので、若干たどたどしさはありますが、ボールがほとんど落ちなくなっています。やったぜ。

学習条件を変更したい場合は、trainer_config.yamlファイルの中身を変更すれば良いのだと思います。


次回以降は自分でシーンを作成して学習させていく予定です。