ML-Agents Release 22 の新規プロジェクト作成
基本はこの公式ドキュメント[1]の通りなのですがそのままコピペで実行できるって感じではなかったので訳してまとめておきました。プログラムの詳細は説明していないですが詳しくコメントを書いておいたので分かると思います。
前提となる過去の記事
- ML-Agents Release 22 の導入に関する記事です。ここで作った環境で確認しました。
- エージェントを訓練し、訓練済みのモデルを Unity 環境に組み込むまでの一連のプロセスを追っています。ML-Agents で使われる基本的な概念が分からない場合はこれを確認してみてください。。
Unity プロジェクトの作成
- Unity Hubを起動し、"RollerBall"という名前で新しい3Dプロジェクトを作成
- ML-Agents パッケージをプロジェクトに追加
- Window > Package Manager > + > Select package on disk
-
ml-agents\com.unity.ml-agents\package.json
を選択。
環境の作成
- 床となる平面を作成する
- Hierarchyウィンドウ内で右クリックし、3D Object > Planeを選択します。
- GameObjectの名前を「Floor」にします。
- Floor Planeを選択し、Inspectorウィンドウでそのプロパティを表示します。
- TransformをPosition = (0, 0, 0)、Rotation = (0, 0, 0)、Scale = (1, 1, 1)に設定します。
- Target となるキューブを追加する
- Hierarchyウィンドウ内で右クリックし、3D Object > Cube を選択します。
- GameObjectの名前を "Target" にします。
- Target Cubeを選択し、Inspectorウィンドウでそのプロパティを表示します。
- Transformを Position = (3, 0.5, 3), Rotation = (0, 0, 0), Scale = (1, 1, 1) に設定します。
- Agent となる球体を追加する
- Hierarchy ウィンドウ内で右クリックし、3D Object > Sphere を選択します。
- GameObject の名前を "RollerAgent" にします。
- RollerAgent Sphere を選択し、Inspector ウィンドウでそのプロパティを表示します。
- Transform を Position = (0, 0.5, 0), Rotation = (0, 0, 0), Scale = (1, 1, 1) に設定します。
- Add Component をクリックします。
- Sphere に Rigidbody コンポーネントを追加します。
- Training Area へのグループ化
- プロジェクトのHierarchyを右クリックし、新しい空のGameObjectを作成します。名前をTrainingAreaにします。
- TrainingAreaのTransformをPosition (0,0,0)、Rotation (0,0,0)、Scale (1,1,1)に設定します。
- Hierarchy内のFloor、Target、およびRollerAgent GameObjectをTrainingArea GameObjectにドラッグアンドドロップします。
Agent の実装
- Agent Script を作成
- RollerAgent GameObjectを選択し、Inspectorウィンドウに表示します。
- Add Componentをクリックします。
- コンポーネントのリストにあるNew Scriptをクリックします (一番下にあります)。
- スクリプトに"RollerAgent"と名前を付けます。
- Create and Addをクリックします。
- RollerAgent.cs に以下のコードを貼り付ける
using System.Collections.Generic;
using UnityEngine;
// ML-Agent パッケージを追加
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;
public class RollerAgent : Agent
{
Rigidbody rBody;
void Start () {
rBody = GetComponent<Rigidbody>();
}
public Transform Target;
// 各 Episode の開始時に呼び出される
public override void OnEpisodeBegin()
{
// Agent が落下した場合、運動量をゼロにする
if (this.transform.localPosition.y < 0)
{
this.rBody.angularVelocity = Vector3.zero;
this.rBody.linearVelocity = Vector3.zero;
this.transform.localPosition = new Vector3( 0, 0.5f, 0);
}
// Target を新しい場所に移動する
Target.localPosition = new Vector3(Random.value * 8 - 4,
0.5f,
Random.value * 8 - 4);
}
// 観測する
public override void CollectObservations(VectorSensor sensor)
{
// Target と Agent の位置
sensor.AddObservation(Target.localPosition);
sensor.AddObservation(this.transform.localPosition);
// Agent の速度
sensor.AddObservation(rBody.linearVelocity.x);
sensor.AddObservation(rBody.linearVelocity.z);
}
public float forceMultiplier = 10;
// Step ごとの Agent の行動を定める
// actionBuffers には次のステップの行動で使う値が入っている
public override void OnActionReceived(ActionBuffers actionBuffers)
{
// Agent を actionBuffers の値に基づいて動かす
Vector3 controlSignal = Vector3.zero;
controlSignal.x = actionBuffers.ContinuousActions[0];
controlSignal.z = actionBuffers.ContinuousActions[1];
rBody.AddForce(controlSignal * forceMultiplier);
float distanceToTarget = Vector3.Distance(this.transform.localPosition, Target.localPosition);
// Agent が Target に到達した時
if (distanceToTarget < 1.42f)
{
// 報酬を与えてEpisode を終了
SetReward(1.0f);
EndEpisode();
}
// プラットフォームから落下した時
else if (this.transform.localPosition.y < 0)
{
// Episode を終了
EndEpisode();
}
}
// Heuristic モード(手動操作)
// 次のステップの Agent の行動で使う値を配列 actionsOut に代入する
public override void Heuristic(in ActionBuffers actionsOut)
{
var continuousActionsOut = actionsOut.ContinuousActions;
continuousActionsOut[0] = Input.GetAxis("Horizontal");
continuousActionsOut[1] = Input.GetAxis("Vertical");
}
}
エディターでの Agent の設定
- RollerAgent GameObjectを選択して、Inspectorウィンドウにそのプロパティを表示します。
- そのプロパティの RollerAgent (Script) のTargetフィールドにHierarchy内のTarget GameObjectを、ドラッグアンドドロップします。
- Add ComponentボタンでDecision Requesterスクリプトを追加します。Decision Periodを10に設定します。
- Add ComponentボタンでBehavior Parametersスクリプトを追加します。
- AgentのBehavior Parametersを次のように設定します。
- Behavior Name: RollerBall
- Vector Observation > Space Size = 8
- Actions > Continuous Actions = 2
環境のトレーニング
-
ml-agents-main/config/
の下に新しいrollerball_config.yaml
ファイルを作成し、以下をコピペ。configファイルのパラメータについては公式ドキュメント[3]で説明されています。
behaviors:
RollerBall:
trainer_type: ppo
hyperparameters:
batch_size: 10
buffer_size: 100
learning_rate: 3.0e-4
beta: 5.0e-4
epsilon: 0.2
lambd: 0.99
num_epoch: 3
learning_rate_schedule: linear
beta_schedule: constant
epsilon_schedule: linear
network_settings:
normalize: false
hidden_units: 128
num_layers: 2
reward_signals:
extrinsic:
gamma: 0.99
strength: 1.0
max_steps: 500000
time_horizon: 64
summary_freq: 10000
- 次のコマンドを実行してエディターでPlayを押すとエージェントをトレーニングできる。
mlagents-learn config/rollerball_config.yaml --run-id=RollerBall
Behavior Type
上で紹介した方法では Behavior Type は Default になっている。推論だけしたい場合や、 Agent をマニュアルで操作して環境のテストを行いたい場合は適宜変更して実行する。学習済みモデルの埋め込みに関しては前の記事「ML-Agents Release 22 の公式ドキュメントを読む」を参照してください。Behavior Type について[2]に書いてありましたので訳しておきました。
Behavior Type | 実行内容 |
---|---|
Default | Agent は、リモートプロセスを意思決定に使用する。リモートプロセスが利用できない場合は推論を使用し、モデルが提供されていない場合は Heuristic を使用する。 |
Heuristic Only | Agent は常に Heuristic を使用する。 |
Inference Only | Agent は、Model フィールドで与えられた Model Asset を用いて、常に推論を行います。 |
参考文献
[1] Making a New Learning Environment - Unity ML-Agents Toolkit, https://unity-technologies.github.io/ml-agents/Learning-Environment-Create-New/
[2] Enum BehaviorType
| ML Agents | 3.0.0 , https://docs.unity3d.com/Packages/com.unity.ml-agents@3.0/api/Unity.MLAgents.Policies.BehaviorType.html
[3] ml-agents/docs/Training-Configuration-File.md at main · Unity-Technologies/ml-agents · GitHub, https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Training-Configuration-File.md
Discussion