Microsoft Azure DSVMでUnity ML-Agentsを使用した強化学習を行う

# Microsoft Azure DSVMでUnity ML-Agentsを使用した強化学習
　Unity ML-Agentsでは、PCで開発したUnityアプリのゲームオブジェクトに脳（学習済みモデル）を持たせて動かすことができますが、頭の良い脳を育てるには多くの時間がかかります。育て方には様々な方法がありますが、複数の異なる脳を育てることもできますし、同じ脳を複数のオブジェクト同士を競い合わせて育てることもできます。
　今回は時間のかかる強化学習の学習をUnityでアプリ開発しているPCではなく、コンピュートリソース豊富なAzureのDSVMを使用して実施する方法を紹介します。

## Microsoft Azure DSVMとは
　Data Science Virtual Machine(DSVM)は、機械学習の各種ツールがプレインストールされている便利な仮想マシンです。
　今回使うLinuxのDSVMは、UbuntuとAnacondaをベースに、The Microsoft Cognitive Toolkit, TensorFlow, MXNet, Caffe, Caffe2, Chainer, NVIDIA DIGITS, Deep Water, Keras, Theano, Torch, PyTorch などのDeep Learningツールが初めからインストールされています。また、NシリーズのようなNVIDIA GPUが搭載された仮想マシンを素早く利用するために、NVIDIAドライバ、CUDA、cuDNNも初めからインストールされています。
https://azure.microsoft.com/ja-jp/services/virtual-machines/data-science-virtual-machines/

## Unity ML-Agentsとは
　Unity Machine Learning Agents Toolkit（ML-Agents）は、ゲームオブジェクトに強化学習を適用できるオープンソースのUnityプラグインです。外部のTensorflow環境を使用して学習を行うことが可能であり、生成された学習モデルをゲームオブジェクトを使って推論動作させることもできます。
https://github.com/Unity-Technologies/ml-agents

# ML-Agentsを動かすDSVMの準備
　Microsoft AzureのポータルでDSVMの仮想マシンを作成した後、DSVMでML-Agentsの動作環境を構築します。Microsoft Azureのポータルは以下よりアクセスします。
https://portal.azure.com

## DSVM仮想マシンの作成
　Microsoft Azureのポータルの「リソースの作成」より、"Data Science Virtual Machine"で検索して出てくる「Data Science Virtual Machine for Linux(Ubuntu)」を選択します。
![01.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/9451c1d1-531d-4227-2d9a-a85e1cede543.png)
　仮想マシン作成時の注意点としては次の通りです。ステップ２のサイズ選択では、強化学習を行うため、NC, NVなどのようなNシリーズようなGPUを使っても強化学習内容によっては思っていたほどの効果が出ないかもしれません。ステップ３の設定では、sshのポートだけ使用します。sshを経由してシェルとTensorBoardを利用します。
![04.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/45b2c01a-2396-7c48-bde0-6adcc3b83f3c.png)
## ML-Agentsのインストール
　githubのML-AgentsのリポジトリをDSVMの仮想マシンにクローンします。また、ML-Agentsで利用するPythonのパッケージをインストールします。（以下はDSVMにログインして実行）

```
$ cd ~
$ git clone https://github.com/Unity-Technologies/ml-agents.git
$ cd ml-agents/python
$ conda create -n ml-agents python=3.6
$ source activate ml-agents
$ pip install .
```
# UnityアプリのビルドとDSVMへのコピー
今回はUnityアプリにML-Agentsのサンプルを例として使用します。このサンプルをPCでLinux向けアプリとしてビルドした後、前章で作成したDSVMの仮想マシンにコピーします。
## プロジェクトの作成とTensorFlowSharpの設定
　Unityのプロジェクトを作成してください。次にEdit > Project Settings > Playerから、PlayerSettingsのInspectorの、Display　Resolution DialogをDisableに、Script Runtime Versionを.NET 4.xに、Script Define SymbolsをENABLE_TENSORFLOWとして設定します。

![10.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/b3f8ce5e-36a8-73bc-8186-3c79ae17cc4a.png)
![09.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/7bc63f2d-bb2c-a2f0-e3ba-11a0aec5a789.png)

プロジェクトでは強化学習にTensorflowを使用するため、C#からTensorFlowを使うためのTensorFlowSharpプラグインをインポートします。以下のURLにリンクされている「TensorFlowSharp plugin」をクリックしてプラグインをダウンロードします。

https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Basic-Guide.md

　次に、ダウンロードしたファイルを、Assets > Import Package よりインポートします。

![06.png](https://qiita-image-store.s3.amazonaws.com/0/32580/3a959012-8c9a-9cad-7645-966fa1267271.png)

## サンプルアプリのビルド
　サンプルアプリはML-Agentsのリポジトリに含まれていますのでML-Agentsをクローンします。（gitがインストールされていない場合は、https://github.com/Unity-Technologies/ml-agents よりZipファイルをダウンロードしてください。）（以下はPCで実行）

```
> git clone https://github.com/Unity-Technologies/ml-agents.git
```
　ml-agents\unity-environment\Assets\ML-Agents フォルダ配下にサンプルのシーンがありますので、このML-AgentsフォルダをUnityのアセットに追加します。追加したアセット内の「3D Ball」シーンを開きます。Hierarchyより、Ball3DAcademy（Academy）のBall3DBrain（Brain）を選択し、InspectorのBrain TypeをExternalに設定します。これによりTensorflowを利用して学習を行うことが可能になります。

![07.png](https://qiita-image-store.s3.amazonaws.com/0/32580/c222270a-eb94-e457-15d1-9d9d85dfaccf.png)

次に、ビルドです。AzureのDSVMはLinuxで動作するため、Linux向けのビルド設定をします。File > Build Settingsより、Target PlatformをLinuxにして、Headless Modeにチェックを入れます。Headless Modeのチェックは、DSVMにSSHを使用したターミナルだけで接続するためです。

![08.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/ae866630-de7c-d648-17c3-a232ec34d6b7.png)

ビルドにより作成された実行ファイルは以下のような構成です。（以下はPCで実行）

```
> dir linux-build
2018/08/25  10:57    <DIR>          .
2018/08/25  10:57    <DIR>          ..
2018/08/19  17:00        25,630,440 3DBall.x86_64
2018/08/25  10:57    <DIR>          3DBall_Data
```

これをSCPでDSVMにコピーします。（以下はPCで実行）

```
> scp -r linux-build <ユーザ>@<DSVMのアドレス>:./
```

# DSVMで学習を行う
　DSVMにコピーしたUnityアプリをchmodコマンドで実行できるように変更します。（以下はDSVMで実行）

```
$ cd ~
$ chmod +x linux-build/3DBall.x86_64
```

　学習にはlearn.pyを使用します。オプションとしてコピーしたUnityアプリと学習モードを指定します。（以下はDSVMで実行）

```
$ cd ~
$ source activate ml-agents
$ python ml-agents/python/learn.py linux-build/3DBall.x86_64 --train
```

学習には時間がかかりますが、学習中の状況はTensorbordで表示することが可能です。（以下はDSVMの別ターミナルなどで実行）

```
$ cd ~
$ source activate ml-agents
$ tensorboard --logdir=summaries --host 127.0.0.1
Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
TensorBoard 1.7.0 at http://127.0.0.1:6006 (Press CTRL+C to quit)
```

PCからTensorBoardへのアクセスには、SSHのポートフォワード機能を使用します。SSHのポートフォワード接続が確立された後に、PCのブラウザよりTensorBoardに接続して学習状況を確認します。（以下はPCで実行）

```
> ssh -L 6006:localhost:6006 <ユーザ>@<DSVMのアドレス>
```

PCのブラウザでローカルの6006にアクセスすることにより学習状況を確認することができます。
http://localhost:6006/

![05.PNG](https://qiita-image-store.s3.amazonaws.com/0/32580/102c0ea3-a456-eaf2-a643-05c198ae74d9.png)

# 学習済みモデルの取得と動作確認
DSVMで学習された学習済みモデルは、Unityアプリで使うことができます。まず、学習済みモデルをPCにコピーします。（以下はPCで実行）

```
> scp <ユーザ>@<DSVMのアドレス>:./models/<run-identifier>/3DBall*.bytes <アセットのディレクトリ>
```

Hierarchyより、Ball3DAcademy（Academy）のBall3DBrain（Brain）を選択し、InspectorのBrain TypeをInternalに設定し、Graph ModelにDSVMよりコピーした学習済みモデルを設定します。アプリケーションを実行することにより学習済みモデルを反映したゲームオブジェクトの動きを見ることができます。

![11.png](https://qiita-image-store.s3.amazonaws.com/0/32580/f8d106dd-f9ec-41cc-7280-f0686b7e1033.png)

# さいごに
強化学習を動かしていると、ナルトが多重影分身して修行するシーンを思い出します。Unity ML-Agentsは触ったばかりなので、Azureをもっと活用しながら、もっと面白いことを試してみたいと思います。