ML-Agents Python Low Level API入門：強化学習環境の作成その4

# はじめに
今回はUnityの設定を行い、強化学習環境を完成させます。その3までに比べて、比較的簡単なのでサクサク進めていきましょう。

# JumpAgentのインスペクタ設定
```JumpAgent```コンポーネントはpublic変数を2つ持っているので、以下のように指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412657/6d6539ac-718f-2ff7-8978-053382e7f583.png)
```Max Step```はエピソードを終了するまでの最大のステップ数です。0に指定すると無制限になります。今回のような単純な環境だと起こりにくいですが、学習中に同じようなことを延々繰り返して生き残り続ける(いわゆる嵌め状態)ことがあります。そのような学習データが大量に集まっても学習が正常に進まないので一定のステップ数で学習を止め、新しいエピソードを開始することができます。今回は5000に設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412657/4a39ca25-81af-fc4c-2da4-40cc2799d67e.png)

# Behavior Parametersの設定
```Behavior Parameters```コンポーネントには学習を進めるために必要な情報を設定します。

- ```Bahavior Name```：観測と行動をまとめた識別子で、ひとつの強化学習モデルに相当します。今回のように単一のエージェントが学修する場合には意味を感じにくいですが、ひとつの環境内で「攻撃側」と「防御側」に分かれてそれぞれが特有の行動を持っているならば、当然強化学習のモデルも別になり、それを識別するためのIDが必要になります。サンプルコードでは、"Jump"と設定しておきます。
- ```Model```：強化学習のモデルを設定します。mlagents-learnを使用する場合にはmlagents learnコマンドで自動的に生成されるONNXファイルを指定することで学習させることができます。しかし、本連載ではLow Level APIを用いた自力での強化学習モデル構築を行っていくので使用できません。この問題の解決については次回以降の記事で解説します。
- ```Behavior Type```：重要なので後述します
- ```Team Id```：複数のエージェントが協力するようなタスクで使用しますが、今回はどんな値を設定してもよく、デフォルトのままにします。
- ```Use Child Sensors```：センサーについては次回以降の記事で解説します。今回はどのような値を設定しても挙動には影響しませんので、デフォルトのままにします。
- ```Observable Attribute Handling```：センサーと同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412657/0bf1076b-d7a2-ac20-93ee-e01d9de63fa3.png)

# Decision Requesterのアタッチ
ここまでで作成してきたメソッドを利用してstepを具体的に実行していくには、まだ不足している機能があります。それは決定を要求して、stepを起動するための機能です。これまでには「行動→報酬→観測」という流れを実装してきたので、このstepを具体的に誰かが呼び出す必要があるのです。このためには2種類の方法があります。
## 手動で呼び出す方法
Unityの```FixedUpdate```などから```Agent.RequestDecision```というメソッドを呼ぶと、エージェントはBrainに対して行動の決定を要求して、Brainは何らかの方法で決定を作成して、その結果を```OnActionReceived```に```ActionBuffer```として与えます。これはターン制ゲームなどに有効です。
## 自動で呼び出す方法
今回採用する方法はこちらです。Agentゲームオブジェクトに```Decision Requester```をアタッチすると、自動的に一定時間間隔で```Agent.RequestDecision```を呼び出してくれます。今回のような一定時間ごとに判断を下す必要があるタスクの場合には、こちらの方法が楽です。もちろん、単にFixedUpdateなどでおなじことをしてもかまいません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412657/66ee5e5b-46e3-3fdc-1197-30f12c5a6fdb.png)
- ```Decision Period```：行動をするstepの間隔を指定します。これまで、stepとは「決定→行動→観測」の流れだと説明してきましたが、1ステップでの変化が少ないシミュレーションのタスクの場合には、あまりに細かい観測と行動は経験の多様性を下げ、サンプリング効率が下がってしまいます。そこで観測だけをして、決定を要求せずしないというstepを作成することで、学習を高速化しています。1を指定すると、すべてのstepで決定を要求します。
- ```Take Actions Between Decisions```：上で説明した、決定が要求されないようなstepでの行動についての設定です。これがチェックされていると、決定されなかったフレームには```OnActionReceived```が呼び出され、その引数の```ActionBuffers```はすべてが0のデフォルトの行動をとるようになります。


# ヒューリスティックモードの実装
先ほどDefaultのままにしておいた```Bahavior Type```の解説を行います。これは、行動の決定方法についての設定です。以下の3通りの設定ができます。

- ```Default```：Pythonプログラムの指示に従って行動します。学習用の設定です。
- ```Heuristic Only```：プレイヤーの指示に従ったり、ルールベースだったりで行動します。動作確認用の設定です。
- ```Inferrence Only```：与えられた訓練済み強化学習のモデルに従って行動します。実践用の設定です。

その2の記事では、```FixedUpdate```メソッドにユーザーのキー操作に反応して動く操作を実装しましたが、それをML-Agentsの仕組み、すなわちエピソードや報酬などの仕組みにのせつつテストするための仕組みがヒューリスティックモードです。それでは```Behavior Type```を```Heuristic Only```に設定したうえで、その2の記事の```ControlPlayer1```の```FixedUpdate```を参考に実装をしてみましょう。

```JumpAgent.cs
    public override void Heuristic(in ActionBuffers actionsOut)
    {
        var discreteActions = actionsOut.DiscreteActions;
        if (Input.GetKey(KeyCode.Z) && ControlPlayer.CanJump)
        {
            discreteActions[0] = 1;
        }
        else
        {
            discreteActions[0] = 0;
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            discreteActions[1] = 0;
        }else if (Input.GetKey(KeyCode.RightArrow))
        {
            discreteActions[1] = 2;
        }
        else
        {
            discreteActions[1] = 1;
        }
    }
```
```ControlPlayer```と異なるのは、直接ジャンプや移動を行うのではなく```discreteActions```を通じてActionを設定していることです。その理由は、これが強化学習のモデルに代わって決定を作成するためのメソッドであることです。

# エージェントを使ってみる
ここまで実装することによって、実際に強化学習環境でエージェントを操作できるようになりました。実際にPlayModeでエージェントを操作してみましょう。ジャンプや移動を行えるのはそのままですが、それと同時に赤い敵にぶつかるとリセットされること、落下してもリセットされることが分かります。これは、エピソードというML-Agentsの仕組みに自作の環境を組み込むことができたということを意味しています。

# おわりに
ここまでで、基本的な環境作成についての実装方法はマスターできたことになります。実はML-Agentsを使ったこの環境は、Pythonから自由に操作できます。次回以降、Low Level APIを使ってこの環境で強化学習アルゴリズムを試していきましょう。