Unity ML-Agentsの学習コンフィグについてまとめてみた

# はじめに
最近、とあるYoutuberの方に影響されて、少し機械学習を触ってみました。
本記事は、その過程で自分が一番困った「学習コンフィグの役目」について、初心者なりに解説するものです。
初めて書く記事なので、拙い部分等あると思われますがご容赦ください。

# 概要
この記事では、[公式ドキュメント](https://unity-technologies.github.io/ml-agents/Training-Configuration-File/)を参考に、ML-Agentsにおける基本的なコンフィグについて、役目とその挙動を簡単に解説します。よければ最後まで見ていってください。


# 学習コンフィグとは？
おそらくこの記事を見ている方は、「環境構築が終わって、さあ学習だ！」という状態の方が多いのではないかと思います。
チュートリアルを終え、いよいよ自分の環境で学習を始めようというときに立ちはだかるのが、この学習コンフィグです。
しかしそんな時も大丈夫、この[公式ドキュメント](https://unity-technologies.github.io/ml-agents/Training-Configuration-File/)を見れば...？

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2016616/693eb179-982b-025d-64bf-365e58731d64.png width=50%>

はい、頭が爆発しますね。私はこれを全て日本語に直してWordにまとめるという暴挙に出ましたが、正直２度とやりたくないです。

そこで、~~第二の被害者を産まないためにも~~今回はここに上ののコンフィグたちが何を意味するのか、まとめておきたいと思います。

# 本題
前置きが長くなりましたが本題です。
必要に応じて、あとがきにあるconfigと一緒に見てください。


|項目名称|説明|
|:----:|:------|
|trainer_type|学習方法を設定する項目。PPO、SAC、POCAがあるがこれについては割愛。`default=PPO`|
|summary_freq|コマンドプロンプトに何ステップごとに学習経過を表示するかの設定。自分は10000にしている。`default=50000`|
|time_horizon|エージェントがどれだけ長期を見据えて行動するかの指標。大きくすればより長い目で報酬を得るように動き、小さくすればより即時的な報酬を優先するようになる。`default=64` |
|max_steps|学習を行うステップ数を指定する。`default=500000`|
|keep_checkpoints|チェックポイントの保存数を指定する。後述する`init_path`で、途中から学習を再開するのに使う。`default=5`|
|checkpoint_interval|チェックポイントの保存間隔をstep数で指定する。`default=500000`|
|init_path|学習を再開するチェックポイントのパスを指定する。拡張子は(.pt)。`default=指定なし`|
|threaded|モデルの更新中にも学習を継続するか否か。PPOであれば変更の必要は基本ない。`default=false`|
|**hyperparamaters**|**以下はハイパーパラメータ(以降HP)のオプションです.**|
|HP-><br>learning_rate|勾配降下法における、初期学習率。最適解に近づこうとする速度に相当する。大きくしすぎるとオーバーシュートするので注意。`default=0.0003`|
|HP-><br>batch_size|一度の学習でモデルにどれだけのデータを与えるか。<br>大きい→学習は早いが過学習する可能性がある。<br>小さい→学習に時間がかかる。`default=記載なし`|
|HP-><br>buffer_size|一度のモデル更新にどれだけの経験を利用するか。<br>大きい→安定するが変化は遅い<br>小さい→変化は早いが不安定<br>`default=10240`|
|HP-><br>learning_rate_schedule|学習量と時間の関係性を表す。<br>liner:終盤に近づくにつれ学習量が減少する。<br>constant:常に一定量学習する<br>`default=linear`|
|**PPO settings**|**以下は、ハイパーパラーメーターのうち、PPOでのみ(?)使用される部分です。**|
|HP-><br>beta|大きければ大きいほどエージェントがランダムに動く。Tensorboardから学習を観察し、エントロピーの項目が緩やかに減少するよう調整するとよい。`defualt=0.005`|
|HP-><br>bera_schedule|betaの値を学習時間に合わせて減少させるか否か。<br>linear:時間とともに減少<br>constant:常に一定<br>`default=linear`|
|HP-><br>epsilon|一度の学習でどれだけ変化が可能であるかの閾値。<br>大きい:学習は早いがあまり安定しない<br>小さい:安定するが学習が遅い<br>`defalut=0.2` `Typical_range=0.1~0.3`|
|HP-><br>epsilon_schedule|epsilonの値を学習時間に合わせて減少させるか否か。<br>linear:時間とともに減少<br>constant:常に一定<br>`default=linear`|
|HP-><br>num_epoch|モデルにおいてデータの学習を何回反復するかの設定。<br>小さい→学習は早いが不安定<br>大きい→学習は長引くが安定<br>`default=3`|
|HP-><br>shared_critic|自身があまり理解できていないため割愛。`default=false`
|**network_settings**|**これより下は[ニューラルネットワーク](https://qiita.com/begaborn/items/3fb064215d7f6e6cce96)の設定(以降NS)になります。**|
|NS-><br>hidden_units|ニューラルネットワークにおける、中間層のユニットの数。単純な問題なら少なく、複雑な問題なら大きくすると良い。`default=128`|
|NS-><br>num_layers|ニューラルネットワークにおける、中間層の数。`default=2`|
|NS-><br>normalize|ネットワークに対する入力に[正規化](https://qiita.com/yShig/items/dbeb98598abcc98e1a57)を行うかどうか。`default=false`|
|NS-><br>vis_encode_type|映像情報で学習を行う際、画像をどれくらい分割して学習させるかを指定する。<br>simple=20x20<br>nature_cnn=36x36<br>resnet=15x15<br>match3=5x5<br>fully_connected=0x0(サイズなし)<br>分割を行うことで、例えば欠けた画像も認識できるようになる。<br>`default=simple`|
|NS-><br>conditioning_type|ニューラルネットワークにおいて、「重み」を最適化しながら学習するか否か。`default=hyper`しないなら`none`|
|**reward_signals**|**これより下は報酬設定(以下RS)の項目です**|
|RS-><br>strength|スクリプトから設定した報酬を、エージェントがどれだけ重視するかの項目。特に変える必要は無い。`default=1`|
|RS-><br>gamma|エージェントが将来の報酬に対しどれほど気を配るか、に相当する値。この値は1未満でなければならない。`default=0.99` `Typical_range=0.8~0.995`|


ここまで読み切った方々、お疲れ様でした。
「色々な項目があって難しそうだ」と感じるかもしれませんが、実のところ`max_steps`と`summary_freq`を変えるだけでも、わりかし快適に学習ができます。
また、上に書いた全てを覚える必要は全くありません。スクショなどに残すか、必要になればまた見にいらしてください。

# 終わりに
今後機械学習を始めるにあたり、役に立つであろうデフォルト値のコンフィグを置いておきます。上の表と照らし合わせつつ見るのがおすすめです。

```yml
behaviors:

  Agent:

    # トレーナー種別
    trainer_type: ppo

    # 基本設定
    summary_freq: 10000

    time_horizon: 64

    max_steps: 1500000

    keep_checkpoints: 5

    checkpoint_interval: 500000

    # init_path: デフォルトでは設定なし

    threaded: false

    # 学習設定
    hyperparameters:

      # PPO、SAC共通

      learning_rate: 0.0003

      batch_size: 512 # デフォルトが載ってなかったのでとりあえず512にしておく

      buffer_size: 10240

      learning_rate_schedule: linear

      # PPO専用

      beta: 0.005

      beta_schedule: linear

      epsilon: 0.2

      epsilon_schedule: linear

      num_epoch: 3

      shared_critic: false

    # ニューラルネットワークの設定
    network_settings:

      hidden_units: 128

      num_layers: 2

      normalize: true

      vis_encode_type: simple

      conditioning_type: hyper
    
    # 報酬設定
    reward_signals:

      extrinsic:

        strength: 1

        gamma: 0.99
```


# あとがき

拙い文章ではありますが、皆様のお役に立てれば幸いです。ありがとうございました。

#### 参考文献
https://unity-technologies.github.io/ml-agents/Training-Configuration-File/

https://qiita.com/yShig/items/dbeb98598abcc98e1a57

https://qiita.com/begaborn/items/3fb064215d7f6e6cce96

https://qiita.com/oreo/items/82183bfbaac69971917f#fn-1