AWS DeepRacerの報酬関数トレースログをCloudWatchLogs Insightsでパースして分析

DeepRacerのSageMakerサンプルノートブックを動かすと、CWLogsに報酬関数のトレースログが吐かれます。これをLogsInsightsでパースしてみました。


[サンプルノートブック](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/reinforcement_learning/rl_deepracer_robomaker_coach_gazebo/rl_deepracer_coach_robomaker.ipynb) 自体は下記の記事を参考に動かしています。

 - [Amazon SageMaker ノートブックを使用して AWS DeepRacer モデルをトレーニングし評価する](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/train-evaluate-models-using-sagemaker-notebook.html)
 - [Amazon SageMakerとAWS RoboMakerでAWS DeepRacerを走らせて学習させるノートブックを試してみた](https://dev.classmethod.jp/machine-learning/sagemaker-robomaker-deepracer-sample/)




# 吐かれるログ

ログはデフォルトで以下のCloudWatchlogsに吐かれる。

### ロググループ名
/aws/robomaker/SimulationJobs

### 対象ログイベント
 - SIM_TRACE_LOGで始まるログ 
 - [deepracer_env.py](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/reinforcement_learning/rl_deepracer_robomaker_coach_gazebo/src/robomaker/environments/deepracer_env.py) の def infer_reward_state の中で「入力パラメータ」と「結果の報酬」を出力している

ソースコードを見ると[報酬関数](https://docs.aws.amazon.com/ja_jp/deepracer/latest/developerguide/deepracer-train-models-define-reward-function.html)に渡しているものとは若干違うパラメータもログ出力していますが、今回はそのままパースしてみます。

### デフォルトの出力

どれがどのパラメータかパッと見ではわからない...

<img width="1210" alt="logs.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43631/747a1709-54b2-42af-a7fe-d8217af6db4a.png">



# Logs Insights でパース

実装コードから、どの出力がどのパラメータなのか確認し、insightsのparseコマンドに反映。

## トレースログをパースして100行表示

### クエリ
```
fields @message
| filter @message like /^SIM_TRACE_LOG/
| parse @message "SIM_TRACE_LOG:*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*" as episodes,steps,x,y,car_orientation,steering,throttle,action_taken,reward,progress,waypoint_action,done,on_track,current_progress,initidxWayPoint,closest_waypoint_index,track_length,time
| sort by time
| limit 100
```

### 出力結果

これでまともに見れそうな気がしてきました。

<img width="1635" alt="query1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43631/69dd8b3b-bf45-b767-8d56-11dcba7881cb.png">


## 条件に合うログのみ表示してみる

50steps以降で、スロットル0.5未満で1以上の報酬を与えたログを100行表示してみます。

### クエリ

```
fields @message
| filter @message like /^SIM_TRACE_LOG/
| parse @message "SIM_TRACE_LOG:*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*" as episodes,steps,x,y,car_orientation,steering,throttle,action_taken,reward,progress,waypoint_action,done,on_track,current_progress,initidxWayPoint,closest_waypoint_index,track_length,time
| filter (steps>50 and throttle<0.5 and reward>=1)
| sort by time
| limit 100
```

### 出力結果

<img width="1632" alt="query2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43631/ae0f439f-c13f-b44c-ca8a-095ec47c4cb0.png">

Insightsでは他にもstatsなどの集計コマンドが使えるので、いろいろできそうです。

# 補足
progress(コード上はtotal_progressという変数)はドキュメント上、0.0〜1.0が入るように読めたが
> | progress | float | [0,1] | Percentage of track completed. |
|:--|:--|:--|:--|

実際は0〜100のレンジっぽい値が出力された。コードを確認すると積算用の進捗をcurrent_progress *= 100.0 していたり気になりましたがパラメータの詳細についてはこの記事で触れません。

# 参考
 - [CloudWatch Logs Insights クエリ構文](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html)

 - [CloudWatch の料金](https://aws.amazon.com/jp/cloudwatch/pricing/)
   - 分析(Logs Insightsのクエリ)スキャンされたデータ 1GBあたり0.005USD@バージニア(2019/04/16)