Unity_Lesson

DiscreteBranchesを1、Branch 0 Sizeを3などにしているところを
DiscreteBranchesを3,Branch 0 Sizeを1にすることも(一応)可能です。
この設定では、エージェントは3つの異なるブランチを持ち、それぞれが1つのアクションを提供する形になります。

  1. 新しいアクションの構成:
    • DiscreteBranchesが3、Branch 0 Sizeが1の場合、各ブランチは以下のようなアクションを持つことになります。
      • ブランチ0: アクション0
      • ブランチ1: アクション1
      • ブランチ2: アクション2
    • 各ブランチからアクションを選択することができ、例えば、左に移動、右に移動、何もしない、などのアクションを分散させることができます。
  2. スクリプトの変更:

変更前例 4-5 セルフプレイから抜粋

public override void OnActionReceived(ActionBuffers actionBuffers)
    {
        // PingPongAgentの移動
        float dir = (agentId == 0) ? 1.0f : -1.0f;
        int action = actionBuffers.DiscreteActions[0];
        Vector3 pos = this.transform.localPosition;
        if (action == 1)
        {
            pos.x -= 0.2f * dir;
        }
        else if (action == 2)
        {
            pos.x += 0.2f * dir;
        }
        if (pos.x < -4.0f) pos.x = -4.0f;
        if (pos.x > 4.0f) pos.x = 4.0f;
        this.transform.localPosition = pos;
    }


具体的な変更例

以下のようにスクリプトを変更することが考えられます:

public override void OnActionReceived(ActionBuffers actionBuffers)
{
    // PingPongAgentの移動
    float dir = (agentId == 0) ? 1.0f : -1.0f;
    Vector3 pos = this.transform.localPosition;

    // 各ブランチのアクションを取得
    int actionBranch0 = actionBuffers.DiscreteActions[0]; // Branch 0
    int actionBranch1 = actionBuffers.DiscreteActions[1]; // Branch 1
    int actionBranch2 = actionBuffers.DiscreteActions[2]; // Branch 2

    // 各アクションに基づいて移動
    if (actionBranch0 == 1) // 例えば、左に移動
    {
        pos.x -= 0.2f * dir;
    }
    if (actionBranch1 == 1) // 例えば、右に移動
    {
        pos.x += 0.2f * dir;
    }
    // actionBranch2など、追加のアクションを必要に応じて処理

    // 位置制限
    if (pos.x < -4.0f) pos.x = -4.0f;
    if (pos.x > 4.0f) pos.x = 4.0f;
    this.transform.localPosition = pos;
}

「Branch」や「Buffers」の設定例

移動や力を加えるアクションを考える際に、強化学習エージェントの「Branch」と「Buffers」の具体例を以下に示します。


1. アクションの種類(Branch)

移動(Movement)

Branch 1

Buffers 3

// 例: 移動アクション
public override void OnActionReceived(ActionBuffers actionBuffers)
{
    int action = actionBuffers.DiscreteActions[0];
    Vector3 pos = transform.localPosition;

    // アクションに応じた移動
    if (action == 0) // 何もしない
    {
        // 位置は変更しない
    }
    else if (action == 1) // 左に移動
    {
        pos.x -= 0.2f;
    }
    else if (action == 2) // 右に移動
    {
        pos.x += 0.2f;
    }

    // 位置を更新
    transform.localPosition = pos;
}


力を加える(Applying Force)


// 例: 力を加えるアクション
public override void OnActionReceived(ActionBuffers actionBuffers)
{
    int action = actionBuffers.DiscreteActions[0];
    Rigidbody rb = GetComponent<Rigidbody>();

    // アクションに応じた力の加え方
    if (action == 0) // 力を加えない
    {
        // 何もしない
    }
    else if (action == 1) // 上にジャンプ
    {
        rb.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    }
    else if (action == 2) // 前に押す
    {
        rb.AddForce(Vector3.forward * 5f, ForceMode.Impulse);
    }
}

2. Buffersの役割


さらに追加で例を考えてみる

1. アクションの種類

2. 具体的な実装例

状態変更の例

public override void OnActionReceived(ActionBuffers actionBuffers)
{
    int action = actionBuffers.DiscreteActions[0];
    if (action == 0) // ドアを開ける
    {
        // ドアを開けるロジック
    }
    else if (action == 1) // アイテムを拾う
    {
        // アイテムを拾うロジック
    }
}

攻撃の例

public override void OnActionReceived(ActionBuffers actionBuffers)
{
    int action = actionBuffers.DiscreteActions[0];
    if (action == 0) // 近接攻撃
    {
        // 近接攻撃のロジック
    }
    else if (action == 1) // 遠距離攻撃
    {
        // 遠距離攻撃のロジック
    }
}

防御の例

public override void OnActionReceived(ActionBuffers actionBuffers)
{
    int action = actionBuffers.DiscreteActions[0];
    if (action == 0) // シールドを構える
    {
        // シールドのロジック
    }
    else if (action == 1) // 回避行動
    {
        // 回避のロジック
    }
}


3. Buffersの役割

それぞれの「Branch」に関連するアクションを管理するために、ActionBuffers を使用します。このバッファには、エージェントが選択したアクションが格納され、エージェントがそれに基づいて行動を決定します。例えば、DiscreteActions の配列が、どのアクションを選択したかを示す整数を含みます。


まとめ

このように、「Branch」と「Buffers」はエージェントの行動を整理し、学習を促進するための重要な構造です。様々な行動に対応するために、ブランチの設計とバッファの使い方を工夫することで、より複雑でインタラクティブなエージェントを作成することができます。