AWS DeepRacerのはじめかた（8）参考情報 モデルのトレーニングと評価

## 目次（投稿一覧）
1. [DeepRacerのはじめかた（1）概要と目次](https://qiita.com/tagucchan/items/06cb3c5c81de766ebe59)
2. [DeepRacerのはじめかた（2）サービスの利用開始と参考費用](https://qiita.com/tagucchan/items/7c80d7e3f872b51e218e)
3. [DeepRacerのはじめかた（3）最初のエンジンを作成](https://qiita.com/tagucchan/items/b3e4a03455ee74becd0e)
4. [DeepRacerのはじめかた（4）Evaluation（作成したエンジンを評価）](https://qiita.com/tagucchan/items/1fd99f35061c7a21839f)
5. [DeepRacerのはじめかた（5）ログの場所](https://qiita.com/tagucchan/items/4f69306cf3c552bfcbdd)
6. [DeepRacerのはじめかた（6）モデルのダウンロード方法](https://qiita.com/tagucchan/items/a228cb4d529716bddab9)
7. [DeepRacerのはじめかた（7）Virtual Circuit](https://qiita.com/tagucchan/items/0281d8f99b0386cbbd78)
8. [DeepRacerのはじめかた（8）参考情報 モデルのトレーニングと評価](https://qiita.com/tagucchan/items/14ce383d2a5775aa3f49)　**← 表示中**

### 本資料は私が主催する　AI・データ解析　もくもく会　の参加者（初心者）向け資料です。
AWS・強化学習にはじめて取り組まれる方向けの、参考情報となっています。

## ご注意
**私はデータサイエンティストおよびAWSのプロではありません**
**不備等も多々あると思いますが、ご容赦下さい。**
**また、記載事項を参考にされる場合は、自己責任でお願いいたします！！**

### もくもく会に参加される方へ
強化学習や関連テーマへの取り組みは大変だと思いますので、一緒に勉強するメンバーを募集されることを強く推奨します。
個人戦の気配がしているので。。。
一応、お願いしておきます。。。

## 公式ドキュメント　へのリンク
[AWS DeepRacer 開発者ガイド](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/index.html)
[AWS DeepRacer モデルのトレーニングと評価](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/create-deepracer-project.html)
[Input Parameters of the AWS DeepRacer Reward Function](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/deepracer-reward-function-input.html)

## ロボットの動作を定義する
### Action space
ロボットがシミュレータと物理的な世界の両方で実行できる具体的なアクションを定義します。
トレーニング終了後、モデルを *clone* してトレーニングを続けることはできますが、*Action space*のパラメータをその際に変更することはできませんので、注意してください。
![WS20190519220523_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/8f4ac5a1-7b7a-60cf-44b8-89496104578a.jpeg)

1周できるモデルを作成したい方向けに、完走しやすい／しにくいを記載しています。
学習の方針や、組み合わせ方によって結果は変わりますので、どちらが良いかは一概には決まりません。

- 項目：Maximum steering angle
   - 機能：アクション（舵角／ハンドルを切る角度 の最大）を定義、単位は度
      - 大きいと、コーナーを曲がりやすいが、走行ラインがふらつく（完走しやすい）
      - 小さいと、コーナーを曲がりにくいが、走行ラインが安定する（完走しにくい）

- 項目：Steering angle granularity
   - 機能：アクション（舵角／ハンドルを切る角度 の粒度）を定義
      - 大きいと、舵角／ハンドルを切る角度を丁寧に調整するモデルができる可能性がある（完走しやすい）
      - 小さいと、舵角／ハンドルを切る角度を素早く調整するモデルができる可能性がある（完走しにくい）

- 項目：Maximum speed
   - 機能：アクション（最大速度）を定義、単位はm/s
      - 大きいと、完走できた際のタイムが早くなるが、コーナーを曲がりにくい（完走しにくい）
      - 小さいと、完走できた際のタイムが遅くなるが、コーナーを曲がりやすい（完走しやすい）
      - 世界最速を狙うなら **５** しかない、4ではあんなタイムは出せない

- 項目：Speed granularity
   - 機能：アクション（速度 の粒度）を定義
      - 大きいと、速度を丁寧に調節するモデルができる可能性がある（完走しやすい）
      - 小さいと、速度を素早く調節するモデルができる可能性がある（完走しにくい）

#### Action list
ロボットが選択するActionのリスト。
Action numberが選ばれ、ロボットはその動作をします。
Action spaceの設定から、Action listは自動的に決まります。
![WS20190519230514_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/a6a8cd93-ba55-d073-9631-5ec6e07a5c1e.jpeg)

## モデルのトレーニング
### Reward function
ロボットがコースを早く走行できるAction numberを選び続けられれば、タイムが上がるはずです。
DeepRacerでモデルをトレーニングするのに使う強化学習では、与えられた「環境」における「報酬」（価値・利益）を最大化するように学習させますが、**Reward function**は**「報酬」**を定義するためのものです。
当然、**「報酬」**は目的に沿う（＝コースを少ないタイムで走る、理想的なラインを通る）よう、**強化学習**の過程において増加するように設計する必要があります。

- Reward function の機能
  - ロボットがトラック上の現在位置から新しい位置へ移動するための行動をとるときの即時の報酬（または 罰・ペナルティ）を記述

- 記述する方法
  - Code editor 領域に **Python プログラム**で記載します。  
  - 公式ドキュメントに、利用可能なパラメータの詳細や、Pythonプログラムのサンプルが多数あります。  
  - [Input Parameters of the AWS DeepRacer Reward Function](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/deepracer-reward-function-input.html)

### Hyperparameters
トレーニングのパフォーマンスを調整するための、ハイパーパラメーターを指定します。
![WS20190520000522_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/91c7f440-9cc7-e6c3-e08a-7730c496ce17.jpeg)

ハイパーパラメーターの概要については公式ドキュメントに記載があります。
[最適なトレーニングパフォーマンスのためにハイパーパラメータを体系的に調整する](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/deepracer-iteratively-adjust-hyperparameters.html)

### Stop conditions
トレーニングを中止するための条件を設定します。
設定時間が経過すると自動的に学習は停止します（STOP処理が自動的に開始され、請求も止まる）。
トレーニング中、手動で**Stop**することも可能です。
また、トレーニング後にモデルを**Clone**し、パラメータを調整してトレーニングを継続することもできます。

## 参考情報
**私の感想的なもの**ですので、正しいかはわかりません。
参考にされる方は自己責任でお願いします。

### 私の現状(2019/05/19時点)
Hyperparametersはデフォルトです（後述）
![WS20190520020538_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/731e16e2-4552-c24e-5942-3af72cc3aa1c.jpeg)

2019/05/22 少しだけ改善
![12秒台.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/b8bbe821-a911-4fcf-402a-075e2cf16bde.jpeg)

2019/05/24 少しだけ改善(ハイパーパラメータの調整)
![32F58177-7065-4243-87F0-BAC5AF55313A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/f6c9764a-8ef9-341e-f14d-ab750485cca6.jpeg)

### Action listをどう決める？(2019/05/19時点)
- 私のコースを早く走るロボットのイメージ：
   - コーナーはスピードを落とさずに、適切な舵角を維持しながら曲がる
   - ストレートは加速するために、舵角を細かく修正して真っすぐ走る

悩ましい点は、（当たり前ですが）トレーニングを開始すると変更がきかない所。
**注意:以下、項目の順番を変えてます**

- Maximum speed
   - タイムを上げたいなら　**５！！**

- Maximum steering angle
   - コーナーを全く曲がれないような設定からはじめると、学習が上手く進まないため、コースに合わせて大きめに設定  
   - 例えばre:Invent 2018のここ![説明用2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/ad63f694-237c-b607-f31e-2206397dadc0.jpeg)
とか曲がりにくい

- Steering angle granularity　／　Speed granularity
   - 細かく設定すると、向かっていって欲しい方向にトレーニングが進まないこともあり難しい。完走率100%でもタイムが遅いと困る。
   - 理論上は動作の選択肢が多ければ、効率的な動きをするモデルが**最終的には**できると思う、私の財布には厳しいかも。。。

### Reward functionをどう決める？(2019/05/19時点)
**概要**
- センターライン上をゆっくり走るようにトレーニングすれば間違いなく完走しますが、そこまでしなくても、結構、何とかなります
- どこから手を付けて良いかわからない場合は、examplesを修正するところから試しても良いかと
![WS20190520140543_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/52ed5c3c-6365-5aa2-7bda-a9579d2c3f5d.jpeg)
- 1モデル（何度かcloneした）で試しただけですが、細かく制御できればと考えたモデルは上手くできなかった
- 全体的にはRewardが増えるようにする方向（罰だけにしない）で作成、トレーニング中の傾向をグラフでも見やすいので良いかなと考えています

- all_wheels_on_track
   - 最初はこれが必須だと考え重視していましたが、タイムを縮めるトレーニングの際にはコメントアウトしています
   - 4輪が全てトラックに乗っていなくてもコースアウト判定にならないようなので、走行ラインの選択肢が増えるため。

- progress
   - まずは早く周回させたいので、最初のトレーニングでは圧倒的に高い割合になるようにしています
   - 理論上は違うアプローチや、繰り返しのトレーニングで何とかなるはずですが、私の財布（略）

- speed　／　steering_angle 
   - Action listの項目を変更することはできないので注意

### Hyperparametersをどう決める？(2019/05/19時点)
- デフォルト設定でも、London Loopで13秒台のモデルは作成できています。
- 今の用途としては「良いモデルが出来た後、モデルが壊れないようにしたいが、ここだけ改善したい」というような時に変えてみています
- **変更して失敗**が多いです、難しい
   - Gradient descent batch sizeを大きくするとclone後数分でcrash（詳細調査中、メモリ不足？）が起きたことがある、起きる
   - 予算（お小遣い）の制約もあるので、「ハイパーパラメーターを繰返し試して、最適解が見つかる確率」と「完走できれば早いモデルで何度か**submit model**に挑戦し奇跡が起きる確率」どっちが高いんだろ？と思ったりも。

### Stop conditionsをどう決める？(2019/05/19時点)
#### トレーニングを止めるタイミング
- 理想的なタイミングは一番良いモデルができた瞬間だと思います
   - 2周できたらStopしてチェックなど、やり方は色々とあるのでしょうが、常に見ているわけにもいきません
   - 何個も同じモデルで同一条件で複数作成したり、トレーニングの時間を変えて試すのは、やりたいのですが費用がかかります
- そこで。ベースのモデルを最初に作成する際は、60分学習==>Clone==>60分学習==>繰り返し　のようにして様子を見ながら試しています

#### トレーニング（中・後）の評価
- Reward graphの推移を見る
   - Reward functionの設計によります※が、増えるはずのRewardがまったく増えないのは失敗かも
   - 予算が少なければStopすべきか悩むタイミングも多いので、事前にどのようになればStopするか決めておくと良いです
   - **Reward graphはリロード時、最初の1時間分しか表示していませんので注意**
      - 駄目だと消したモデルが、CloudWatchのログ見たら後半凄く良さそうだったんですよね。その時まで、全体のグラフが出ていると思い込んでました。
   - Reward functionが繰返しするにつれ増加する設計のReward graphの例![WS20190520150553_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/361dad05-0068-b6d4-23da-df07eff5bb51.jpeg)
   - Reward functionが増減する設計のReward graphの例![WS20190520150535_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/096a51fd-3fae-4274-c163-b2d92e897f84.jpeg)

- ログ（CloudWatchのインサイト）を見る
  - Reward functionによっては、Rewardを追うだけでは判断が難しいためCloudWatchのインサイトで確認することもあります
  - 1周できているかを確認するため、ログからprogress（1周すると100）の推移を追う場合
  - **画像をクリックすると拡大します**
  - ![WS20190520160527_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/e6ff1275-e070-a621-66c6-02ac16759bbd.jpeg)
  - **少し後**
  - **画像をクリックすると拡大します**
  - ![WS20190520160545_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/a44717e6-54cc-5cda-d42e-543d2771a332.jpeg)

### トレーニングで注意していること
- 時々、Reward graphの推移を見る/ログを監視するのが良い
  - 長時間のトレーニングを行う場合は、念のため、ログ監視（Rewardの値が小さくなると検知）を行っています
     - 悲しくなるケース（トレーニング失敗）の例　・・・気が付いて手動でStopできれば***課金が止まります***
     - 開始30分後から、その場でグルグル回り続けている様子(実際は右にハンドルを切り発進=>コースアウト=>繰り返し)
     - **Reward graphの値がほぼ0(初期値の1e-3付近)のまま 5時間30分後の終了** を迎えました
     - ![M002RE6h-6h-6h-6h_ぐるぐるサイズ極小.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/429cf6dd-ff6a-7f84-9d59-e5c8881b5f1a.gif)

- Reward functionの設計によりますが、毎回完走できるモデルが速いのかはわからない
  - 「毎回安定して完走するようになる」モデルにトレーニングしようとすると、「際どい（タイムが良い）コースを攻めないようになる」モデルにトレーニングしていることもあります。

### 運の要素があるか？
「ある」かも
#### Submitで完走できてしまう（完走できない）
何度テストしても2周できないモデルをSubmitしてみたら、2周に成功したことがあります。逆の方が多いですけど。
**たとえば**逆の方で。
練習で頑張るのに、本番に弱くて何度やっても完走してくれない(London Loop)
![WS20190522220511_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/23846b5e-bcd7-41bf-9117-4fc8259739df.jpeg)

#### たまたま、凄いモデルをトレーニングできてしまう人も居るかもしれない
ハイパーパラメータをカンで当てちゃうとかは無理でも。
**たとえば**こういうモデルを作成していて、これからCloneして、**Reward functionやHyperparametersも何も触らない**方針で学習を継続するとします。
![WS20190522220530_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/1c8e6dfd-d96a-ed63-721b-27d57e90c8a5.jpeg)

**Cloneし30分学習したもの　１**（クリックで拡大します）
![WS20190522220525_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/ca08d348-3863-8d70-c7e8-d3823ee2ab2e.jpeg)

**Cloneし30分学習したもの　２**（クリックで拡大します）
![WS20190522220518_0000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/ea4a5d3d-2ad9-6165-fd9c-dcc065fdf807.jpeg)
当たり前ですが、結果は異なります。
常に**良いほう（この例だと２）**を引く運が欲しい！！

#### RoboMakerの結果に反して、実機では完走できる（できない）
**私は実機（Amazonのラジコン？ロボット）を走らせたことはないです**
コースの路面など、RoboMakerとの微妙な動作の違いがあるか気になっています。

London Loop用に作成している私のモデルは、コースの幅を大きく使って走るようにトレーニングしています。
そのためか、タイムが早いモデルほど結果的にコースアウトし易い傾向があります。
1か月間、何度も挑戦できるVirtual Circuit用の方針ですが、実機では何度も挑戦できない事を想定すると、今のやり方では難しそうです。
ただ逆に、実機のグリップが良いならコースアウトしないかも。。。
**試しに走らせてみたい。**

## 移動
**次の記事**
なし（最後の記事です）

**前の記事**
[DeepRacerのはじめかた（7）Virtual Circuit](https://qiita.com/tagucchan/items/0281d8f99b0386cbbd78)

**Top 概要と目次　に戻る**
[DeepRacerのはじめかた（1）概要と目次](https://qiita.com/tagucchan/items/06cb3c5c81de766ebe59)