就活生のブログ

就活中の理系大学生のブログです

強化学習の環境作成

【目次】

【概要】

 物理法則(重力・慣性力など)を取り入れた環境下で、球(以下、Roller Agent)にどのタイミングでどの方向に力を加えたら目標地点(Target)に到着するか学習させました。

(※)Targetに到着したらランダムな地点に移動します。

f:id:taka_hatene:20210223145941p:plain


【学習環境の作成】

Roller Agent:「Create→3D Object→Sphere」から作成。

「Rigidbody」を追加(重力や慣性力などの物理法則を適用)

「Behavior Parameters」を追加(観察と行動の設定)

「Decision Requester」を追加(10ステップごとに行動を決定するよう設定)

「RollerAgent.cs(新規スクリプト)」を追加(詳細は後述)

Target:「Create→3D Object→Cube」から 作成。

Floor:「Create→3D Object→Plane」から作成。


項目 説明
観察 ・TargetのXYZ座標
・RollerAgentのXYZ座標
・RollerAgentのXZ速度
行動 ・RollerAgentにX方向に力を加える
・RollerAgentにZ方向に力を加える
報酬 ・RollerAgentがTargetに到着した報酬
・RollerAgentが落下した罰
・迷った(時間経過)罰


【RollerAgent.cs(新規スクリプト)】

観察・行動・学習するため、Roller Agentに追加するスクリプト(RollerAgent.cs)を作成する必要があります。

(※) 著作権の関係からコードを一部省略しています(1)。
RollerAgent.cs

using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;

// RollerAgent
public class RollerAgent : Agent
{
    // ~~~中略~~~ //

    // 行動実行時に呼ばれる
    public override void OnActionReceived(float[] vectorAction)
    {
        // RollerAgentに力を加える
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = vectorAction[0];
        controlSignal.z = vectorAction[1];
        rBody.AddForce(controlSignal * 10);

        // RollerAgentとTargetの距離
        float distanceToTarget = Vector3.Distance(
                                 this.transform.localPosition,
                                 target.localPosition);

        // RollerAgentがTargetの位置に到着した時
        if (distanceToTarget < 1.42f)
        {
            // ① 到着した時、正の報酬を与える
            AddReward(1.0f);
            rate.successCount();
            EndEpisode();
        }

        // RollerAgentが床から落下した時
        if (this.transform.localPosition.y < 0)
        {
            // ② 落下防止のため、落下した時に罰を与える
            AddReward(-0.1f);
            rate.failureCount();
            EndEpisode();
        }

        // RollerAgentが探索してる時
        // ③ 探索を急かすため、時間経過で罰を与える
        AddReward(-0.001f);
    }
}


【学習結果】

3パターンの報酬と罰を設定し、それぞれ500000ステップの学習を行い、エピソード毎の報酬とステップ(1ステップ=0.02秒)の関係を図1にまとめました。エピソードはエージェントがターゲットに到着(報酬)またはフロアから落下(罰)、落下も到着もせずに40秒経過(報酬なし)でエピソードは終了します。


f:id:taka_hatene:20210302183241p:plain

図1 学習中の報酬:横軸がステップ数、縦軸が報酬
橙色:パターン1水色:パターン2赤色:パターン3


学習から得られた最終的なポリシーをエージェントに与えて、エージェント9つの600秒間の到着回数と落下回数の合計を測定したところ、表1のようになりました。

(※) 慣性が働くために単純にTargetの方向に力を加えるだけではTargetに到着せず、落下する可能性があります。

表1 パターンごとの到着回数と落下回数

パターン 到着報酬 落下罰 時間経過罰 到着回数 落下回数 到着率(%)
パターン1 1.0 0 0 1177 601 66.1
パターン2 1.0 -0.5 0 1961 1161 62.8
パターン3 1.0 -0.5 -0.005 2049 1083 65.4

約5万ステップ(1000秒)学習した時点で報酬の期待値はほぼ収束していることが分かった。

また、個々のパターンより以下のことが読み取れる。

パターン1は表1の「到着の報酬(1.0)と到着率(66.1%)から与えれる報酬(0.661)」と図1の「報酬値(0.60~0.70)」が近い値である

パターン2は表1の「到着の報酬(1.0)と到着率(62.8%)から与えれる報酬(0.628)」と「落下の罰(-0.5)と落下率(37.2%)から与えられる罰(-0.186)」を合わせた「報酬値(0.442)」と図1の「報酬値(0.35~0.45)」が近い値である

パターン3は時間経過罰により、報酬値が大きく低下しており、0付近に収束している。到着の報酬(0.654)と落下の罰(-0.173)から得られる報酬値(0.481)が時間経過罰(-0.005/ステップ)によって0.0付近に収束していることから、平均して約100ステップに1回、つまり【2.0秒に1回】の頻度で1つのエージェントは到着または落下している。これは表1より計算される頻度【1.7秒に1回】と概ね一致する(600秒間に9つのエージェントが3132回(2049+1083)到着または落下:600×9/3132=1.72)。


パターン1:到着時に報酬を与え、罰を与えずに学習したモデル

youtu.be


パターン2:到着時に報酬を与え、落下時に罰を与えて学習したモデル

youtu.be


パターン3:到着時に報酬を与え、落下時の罰と時間経過(-0.005/ステップ)の罰を与えて学習したモデル

youtu.be


【まとめ】

 落下罰を与えた場合、時間あたりの到着回数が上昇すること、到着報酬と落下罰、時間経過罰を与えた場合、学習中のデータ(図1)から時間あたりの到着回数および落下回数(表1)を予測可能であることが分かった。

【参考文献】

(1)布留川 英一・佐藤 英一(2018)『Unityではじめる機械学習強化学習 Unity ML-Agents実践ゲームプログラミング』ボーンデジタル