PPO で学習させる際のベストプラクティス

# 前書き
　前回は [Unity で ml-agents を使う時のベストプラクティス](https://qiita.com/dora-gt/items/c4fb4a1ce1b27da66f9a) を書きました。これをベースにした上で、実際にやってみたところ、色々と設定が難しい事が分かりました。

　何が難しいかと言うといわゆる「ハイパーパラメータ」と呼ばれる、ディープラーニングで自動的に設定されていくニューラルネットワーク上のパラメータ以外の**人間が設定しなければいけないパラメータ**の設定がそれなりに意味深いものになっており、かつその設定が難しいという事です。

　その様な話を ml-agents の github で開発者としていた所、[Best Practices when training with PPO](https://github.com/Unity-Technologies/ml-agents/blob/master/docs/best-practices-ppo.md) という記事を Unity のエンジニアが書いてくれたのでこれを翻訳してみようと思います。

　なお、前提知識として ML-Agents を一度も使った事がない人にはいくつかの専門用語が分からないものになっている可能性があります。もし個別に分からない部分があればコメントなどでご質問頂ければ分かる範囲でお答えします。

　追記。Epsilon, Hidden Units, Learning Rate は個人的にすごく改善したので、状況にはよると思いますが、試してみるといいかと思います。

　さらに追記。PPO 自体について、強化学習自体については Qiita の以下の記事がとても参考になります。是非見てみて下さい。

- [これから強化学習を勉強する人のための「強化学習アルゴリズム・マップ」と、実装例まとめ](https://qiita.com/sugulu/items/3c7d6cbe600d455e853b)
- [【強化学習】実装しながら学ぶPPO【CartPoleで棒立て：1ファイルで完結】](https://qiita.com/sugulu/items/8925d170f030878d6582)

# PPO で学習させる際のベストプラクティス
　強化学習のモデルを学習させるプロセスは望ましいレベルのパフォーマンスを獲得するために、しばしばハイパーパラメータを調整する必要があります。

　このガイドは、デフォルトのハイパーパラメータがあなたの望んでいるレベルのパフォーマンスを提供できていない様に見える時に、学習プロセスをチューニングする際のいくつかのベストプラクティスを示したものです。

## ハイパーパラメータ

### Batch Size（バッチサイズ）
　`batch_size` はどれだけのデータが一度に勾配下降でアップデートする時に使われるかを指します。この数値は常に `buffer_size` の分数でなければなりません（例えば `buffer_size` が `2048` なら `512` などの割り切れる数）。もしあなたが連続的（continuous）なアクション空間を利用している場合は、値は大きい必要があります。離散的（discrete）なアクション空間を利用している場合は、値は小さい必要があります。

- 一般的な値のレンジ（continuous）: `512` - `5120`
- 一般的な値のレンジ（discrete）: `32` - `512`

### Beta（ベータ）
　`beta` はエントロピーの正則化の強さを指します。この値は離散的なアクション空間を利用しているエージェントが学習中に適切に探索ができる様にします。この値を大きくすると、よりランダムなアクションが取られる様になります。この値は報酬が徐々に上昇するのと同時にエントロピー（TensorBoard で閲覧可能）が徐々に減少する様に調整される必要があります。もしエントロピーが減少するのが早すぎる場合は、`beta` を上げてみるとよいでしょう。逆にエントロピーが減少するのが遅すぎる場合は、`beta` を減らしてみるとよいでしょう。

- 一般的な値のレンジ: `1e-4` - `1e-2`

### Buffer Size（バッファサイズ）
　`buffer_size` は勾配下降が行われる前にどれだけのデータを収集するかを指します。この値は `batch_size` の倍数でなければなりません。

- 一般的な値のレンジ: `2048` - `409600 `

### Epsilon（イプシロン）
　`epsilon` は勾配下降のアップデートが行われる際に、新しいポリシーと古いポリシーの差をどこまで受け付けるかになります。この値を小さくすると、突発的な学習が行われてポリシーが壊れる事を防いでくれます。詳しくは [PPO の論文](https://arxiv.org/abs/1707.06347)を参照するとよいでしょう。

- 一般的な値のレンジ: `0.1` - `0.3`

### Hidden Units（隠れ層の要素数）
　`hidden_units` はニューラルネットワークのそれぞれ接続されたレイヤーにどれだけの要素があるかを指します。状態のインプットに対して正しいアクション（出力）が分かりやすい組み合わせになる様な簡単な問題の場合は、この値は小さくてよいでしょう。状態のインプットとアクション（出力）が複雑に絡み合う様な問題の場合は、この値は大きい方がよいでしょう。

- 一般的な値のレンジ: `32` - `512`

### Learning Rate（学習率）
　`learning_rate` は勾配下降のそれぞれのステップの強さを指します。もし学習が不安定で報酬が継続的に増加しない様な場合は、この値を小さくするのが一般的です。

- 一般的な値のレンジ: `1e-5` - `1e-3`

### Number of Epochs
　`num_epoch` はデータセットを何度勾配下降にかけるかを指します。`batch_size` が大きければ、この値を大きくする事ができるでしょう。

- 一般的な値のレンジ: `3` - `10`

### Time Horizon
　`time_horizon` はバッファに積む前にエージェントあたりどれだけの経験のデータ（ステップ）を収集するかを指します。エピソード内で頻繁に報酬が与えられる、あるいはエピソードが非常に多い様なケースでは小さな値にする可能性があります。一方で、ほとんどの安定した学習プロセスでは、この値はエージェントの一連のアクションの全ての重要な振る舞いを得るために、大きな値であるべきです。

- 一般的な値のレンジ: `64` - `2048`

## 学習統計

　学習統計を見るには、TensorBoard を利用して下さい。TensorBoard の起動方法、利用方法についての情報は[こちら](https://github.com/Unity-Technologies/ml-agents/blob/master/Getting-Started-with-Balance-Ball.md#observing-training-progress)を参考にして下さい。

### Cumulative Reward

　報酬の一般的なトレンドとしては、時間が経つにつれて継続的に増加すべきです。上下の振れ幅は小さい事が期待されます。

### Entropy

　ブレインの意思決定がどれだけランダムかを指します。学習のプロセスを通じて、この値は継続的に低下していくべきです。もしこの値がすぐに低下してしまう場合や、全く低下しない場合は、`beta` の値を調整して下さい（離散的なアクション空間を利用している場合）。

### Learning Rate

　学習率は、線形なスケジュールに則って時間とともに減少していきます。

### Policy Loss

　学習のプロセス中、変動します（※どういう状態が正しいのかについては触れられていない）。

### Value Estimate

　報酬とともに増加していくべきです。この値は、その時点でエージェント自身が予測した将来的に受け取るであろう報酬の値を指しています。

### Value Loss

　この値は報酬が増えるに従って増加し、報酬が安定したら減少すべきです。この値は、自身の予測と実際の報酬がどれだけかけ離れたものだったかを指します。