Aimbot-ParallelEnv/README-JP.md
2024-01-24 17:02:48 +09:00

27 KiB
Raw Permalink Blame History

Aimbot-ParallelEnv

これはUnity ML-Agentsに基づいたFPSゲームのマルチエージェントトレーニング環境で、特定の目標と対応する難易度を生成し、エージェントのアクションに基づいて報酬をフィードバックして強化学習エージェントをトレーニングするための環境です。

Chinese badge Japanese badge

Description

プロジェクトはML-Agents 2.0.1を基にして、Unity 2021.3.14f1を使用して開発されています。 Python側では、mlagents-envs 0.30.0を使用してゲーム環境と通信を行います。

Quick start

プロジェクトAimbot-PPOでは、この環境を使用してPPOアルゴリズムのトレーニングが行われています。具体的な使用例はAimbotEnv.pyで記載されています。

ゲーム環境の概要

本環境は初代Doomの基本モードを模したFPSゲームで、エージェントには異なる目標が与えられます。エージェントは目標の種類と位置、自身の状態に基づいて、撃つかどうか、撃つ方向、移動方向を決定します。この環境には2つのモードと3種類の目標があります訓練モードとテストモード、そしてFreeTargetGotoTargetAttackTargetです。FreeTargetでは、エージェントは武器を使ってエリア内のすべての敵を倒す必要があります。GotoTargetAttackTargetでは、エリア内に目標ブロックが生成され、エージェントはそれに応じた異なる行動を取る必要があります。さらに、GotoTargetAttackTargetでは、生成される目標ブロックの構造に応じて5つの異なる難易度に分けられています。

ゲームの概要

この環境は初代Doomの基本モードを模したFPSゲームで、エージェントには異なる目標が与えられます。エージェントは目標の種類と位置、自身の状態に基づいて、撃つかどうか、撃つ方向、移動方向を決定します。この環境には2つのモードと3種類の目標があります訓練モードとテストモード、そしてFreeTargetGotoTargetAttackTargetです。FreeTargetでは、エージェントは武器を使ってエリア内のすべての敵を倒す必要があります。GotoTargetAttackTargetでは、エリア内に目標ブロックが生成され、エージェントはそれに応じた異なる行動を取る必要があります。さらに、GotoTargetAttackTargetでは、生成される目標ブロックの構造によって、5つの異なる難易度に分けられています。

モード

訓練モードとテストモードは、Python側と通信が必要で、この環境から観測されたObservationに基づいてActionを生成し、環境にフィードバックします。環境を起動する際、ゲーム内でユーザーが操作してモードを選択する必要があります。ML-Agentsにはタイムリミットが存在するため、45秒以内にモードを選択する必要があります。45秒を超えると、自動的にゲーム環境から退出します。

訓練モード

訓練モードに入る前に、手動でスタート画面からTrain-FreeTrain-GotoTrain-Attack(単一モードの訓練)またはTrain-Mix(全モードの訓練)の中から選択する必要があります。選択後、訓練モードに入りますが、この選択は後で変更できません。複数の難易度がある目標ブロックTrain-GotoTrain-Attackのモードでは、スタート画面に異なる難易度の目標ブロックを生成する確率を調整するパネルが画面の左上にあります。デフォルトでは、各難易度の生成確率は均等となっています。このパネルでは、各モードの難易度の合計確率が1になるように、一つの難易度の確率を調整すると他の難易度の確率が自動的に調整されます。ユーザーは右側のロックボタンをクリックして、特定の難易度の確率をロックまたは解除することができます。このパネルは訓練モードの実行中にも表示され、ユーザーが訓練中に確率パネルを調整すると、次の目標ブロックの生成時に適用されます。
TargetLevelProbabilityPanel

テストモード

テストモードでは、ユーザーが手動でエージェントに命令を指定する必要があります。画面右上のメニューをクリックすることで、目標ブロックや敵を生成したり、目標モードを切り替えたりすることができます。このモードでは、訓練モードにはない新しいターゲットStayTargetが追加されています。ユーザーが特定の目標を指定しない場合やゲームをクリアした場合、StayTargetがエージェントに割り当てられます。右上隅のメニューをクリックすると、マウスモードを切り替えて敵Enemyを生成するモードや、特定の難易度のターゲットブロックを生成するモードに変更できます。マウスがブロック生成モードで、マウスをゲームエリアに移動すると、生成するオブジェクトのプレビューが表示され、マウスの右クリックで指定した位置に対応する敵やブロックを生成できます。ターゲットブロックを生成すると、対応するターゲットが自動的にエージェントに割り当てられます。FreeTargetを割り当てる必要がある場合は、FreeModeボタンをクリックします。ClearGameをクリックすると、すべての敵とブロックがクリアされ、エージェントのターゲットがStayTargetに設定されます。StayModeをクリックすると、エージェントのターゲットを強制的にStayTargetに設定できます。

Target

FreeTarget

エージェントがFreeTargetに割り当てられた場合、エージェントはエリア内のすべての敵を武器で倒す必要があります。このモードでは、ラウンド開始時にエリア内にランダムな数の敵が生成されますデフォルトは6体。エージェントはエリアのランダムな位置に生成され、向きは前回のラウンドを引き継ぎます最初のラウンドの場合はデフォルトで角度0。エージェントがすべての敵を倒せば勝利と判断され、30秒以内にすべての敵を倒せない場合は失敗と判断されます。

GotoTarget

エージェントがGotoTargetに割り当てられた場合、指定された目標エリアの特定の位置に移動することが目標です。このモードでは、ラウンドが始まるとエージェントの位置は前のラウンドを引き継ぎます最初のラウンドではマップの左下隅にデフォルトで生成されます。Gotoの目標ブロックは、難易度の確率に応じてエリア内にランダムに生成され、異なる難易度には複数のプリセットブロックが用意されています。これらのプリセットブロックはSceneBlocksSetによってPrefabフォルダに保存されています。すべての目標ブロックの合計サイズは10x10で、ブロックが生成される際にはエージェントの位置を避けます。指定された目標エリアはFireBaseと呼ばれる円形のエリアで、その範囲は目標ブロックを超えることはありませんが、位置とサイズはプリセットブロックによって異なります。エージェントが目標ブロックの中心位置に正常に移動すると勝利と判断され、30秒以内に中心位置に移動できない場合は失敗と判断されます。

AttackTarget

エージェントがAttackTargetに割り当てられた場合、目標エリアに火力を集中し、主な目標はブロック内のすべての敵を倒すことです。このモードでのエージェントと目標ブロックの生成戦略、およびFireBaseの構成はGotoTargetと同様です。しかし、AttackTargetFireBaseエリア内には必ず敵が生成されます。エージェントがブロック内のすべての敵を倒せば勝利と判断され、30秒以内にすべての敵を倒せない場合は失敗と判断されます。


Environment

Observation Space

本強化学習訓練設定では、状態(State)は環境を理解し、分析する上での鍵となります。観測環境は3つの主要な部分で構成されていますTargetState(ターゲット状態)、AgentState(自機状態)、そしてRaycastStateレイキャスト状態。これらの観測データはML-AgentsのVectorSensorクラスを通じて収集され、Python側に送信され、意思決定に必要な情報を提供します。ObservationのソースコードはMLAgentsCustomController.csにあるoverrideされたCollectObservations関数内に格納されています。

TargetStateターゲット状態

TargetStateは、エージェントが受け取ったTargetとその関連情報を含んで、合計六つあります。ターゲットの種類、x,y,z座標、TargetAreaの直径、そしてエージェントがTargetArea内にいるか、およびそのラウンドの残り時間などの情報を含みます。

番号 観測項目 サイズ 状態空間 説明
0 Targetの種類 1 0,1,2,3,4 割り当てられたTargetの種類を記述0=FreeTarget、1=GotoTarget、2=AttackTarget、3=DefenceTarget未使用、4=StayTarget
1~3 Targetの座標 3 0~47 Target中のFirebaseの連続空間座標を記述、範囲は0から47の連続値
4 FireBaseの直径 1 1~10 FireBaseの直径を記述、範囲は1から10の連続値
5 InFireBase状態 1 0,1 エージェントがFireBase内にいるかどうかを記述、0=False、1=True
6 残り時間 1 0~30 ラウンドの残り時間を記述、範囲は0から30の連続値

AgentState自機の状態

AgentStateは、エージェントの武器が攻撃可能な状態かどうか、エージェントのx, y, z座標、およびエージェントの向きの角度を含んでいます。エージェントのGameObjectの向きの角度を直接使用すると、0から360度の変化時に値が大幅に変化してしまいます。より良い周期的な表現を実現するために、エージェントのGameObjectの回転角度のコサインとサインの値を使用してエージェントの向きを表しています。

番号 観測項目 サイズ 状態空間 説明
7 GunState 1 0,1 エージェントの武器が使用可能な状態かどうかを記述。0=False、1=True
8~10 エージェントの座標 3 0~47 エージェントの連続空間座標を記述、範囲は0から47の連続値
11~12 エージェントの向き 2 -1~1 エージェントのGameObjectの回転角度のcosとsin値を計算してエージェントの正面の向きを記述。

RaycastState視野状態

RaycastStateはエージェント視界内で発射されたレイキャストが検出したオブジェクトのタグとその距離を記録します。タグはラベルエンコーディングとワンホットエンコーディングの2つの方法で記録することができ、デフォルトではラベルエンコーディングが使用されます。これはCommonParameterContainerオブジェクトで調整することが可能です。RaycastStateRaySensorsクラスによって管理されており、非均一なレイキャストの分布が実装されています。デフォルトでは、視界の中央15のエリアに射線がより密集して分布し、両側はより希薄です。中央の密集エリアからは5本の射線が、両側の希薄エリアからはそれぞれ7本の射線が発射されます。各レイキャストが検出可能な最大距離は100ユニットで、その距離を超えると0が返されます。視界の中央エリアのカバー範囲、エリア内のレイキャスト数、検出可能な距離は、各AgentのGameObjectのInspectorで調整できます。
射線の分布方式

番号 観測項目 サイズ 状態空間 説明
11~Raynum+11 TagType(Label) Raycast数 0, 1, 2 レイキャストが検出した物体のタグ。0=Wall, 1=Enemy, 2=Player, -1=Nothing
11~Raynum * 3+11 TagType(Onehot) Raycast数 * 3 0, 1 レイキャストが検出した物体のタグ。ワンホットエンコーディングで記録
Raynum+12~2* Raynum+12ラベル,
3* Raynum+12~4* Raynum+12ワンホット
距離 Raycast数 0~MaxDistance レイキャストが検出した物体までの距離。範囲は0〜MaxDistance。MaxDistanceのデフォルトは100

nは各エージェントのRaycast数、MaxDistanceは各エージェントのレイキャストの最大探知距離を指します。

Action Space

FPSゲームにおけるプレイヤーのキーボードとマウスの同時操作をシミュレートするため、本環境のActionSpaceはDiscrete Action(離散動作)とContinuous Action連続動作の2つの部分に分かれています。Discrete Actionはプレイヤーのキーボードによる離散的な操作を模擬し、Continuous Actionはマウスによる連続的な操作を模擬します。両方のActionSpaceに対応する操作はMLAgentsCustomController.cs内のoverrideされたHeuristic関数で参照できます。具体的な実装はAgentController.cs内のMoveAgent関数とCameraControl関数にあります。

Discrete Action離散動作

Discrete Actionでは、エージェントは各方向の移動と攻撃を離散的に操作できます。移動操作には垂直移動と水平移動が含まれ、攻撃操作では武器の操作が可能です。

番号 動作 ActionSpace 説明
0 垂直移動 0, 1, -1 エージェントをその正面方向の垂直軸で制御。0=停止、1=前進、-1=後退
1 水平移動 0, 1, -1 エージェントをその正面方向の水平軸で制御。0=停止、1=右移動、-1=左移動
2 攻撃 0, 1 エージェントの攻撃操作を制御。0=攻撃しない、1=攻撃する

Continuous Action連続動作

Continuous Actionでは、エージェントの視点を制御できます。本環境は初期のDoomのFPS環境を模擬しているため、エージェントの視点は水平方向のみで回転可能と設定されています。

番号 動作 ActionSpace 説明
0 水平回転 -Inf ~ Inf エージェントの水平方向(左右)の視角回転を制御。正の値で右に、負の値で左に回転する。

Reward

与えられた各ターゲットにおいて、エージェントが異なるタスクを達成することに注力するため、リワードの設計もそれぞれ異なります。訓練モードでは、リワードは共通リワード「Common Reward」と各ターゲット専用のリワードで構成されています。

Common Reward共通リワード

エージェントが訓練中に目標達成に役立つ行動を取るように導き、無意味な動作を避けるために、Common Rewardでは以下のリワードとペナルティが設計されています。ML-AgentsはPythonに直接ラウンド終了の結果を伝えることができないため、他のリワードの値が小さすぎたり大きすぎたりして勝利または失敗を判断できない場合に備えて、ラウンド終了時のリワードには極大値と極小値が追加されています。

リワード/ペナルティ 値/シンボル 説明
非ターゲット命中 3 エージェントがターゲットではない敵を撃つか倒すと得られるリワード
ターゲット命中 25 エージェントがターゲットとなる敵を撃つか倒すと得られるリワード
移動ペナルティ -0.5 エージェントがフィールド上を移動するときに与えられるペナルティ
回転ペナルティ P_s エージェントが視点を回転するときに与えられるペナルティ
勝利リワード 999 ラウンドが終了し、そのラウンドでエージェントが目標を達成したときに与えられるリワード
失敗リワード 999 ラウンドが終了し、そのラウンドでエージェントが失敗したときに与えられるリワード

エージェントが訓練中に無意味な回転を行わないように、また回転速度が速すぎないように、以下の関数を使用してSpinPenaltyを与えます。40個のマウス操作の回転記録が閾値に達していない場合、小さなペナルティが与えられます。閾値を超えると、エージェントが同じ方向に持続的に回転していることがわかるので、大きなペナルティが与えられます。ここでのPstは時刻tの回転ペナルティ、mouseXtは時刻tのエージェントのContunuouse Action内の回転アクションの値を指します。


P_{st} = 
\begin{cases} 
  -|mouseX_t| \cdot 0.06 &, & \left| \sum_{t=0}^{-40} mouseX_t \cdot 0.08 \right| < 10 \\
  -\left| \sum_{t=0}^{-40} mouseX_t \cdot 0.08 \right| & , & \left| \sum_{t=0}^{-40} mouseX_t \cdot 0.08 \right| \geq 10 
\end{cases}

FreeTarget

FreeTargetでは、主な目標は全ての敵を消滅させることです。そのため、敵を追跡する能力が非常に重要です。このモードでは、2種類の報酬メカニズムが設定されています視界の中心で敵を検出した場合、エージェントには2の報酬が与えられます。敵を検出しなかった場合、視界の中心から検出された敵までの距離 D に基づいて2未満の報酬が与えられます。距離の計算は、Raycastで検出された敵にのみ考慮され、距離が0.5に近づくほど、つまり敵の半径がRewardに近づくほど、報酬は2に近づきます。たとえば、下図ではEnemy1Enemy3との距離のみが計算され、最短距離 D_1 が報酬の計算に使用されます。検出されなかったEnemy2Enemy4は除外されます。このモードでは、すべての敵がターゲットと見なされ、敵が倒されたり、ヒットした場合、エージェントはCommon RewardTargetHit Rewardを獲得します。


FacingReward

報酬/ペナルティ 値/記号 説明
FacingReward R_f 視界の中心と検出された最も近い敵との距離に基づく報酬

R_{f} =
\begin{cases} 
  2 &, &min(D) \leq 0.5 \\
  \frac{1}{\sqrt{\frac{min(D)}{2}}} &,& min(D) \gt 0.5
\end{cases}

GotoTarget

GotoTargetでは、主な目標は指定されたFireBaseへの移動です。時刻 tt-1 でのプレイヤーとターゲット間の距離 D_tD_{t-1} の差に基づいて、各ステップで獲得できる距離報酬 R_d が設定されています。エージェントが目標に近づくと正の報酬が与えられ、目標から離れると0未満のペナルティが与えられます。プレイヤーがFireBase内にいる場合、より高い固定報酬を得ることができますが、この場合DistanceRewardは効果を発揮しません。このモードでは、すべての敵は攻撃対象とは見なされませんが、敵をヒットまたは倒した場合、Common RewardNonTargetHitを獲得できます。

報酬/ペナルティ 値/記号 説明
DistanceReward R_d エージェントが目標外にいる際の目標との距離差に基づく報酬
InAreaReward 5 エージェントが目標内にいる際の持続報酬

R_{d} = (D_{t-1} - D_{t}) \cdot 20

AttackTarget

Attack Modeでは、主な目的は目標地点の敵を排除し、エージェントが目標地点に対して行動をとることを奨励することです。したがって、FreeTargetと同様に、目標地点への視線の移動も重要です。エージェントが目標地点に面して攻撃する場合、それは抑圧行動と見なされ、より低いSuppressiveRewardが与えられます。目標地点に面しているが攻撃していない場合、さらに低いFacingAreaRewardが継続して与えられます。FireBase内の敵は目標と見なされ、敵が倒されたりヒットした場合、エージェントはCommon RewardTargetHit Rewardを獲得します。一方、FireBase外の敵は目標とは見なされず、敵が倒されたりヒットした場合、エージェントはCommon RewardNonTargetHit Rewardのみを獲得します。

報酬/ペナルティ 値/記号 説明
SuppressiveReward 5 エージェントがFireBaseに対して抑圧攻撃を行った際の報酬
FacingAreaReward 2 エージェントが目標に向かっている間の継続報酬

Side Channel

環境のデバッグやUnityとPython間の非リアルタイム通信を実現するため、この環境ではML-Agentsが提供するSide Channelを使用しています。ここではhuggingfaceのCustom Side Channelsをベースで開発を進みました。Unity側では、Side Channelの実装はAimbotSideChannel.csAimBotSideChannelController.csに位置しています。各ログ情報は|でフィールドを区切り、最初のフィールドはログのタイプで、次のフィールドはカスタムログ情報です。この環境では、UnityのSide ChannelはすべてのLogType.WarningLogType.ErrorタイプのログをPython側に送信します。LogType.Warningはラウンド終了後の勝敗情報やUnityからPythonへの指示を伝えます。勝敗情報はWarning|Result|WinWarning|Result|Loseのようになります。一方、指令は次のトレーニング終了後にモデルを保存するコマンドで、その内容はWarning|Commandとなります。