ほかの学習フレームワークではあまり見られない、Unity ML-Agents特有の「決定」というプロセスについて解説する
強化学習フレームワークでは1ステップごとに「強化学習サイクル」1周分を実行することが多いですが、「Unity ML-Agents」では、エージェントから「決定」を要求されたときに実行されます。
「Unity ML-Agents」での「決定」を要求する方法には、次の2つの方法があります。
・Decision Requester:
・RequestDecision():
たとえば、2ステップごとに「決定」を要求すると、次のようになります。
「決定」を要求するステップでは、「強化学習サイクル」1周分を実行します。
①状態取得:CollectObservations()で観察取得
②行動決定:ポリシー(もしくはHeuristic())で行動決定
③行動決定 + 報酬取得:OnActionReceived()で行動実行と報酬取得
④ポリシー更新:経験に応じてポリシー更新
「決定」を要求しないステップでは、「強化学習サイクル」は実行されません。ただし、設定(Take Actions Between Decisons = True)によって、「行動実行 + 報酬取得」(OnActionReceived())のみを実行することも可能です。 これは、最後に「決定」した「行動」を繰り返し実行する処理になります
「Decision Requester」、定期的に「決定」を要求するコンポーネントです。エージェントとなるゲームオブジェクトに追加して利用します。
設定項目 | 説明 |
---|---|
Decision Period | 「決定」を何ステップごとに実行するか |
Take Actions Between Decisions | 「決定」が要求されないステップでOnActionReceived()を呼ぶかどうか |
基本的にステップは、0.02秒毎に実行されます。
「Decision Period」が「5」の場合は「50.02=0.1秒毎」、
「10」の場合は「100.02=0.2秒毎」に決定が実行されます。
AgentクラスのRequestDecision()を呼ぶことで任意のタイミングで「決定」を要求することができます。
RequestDecision()
メソッドは、Unity ML-Agentsでエージェントに任意のタイミングで決定(アクション)を要求するためのメソッドです。これにより、決定を行うタイミングを制御できます。以下に、RequestDecision()
を使用した基本的なスクリプトの例を示します。
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;
public class MyAgent : Agent
{
public float moveSpeed = 5f;
private Rigidbody agentRigidbody;
// 初期化
public override void Initialize()
{
agentRigidbody = GetComponent<Rigidbody>();
}
// エージェントのリセット処理
public override void OnEpisodeBegin()
{
// エージェントの位置と速度をリセット
agentRigidbody.velocity = Vector3.zero;
transform.localPosition = new Vector3(0, 0.5f, 0);
}
// 観測の取得
public override void CollectObservations(VectorSensor sensor)
{
// エージェントの位置を観測に追加
sensor.AddObservation(transform.localPosition);
}
// アクションの実行
public override void OnActionReceived(ActionBuffers actionBuffers)
{
// 連続アクションの場合の例
float moveX = actionBuffers.ContinuousActions[0];
float moveZ = actionBuffers.ContinuousActions[1];
// エージェントの移動
Vector3 move = new Vector3(moveX, 0, moveZ) * moveSpeed;
agentRigidbody.AddForce(move);
// 報酬の例
if (transform.localPosition.y < 0)
{
// 落ちた場合のペナルティ
SetReward(-1.0f);
EndEpisode();
}
else
{
// プラスの報酬
SetReward(0.1f);
}
}
// 決定を要求するトリガー
private void Update()
{
// 任意のタイミングで決定を要求
if (Time.frameCount % 10 == 0) // 10フレームごとに決定を要求
{
RequestDecision();
}
}
}
Update()
メソッド内で、任意のタイミングでRequestDecision()
を呼び出し、エージェントに決定を要求しています。この例では、10フレームごとに決定を要求するようになっています。このスクリプトは、エージェントが10フレームごとにアクションを実行するように設定されていますが、RequestDecision()
の呼び出しタイミングを調整することで、エージェントの動作のタイミングを制御できます。
「決定」という言葉は、Unity ML-Agentsにおいて、エージェントが次に行うべき行動(アクション)を選択するプロセスを指します。
RequestDecision()
メソッドは、エージェントに対して「次に何をするべきかを決定してください」というリクエストを送ります。これを呼び出すことで、エージェントは観測を行い、ニューラルネットワークを使って次の行動を決定し、その結果としてアクションを実行します。
たとえば、エージェントが迷路を進んでいるとします。迷路の中で「次にどちらの方向に進むか」を選ぶ際に「決定」が行われます。この「決定」が適切であれば、エージェントはゴールに向かって効率的に進むことができ、適切でなければ行き止まりに向かうかもしれません。