見出し画像

Unity ML-Agents 0.14.0 のチュートリアル (2)

1. はじめに

「Unity ML-Agents」で、強化学習の学習環境を作成する手順を説明します。ボール(RollerAgent)がランダムに配置された立方体(Target)に向かって転がるように訓練する学習環境になります。

画像1

今回の学習環境の要素は次のとおりです。

・報酬 :
   ・RollerAgentTargetの位置に到着 : +1.0 (エピソード完了)
   ・RollerAgentが落下 : +0.0 (エピソード完了)
・観察
   ・Vector Observation (サイズ8)
       0 : TargetX座標
       1 : TargetY座標
       2 : TargetZ座標
       3 : RollerAgentX座標
       4 : RollerAgentY座標
       5 : RollerAgentZ座標
       6 : RollerAgentX速度
       7 : RollerAgentZ速度
・行動
   ・Continuous (サイズ2)
       0: RollerAgentX方向に加える力
       1: RollerAgentZ方向に加える力
・決定
   ・10フレーム毎

2. Unityの開発環境のインストール

Unity ML-Agents 0.14.0 のチュートリアル (1)」と同様になります。

3. Unity ML-Agentsのプロジェクトの準備

Unity ML-Agents 0.14.0 のチュートリアル (1)」と同様になります。

4. サンプルの学習環境の準備

非常にシンプルな強化学習の学習環境を作成します。
環境には、
・Agentが動き回るフロアとして機能する「Floor」
・Agentの転がり先としとして機能する「Target」
・Agent自体を表す「RollerAgent」
という3つのオブジェクトを配置します。

◎ Floorの追加
(1) Hierarchyウィンドウで右クリックし、「3D Object → Plane」を選択し、「Plane」を追加。
(2) 「Plane」に「Floor」という名前を付ける。
(3) 「Floor」を選択し、InspectorウィンドウのTransformで以下の設定を行う。

Position = (0, 0, 0)
Rotation = (0, 0, 0)
Scale = (1, 1, 1)

(4) 「Mesh Renderer」の「Materials → Element 0」に灰色の新規マテリアル「Gray」を追加。

画像2

◎ Targetの追加
(1) Hierarchyウィンドウで右クリックし、「3D Object → Cube」を選択し、「Cube」を追加。
(2) 「Cube」に「Target」という名前を付ける。
(3) 「Target」を選択し、InspectorウィンドウのTransformで以下の設定を行う。

Position=(3, 0.5, 3)
Rotation=(0, 0, 0)
Scale=(1, 1, 1)

(4) 「Mesh Renderer」の「Materials → Element 0」に茶色の新規マテリアル「Brown」を追加。

画像3

◎ RollerAgentの追加
(1) Hierarchyウィンドウで右クリックし、「3D Object → Sphere」を選択し、「Sphere」を追加。
(2) 「Sphere」に「RollerAgent」という名前を付ける。
(3) 「RollerAgent」を選択し、InspectorウィンドウのTransformで以下の設定を行う。

Position = (0, 0.5, 0)
Rotation = (0, 0, 0)
Scale = (1, 1, 1)

(4) 「Mesh Renderer」の「Materials → Element 0」に青の新規マテリアル「Blue」を追加。
(5) 「Add Component」で「Rigidbody」を追加。

画像4

5. Behavior Parametersの追加

「Behavior Parameters」は、Agentの「Brain」「観察空間」「行動空間」の設定を行うコンポーネントです。

(1) 「RollerAgent」に「Add Component」で「Behavior Parameters」を追加。
(2) 観察空間はサイズ8の「Vector Observation」、行動空間はサイズ2の「Continuous」なので、「Behavior Parameters」を次のように設定。

Behavior Name : RollerBallBrain
Vector Observation → Space Size : 8
Vector Action → Space Type : Continuous
Vector Action →  Space Size : 2

画像5

6. Decision Requesterの追加

「Decision Requester」は、Agentの「決定」を行うタイミングを設定するコンポーネントです。「RollerAgent」に「Add Component」で「Decision Requester」を追加してください。「決定」時には、CollectObservations()で観察収集を行い、収集した観察を元に次に採るべき行動を予測し、行動をAgentAction()に渡すという処理が行われます。

(1) 「RollerAgent」に「Add Component」で「Decision Requester」を追加。
(2) 今回は「決定」を行うタイミングを「10フレーム毎」とするので、「Decision Period」に「10」を指定。

画像6

7. Agentクラスを継承したスクリプトの追加

「Behavior Parameters」「Decision Requester」を追加したGameObjectに、Agentクラスを継承したスクリプトも追加します。

(1) 「RollerAgent」を選択して、「Add Component」で新規スクリプト「RollerAgent」を追加。
(2) 新規スクリプト「RollerAgent」を次のように編集。

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

// Agent
public class RollerAgent : Agent {
    public Transform target;
    Rigidbody rBody;

    // スタート時に呼ばれる
    void Start () {
        rBody = GetComponent<Rigidbody>();
    }

    // リセット時に呼ばれる
    public override void AgentReset() {
        if (this.transform.position.y < 0) {
            // 落下時は位置と速度をリセット
            this.rBody.angularVelocity = Vector3.zero;
            this.rBody.velocity = Vector3.zero;
            this.transform.position = new Vector3( 0, 0.5f, 0);
        }

        // 場所のリセット
        target.position = new Vector3(
            Random.value * 8 - 4, 0.5f, Random.value * 8 - 4);
    }

    // 観察収集時に呼ばれる
    public override void CollectObservations() {
        // TargetとRollerAgentの位置
        AddVectorObs(target.position);
        AddVectorObs(this.transform.position);

        // RollerAgentの速度
        AddVectorObs(rBody.velocity.x);
        AddVectorObs(rBody.velocity.z);
    }

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

        // RollerAgentがTargetの位置に到着
        float distanceToTarget = Vector3.Distance(
            this.transform.position, target.position);
        if (distanceToTarget < 1.42f) {
            SetReward(1.0f);
            Done();
        }

        // RollerAgentが落下
        if (this.transform.position.y < 0) {
            Done();
        }
    }

    // 方向キーで行動を決定
    public override float[] Heuristic() {
        var action = new float[2];
        action[0] = Input.GetAxis("Horizontal");
        action[1] = Input.GetAxis("Vertical");
        return action;
    }
}

(3) HierarchyウィンドウのTargetを新規スクリプト「RollerAgent」のTargetにドラッグ&ドロップ。

8. 学習環境ので動作確認

Unity Editorでシーンを実行することで、学習前の学習環境の動作確認ができます。方向キーでボールを動かし、立方体に衝突すると立方体が移動し、ボールが落下すると床の上に戻ることを確認してください。

画像7

学習環境の実行モードは「学習」「推論」「ヒューリスティック」の3種類があります。「学習」はPythonスクリプト、「推論」はモデルの推論、「ヒューリスティック」は人間操作が行動を決定します。

Unity Editorでシーンを実行した時に、どのモードが適用されるモードの条件は次のとおりです。

(1) 学習を行うPythonスクリプトが実行中 → 学習
(2) (1)以外で、Behavior ParametersのModelが存在 → 推論
(3) (1)(2)以外で、Heuristic()を定義 → ヒューリスティック

9. Pythonスクリプトによる学習

「Pythonスクリプト」を使って「サンプルの学習環境」を学習を行います。学習が完了すると「推論モデル」が生成されます。

(1) コンフィグファイルの準備。
コンフィグファイル(ml-agents/config/trainer_config.yaml)を初期値のままで実行すると、訓練に約300,000ステップかかります。
次の「RollerBallBrain」セクションをtrainer_config.yamlに追加し、ハイパーパラメータを調整することで、20,000ステップ未満で訓練できるようになります。

【trainer_config.yaml (追加)】

RollerBallBrain:
   batch_size: 10
   buffer_size: 100
   max_steps: 2.0e4

(2) mlagents-learnの実行。
学習を開始するには、次のコマンドを実行します。

$ mlagents-learn config/trainer_config.yaml --run-id=RollerBall-1 --train

(3) Unity EditorのPlayボタン(▶)を押して学習開始します。


この記事が気に入ったらサポートをしてみませんか?