6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ML-Agents入門

Last updated at Posted at 2021-12-26

はじめに

※この記事はRICORA Advent Calendar 12/24 の記事になります。

本記事ではUnityの深層強化学習パッケージのML-Agentsの導入と簡単なモデルの実装を行います。

パッケージなどのバージョンは以下の通りです。少なくともML-Agentsのバージョンは合わせてください。最新バージョンだと色々変わりすぎてて動きません。

  • Unity: 2021.2.0f1
  • ML-Agents: Release3 (1.1.0)
  • Python: 3.7.10

以下Pythonライブラリ

  • mlagents: 0.17.0
  • mlagents-env: 0.17.0
  • gym_unity: 0.17.0

さっそくML-Agentsのインストールから始めていきましょう!

ML-Agentsのインストール

UnityとPythonのインストールは各自でお願いします。PythonはAnacondaを使って入れることをおススメします。

ML-AgentsのGithubからまずはパッケージ群をダウンロードしてきましょう。
github_download.png
解凍したらUnityフォルダ内に配置しておくと扱いやすいと思います。名前もml-agentsに変更しておきましょう。

次はUnity内でパッケージのインポートを行います。

パッケージマネージャーを選択してml-agentsのcom.unity.ml-agentsフォルダにあるpackage.jsonをインポートします。

PackageManager.png

AddPackage.png

ML Agents 1.1.0-previewというものが追加されていればOKです。

あとはPythonに必要なライブラリをインストールしましょう。

pip install mlagents=0.17.0
pip install mlagents-env=0.17.0
pip install gym_unity=0.17.0

これでML-Agentsの環境が整いました。次に簡単なデモを作ってML-Agentsによる作業の流れを体験してみましょう!

ML-Agentsプロジェクトの作成

デモとしてボールがターゲットを追跡する簡単なモデルを作ってみましょう。プロジェクト名はBall Agentとしています。

モデルの作成

まずはモデル作りからです。床とエージェントとターゲットを作成します。

Hierarchyウィンドを右クリックしてPlaneを作成します。

plane.png

Positionは(0,0,0)にしましょう。

plane_pos.png

同様にCubeとSphereも追加しましょう。両方とも高さは0.5にしてます。実は初期位置はあまり関係ないので、適当な見やすい位置に置いておきましょう。

sphere_cube.png

HierarchyウィンドからSpehreを右クリックしてRenameから名前の変更を行いましょう。Sphere⇒Agent、同様にCube⇒Targetと変更します。

rename.png
次に物体が少し見づらいのでマテリアルを適用して色を付けてみましょう。

プロジェクトウィンドのてきとうな位置を右クリックしてCreateのMaterialを選択します。名前はGreenにします。
material.png

マテリアルができたらInspectorウィンドのAlbedoを選択して緑っぽい色を選んでください。
green.png

同様に黄色も作りましょう。

色が作れたら物体に直接ドラッグ&ドロップして色を適用します。

attempt.png

これで物体の視認性が良くなりました。次は物体の中身を作っていきましょう。

コンポネントを付与する

モデルは配置しただけでは何も起きません。物理演算やML-Agentsを適用をするためには、コンポネントというものをモデルに追加する必要があります。

まずAgentに必要なコンポネントを追加していきます。

Agentを選択してInspectorウィンドからAdd Componentを選択してください。

inspector.png

検索からBehavior Parametersを探して追加します。

追加されたら下の図で赤く囲った部分の項目を同じように変更してください。

behavior_parameters.png

Vector ObsevationのSpace Sizeは観測する値が何個あるかを表します。Vector ActionのSpace Typeは受け取る入力の種類です。Continuousは連続値を返します。Space Sizeは何個値を入力するかを表します

同様にRigidBodyもAdd Componentから追加します。特に設定はしません。

同様にAdd ComponentからNew scriptを選択してBallAgentという名前でスクリプトファイルを生成します。

プロジェクトウィンドにBallAgentというスクリプトが追加されてるので。ダブルクリックして編集します。
script.png

スクリプトを以下のように変更します。

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

public class BallAgent : Agent {
    public Transform target;
    Rigidbody rigid;

    public override void Initialize() {
        this.rigid = GetComponent<Rigidbody>();
    }

    public override void OnEpisodeBegin() {
        if (this.transform.position.y < 0) {
            this.rigid.angularVelocity = Vector3.zero;
            this.rigid.velocity = Vector3.zero;
            this.transform.position = new Vector3(0.0f, 0.5f, 0.0f);
        }
        target.position = new Vector3(Random.value*8-4, 0.5f, Random.value*8-4);
    }

    public override void CollectObservations(VectorSensor sensor) {
        sensor.AddObservation(target.position);
        sensor.AddObservation(this.transform.position);
        sensor.AddObservation(rigid.velocity.x);
        sensor.AddObservation(rigid.velocity.z);
    }

    public override void OnActionReceived(float[] vectorAction) {
        Vector3 controlSignal = Vector3.zero;
        controlSignal.x = vectorAction[0];
        controlSignal.z = vectorAction[1];
        rigid.AddForce(controlSignal * 10);
        float distanceToTarget = Vector3.Distance(this.transform.position, target.position);
        if (distanceToTarget < 1.42f) {
            AddReward(1.0f);
            EndEpisode();
        }
        if (this.transform.position.y < 0) {
            EndEpisode();
        }
     }
}

オーバーライドした関数について大まかな説明します。

Initialize
トレーニングの最初に呼び出されます。ここではRigidbodyのインスタンスを取得しています。

OnEpisodeBegin
エピソードの開始時に呼び出され。ここでは主にトレーニングの環境を準備します。今回はターゲットのランダムな位置変更とエージェントの回転、速度のリセットを行っています。

CollectObservations
観察を行うときに呼び出されます。ここではターゲットの座標(x,y,z)、エージェントの座標(x,y,z)、エージェントの速度(x,z)の合計8個の値を受け取っています。ここで受け取る値の数はBehavior Parametersで設定したSpace Sizeと同じにする必要があることに注意してください。

OnActionReceived
行動を指示するときに呼び出されます。ここでは受け取った値でエージェントに力(x,z)を与えています。またエージェントが終了条件を満たしていた時にエピソードを終了する処理を行っています。今回はエージェントがターゲットに一定距離近づくと報酬を受け取って終了、またはエージェントが床から落ちると報酬なしで終了となっています。

これでスクリプトの準備ができました。スクリプト内のtargetの割り当てをUnityの方から行います。

AgentのInspectorウィンドを開いてBall AgentのスクリプトのTargetにHieracchyウィンドのTargetをドラッグ&ドロップします。TargetがNoneからTargetに変更されたら成功です。
同時にBall AgentのスクリプトのMax Stepを1000に設定してください。

target_attempt.png

最後にDecision RequesterをAdd Componentから追加しましょう。Decision Periodは10に設定します。これは何フレーム毎に行動を行うかを設定するものです。数値を小さくすると行動を行う回数が増えます。

decision_requester.png

これで環境の準備が終わりました。トレーニングを実行していきましょう!

ML-Agentsトレーニングの方法

トレーニングを開始する前に必要なパラメーターを記述してyamlファイルを準備します。

BugAgent.yaml
behaviors:
  Agent:
    trainer_type: ppo
    hyperparameters:
      batch_size: 10
      buffer_size: 100
      learning_rate: 0.0003
      beta: 0.005
      epsilon: 0.2
      lambd: 0.95
      num_epoch: 3
      learning_rate_schedule: linear
    network_settings:
      normalize: true
      hidden_units: 128
      num_leyers: 2
      vis_encode_type: simple
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
    keep_checkpoints: 5
    checkpoint_interval: 50000
    max_steps: 50000
    time_horizon: 64
    summary_freq: 1000
    threaded: true

ml-agent内のconfigフォルダーにBallAgentフォルダーを作って、そこにBallAgent.yamlを作りました。

次にコマンドプロンプトを起動してml-agentフォルダーに移動して次のコマンドを実行します。

mlagents-learn ./config/BallAgent/BallAgent.yaml --run-id=firstRun

先ほど作成したyamlファイルの指定と保存するidを決めます。

一度実行したあとでやり直そうとするとすでにフォルダーが生成されているためエラーになってしまいます。
実行を途中からやり直したいときは先ほどのコマンドの後ろに--resumeを付けてください。

mlagents-learn ./config/BallAgent/BallAgent.yaml --run-id=firstRun --resume

実行後に次のように表示されれば成功です。後はUnityのプレイボタンを押すと学習が開始されます。

dos.png

実行後の様子です。爆速で球が動いていたらトレーニングができています。

play.png

トレーニング中はターミナルにsummaryが表示されます。mean rewardが上がっていく様子が分かると思います。

training_dos.png

今回は比較的簡単なタスクなので、ステップ数を5万回に設定しましたが早い段階でmean rewardが1に収束しているのが分かると思います。

トレーニングが終了したら結果を確認してみましょう。

トレーニング後のフィードバック

トレーニングが完了するとml-agentsフォルダーのresultsフォルダー内にidで指定した名前のフォルダーが生成されているのが分かると思います。今回はfirstRunという名前で保存されているはずです。

firstRunフォルダーを開いてAgent.nnというファイルをUnity内のProjectウィンド内にドラッグ&ドロップします。ニューラルネットのアイコンでAgentというファイルが出現します。

agentnn.png

AgentのInspectorウィンドを開いてBehavior ParametersのModelのところにAgentをドラッグ&ドロップします。

model_attach.png

ModelがNoneからAgentに変わったらPlayボタンを押して実行してみましょう。
トレーニング中とは違い通常の速度で推論が行われます。トレーニングが成功していればボールが床から落ちずに出現したターゲットにを追いかける様子が見れると思います。

次にトレーニング中の報酬の推移などを見てみましょう。

ターミナルを起動してml-agentsに移動します。そこで次のコマンドを実行します。

tensorboard --logdir=./results/firstRun

すると次のように表示されるので、赤線を引いた部分のURLをコピーしてウェブブラウザで開きます。

tensorbaord_dos.png

すると次のようにTensorBoardが表示されます。Culmitive Rewardは報酬の推移、Episode Lengthはエピソードの長さを表しています。報酬が1に収束していることとエピソードの長さが短くなっていることが確認できると思います。

tensorbaord.png

このしたにLossやPolicyの情報も表示されます。興味があればそちらも見てみましょう。

まとめ

ML-Agentsの導入から簡単なモデルの作成とトレーニングのデモを行いました。

次の記事では4足歩行のモデルを作成し、そのトレーニングを行ってみたいと思います。お楽しみに!!!

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?