LearningAgentで華麗に崖を飛び越えさせてみたかった

UEアドカレ2023 21日目の記事です。

# LearningAgent爆誕

LearningAgentはUE5.3から利用可能な機械学習ってやつでAIをトレーニングする仕組みです。
C++を全く使わずにBPだけで試せるのでスーパーお気軽な環境です！ミドルウェアやライブラリなどのセットアップも不要です。

興味が沸いた方は今すぐUE5.3をダウンロードして下のリンクにあるチュートリアルをパパっとやるだけで、華麗にサーキットを自動運転する車を観察しながらティータイムを楽しむことが出来たりします。
チュートリアルは想定外のトラブルさえがなければ1時間以内で完走できます。

https://dev.epicgames.com/community/learning/tutorials/qj2O/unreal-engine-learning-to-drive

基本的にBPをコピーしていくだけなのであまりミスりようがないのですが、自分はトップビューでスプラインの調整をしていてトラックのスプラインがコースから浮いているのに気づかず無駄な時間を過ごしました。
辛かったです。(どうでもいい感想)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/bc41c721-7765-eb4a-3c6b-c75345f558c5.png)
↑ スプラインが浮いてる。。。

LearningAgentがあまりにも素敵だったのでこれをベースにしてちょっと遊んでみようというのが今回の記事の趣旨になります。

# マネキン君をLearningAgentで華麗にジャンプできるようにしたい！

事の発端はこのAdversarial Reinforcement Learning for PCG というEA様の研究をFGDCの勉強会で紹介していただいて、あっ！これLearningAgentでできそう！！と思ったことです。(あふれ出る素人感)

https://www.youtube.com/watch?v=kNj0qcc6Fpg

ということでチャレンジしてみます

# LearningAgentとか強化学習のふわっとした解説

# 強化学習
エージェント(=学習対象となるアクター)の周囲の環境やエージェント自身の状態とエージェントがとりうるアクションを定義し、初めはランダムに動いているエージェントの行動に対して評価を与えることで、知覚表現とアクションの関連性を深層学習ってやつで自動的に見つけ出して関連付ける仕組みです。
知覚表現とアクションはなんとなく関連性のある情報を与えてあげる必要があります。

# LearningAgent
LearningAgentは以下の組み合わせで実行されます
- LearningAgentIntractor
環境に対する知覚表現とエージェントがとりうるアクションを組み合わせたブループリント
- LearningAgentsTrainer
トレーニングに対する報酬と終了条件を記述するブループリント
- LearningAgentsManager
トレーニングのセットアップなどを記述するブループリント
- LearningAgentsNeuralNetwork
学習内容を保存するコンテナ。超巨大なアフィン変換マトリックスの配列(ふわっとした個人的な認識)
- そのた設定ファイル
LearningAgentsPolicyとか

# 実装の紹介 (Learning to Driveとの差分)
 ThirdPersonテンプレートをベースにしてLearning to Driveと同じような構成で実装します。
 IntratorとTrainer以外はほとんど同じで調整等はしていません。
なおこれが一般的に良い実装というわけではなくほとんど何も考えずにつくったものです。論文や資料なども追っていないので、すでに標準的な構造などがあったりするのかもしれません。そういう情報をお持ちのつよつよマンは優しく教えてくれると嬉しいです。一緒にUEDeepLearningDeepDiveをやりましょうw

## Intractor
### EventSetupObservations
観測対象をセットアップします
- 周辺のレイトレース情報
- 移動速度
- ゴール方向
を今回は選択しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/c24b22e7-9509-034d-3c55-5b6093a2c1e2.png)

### Event SetObservations

各エージェントに対して観測データを加工して渡してあげます

#### 周辺のレイトレース情報更新
コントロールローテーション相対で固定のオフセット位置を垂直にトレースしてヒット位置を渡します。
LearningAgent君が崖や飛び越えることが出来る崖の深さを学習してくれると期待
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/4926a156-134e-641d-2d4e-aab95b86ca00.png)

#### 速度と相対ゴール方向
ジャンプする時の判断材料として速度を、ゴール方向にむかってくれないと話にならないので相対ゴール方向を計算して与えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/0f1cc83b-f25f-77d1-9a0e-77ab9018715c.png)

### EventSetupActions
エージェントが行えるアクションを定義します。
-カメラの水平回転
エージェントの移動方向はカメラが決めています
-移動
前進後退だけです。横方向には移動しません
-ジャンプ
ジャンプするかどうかです value > 0 でジャンプします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/5ad9501b-96b1-ef0d-cebc-3ae7d9029128.png)

### EventGetActions
深層学習での出力となるアクションを取り出してエージェントに適用します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/b783a9e5-90ce-1790-7667-0ff70ee1c606.png)


## ※BP_ThirdPersonCharacter側の改変
移動入力処理はTick毎に入力されて消費されてしまいます。
LearningAgentはAI処理にインターバルを入れることで効率よく動作するので、アクションをPawn側のTickで適用するようにする必要があります。
こうしないとPawnがぴくぴくとしか動くなくなってしまいます。

### 外部に公開した関数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/db43ceaf-692d-5ae7-ef6d-773492bc5a2e.png)
### 毎tick適用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/cd343f11-c066-4c9c-81ca-ab7d65c3d0be.png)

## Trainer

### EventSetupReward
報酬として以下を定義しています。
-ゴールへの距離
-ゴール方向を考慮した速度

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/c36e75ad-852e-05f2-d640-955812aaed12.png)


### EventSetRewards
各エージェントの報酬を計算して与えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/162ec7cf-54d0-a774-213b-92c9b2a468be.png)

### 中断条件の定義
崖から落ちた場合に即座に終了してほしいので中断条件を定義しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/1d29fe66-4d05-33d0-655f-5eafad98e495.png)

### 中断判定
ゴール位置から3m低い位置に移動したら学習を中断します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/2eb1f388-b467-85fb-b2ee-3057cc1f26b7.png)

### 位置リセット

中断されたり位置リセットが行われた場合にエージェントの位置をリセットします
レベル中のプレイヤースタートを

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/d7ae6f6c-264b-8cbc-6f07-8322123af555.png)

# 最終結果

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">アドカレ！チュートリアルをまねてやってみればLearningAgent君が良い感じにやってくれるだろwと激甘見積もりでやってみたけど、全然簡単じゃなくて頭抱えてる。横方向の移動量が少ないノミの観察をしている気分になってる。 <a href="https://t.co/zQAkz4QXII">pic.twitter.com/zQAkz4QXII</a></p>&mdash; Takashi.Suzuki (@wankotank) <a href="https://twitter.com/wankotank/status/1737481403481137287?ref_src=twsrc%5Etfw">December 20, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">とりあえずの最終結果。改善できる点は沢山あるけど良い勢いで崖を飛び越えられるマネキン君も確認できたてきたので満足 <a href="https://t.co/kRvD7ni6ng">pic.twitter.com/kRvD7ni6ng</a></p>&mdash; Takashi.Suzuki (@wankotank) <a href="https://twitter.com/wankotank/status/1737514253547164020?ref_src=twsrc%5Etfw">December 20, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# バグ調査など

ビジュアルロガーをつかってトレースすると様々な情報のログを取って細かく確認することができます。
なんか正しく報酬が計算できてないぞ・・・？みたいな問題にそうぐうしたら一度キャプチャしてみると良いかもです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223804/ca3a29b8-3400-46a9-24e4-6e86dd307ff6.png)

# アドカレ2023
明日はキンアジ神による

【UE5】【Python】UnrealPythonがエディタと連携する上で覚えておくとよいこと【★★★】

https://qiita.com/advent-calendar/2023/ue

です！