[Unity 2D] 2DでML-Agentsを導入して学習させる方法。

(2023/07/28)
2DでML-Agentsを導入して学習させる方法

・参考にしたページ
実行環境
  • macOS:Ventura(バージョン13.0.1)
  • Unityのバージョン:2021.3.11f1
  • ML-Agentsのバージョン:Release 20
  • Pythonのバージョン:3.9.0

  • 新しい2DプロジェクトにML-Agentsを導入

    まずターミナルを起動し、ML-Agents Toolkitを任意の場所にクローンします。

    $ git clone --branch release_20 https://github.com/Unity-Technologies/ml-agents.git

    次にUnityの新しい2Dプロジェクトを作成します。プロジェクトのバージョンは2021.3以降を選択してください。

    プロジェクトが開いたら、Window→Package Managerをクリックし「+」からAdd package from disk...を選択します。

    2DでML-Agentsを導入して学習させる方法。

    クローンしたml-agents→com.unity.ml-agents→package.jsonを選択します。

    オブジェクトを用意

    まずMain CameraのCameraコンポーネントのSizeを7に変更し、下の画像のようにオブジェクトを追加します。

    2DでML-Agentsを導入して学習させる方法。

    ①壁を追加
    ・ Hierarchy ウィンドウで右クリックし、2D Object→Sprites→Squareを選択します。
    ・ Squareを選択しInspectorで名前を「UpWall」に変更します。
    ・ Sprite RendererコンポーネントのColorを黒色に変更します。
    ・ Transformの値をPosition(0, 6, 0)、Rotation(0, 0, 0)、Scale(11, 1, 1)に変更します。

    2DでML-Agentsを導入して学習させる方法。

    同じように、Hierarchy ウィンドウから2D Object→Sprites→Squareを選択し、Sprite RendererコンポーネントのColorを黒色に変更して、下と左右の壁を作成していきます。

    下の壁
    ・名前を「DownWall」
    ・Transformの値をPosition(0, -6, 0)、Rotation(0, 0, 0)、Scale(11, 1, 1)に変更します。
    右の壁
    ・名前を「RightWall」
    ・Transformの値をPosition(6, 0, 0)、Rotation(0, 0, 0)、Scale(1, 13, 1)に変更します。
    左の壁
    ・名前を「LeftWall」
    ・Transformの値をPosition(-6, 0, 0)、Rotation(0, 0, 0)、Scale(1, 13, 1)に変更します。

    ②Circleを追加
    ・ Hierarchy ウィンドウで右クリックし、2D Object→Sprites→Circleを選択します。
    ・ Circleを選択しInspectorで名前を「Target」に変更します。
    ・ Sprite RendererコンポーネントのColorを赤色に変更します。
    ・Transformの値をPosition(0, 3, 0)、Rotation(0, 0, 0)、Scale(1, 1, 1)に変更します。

    2DでML-Agentsを導入して学習させる方法。

    ③Squareを追加
    ・ Hierarchy ウィンドウで右クリックし、2D Object→Sprites→Squareを選択します。
    ・ Squareを選択しInspectorで名前を「SquareAgent」に変更します。
    ・Transformの値をPosition(0, 0, 0)、Rotation(0, 0, 0)、Scale(1, 1, 1)に変更します。

    2DでML-Agentsを導入して学習させる方法。

    ④オブジェクトをグループ化
    ・Hierarchyウィンドウで右クリックし、Create Emptyを選択します。
    ・GameObjectを選択しInspectorで名前を「TrainingArea」に変更します。
    ・Transformの値をPosition(0,0,0)、Rotation(0,0,0)、Scale(1,1,1)に設定します。
    ・UpWall、DownWall、RightWall、LeftWall、SquareAgent、Target、を選択してTrainingAreaにドラッグします。

    2DでML-Agentsを導入して学習させる方法。
    SquareAgentにスクリプト・コンポーネントを追加

    ①SquareAgent→Add Componentで、Rigidbody2Dコンポーネントを追加し、Gravity Scaleを0に変更します。

    ②SquareAgent→Add Componentで適当な名前のスクリプトを追加します。
    ここではSquareAgentという名前のスクリプトを作成しました。

    作成したスクリプトに下のコードを貼り付けます。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    //MLAgentsを使えるように名前空間を追加
    using Unity.MLAgents;
    using Unity.MLAgents.Sensors;
    using Unity.MLAgents.Actuators;
    
    //MonoBehaviourをAgentに変更
    public class SquareAgent : Agent
    {
      public Transform Target;
    
      public Transform upWall;
      public Transform downWall;
      public Transform rightWall;
      public Transform leftWall;
    
      Rigidbody2D rb;
    
      bool initialPosition;
    
      public float moveForce = 10f;
    
      public override void Initialize()
      {
        initialPosition = false;
        rb = GetComponent<Rigidbody2D>();
      }
    
      //エピソードの開始
      public override void OnEpisodeBegin()
      {
        //Agentが壁に近づいた時の処理
       if (initialPosition == true) {
         initialPosition = false;
         this.rb.velocity = Vector2.zero;
         this.transform.localPosition = Vector2.zero;
       }
       //Targetの新しい位置
       Target.localPosition = new Vector2(Random.value * 10 - 5,Random.value * 10 - 5);
      }
    
      //環境の情報を収集
      public override void CollectObservations(VectorSensor sensor)
      {
      //TargetとAgentの位置
      sensor.AddObservation(Target.localPosition);
      sensor.AddObservation(this.transform.localPosition);
      //Agentの速度
      sensor.AddObservation(rb.velocity.x);
      sensor.AddObservation(rb.velocity.y);
      }
    
      //Agentの移動と報酬
      public override void OnActionReceived(ActionBuffers actionBuffers)
      {
      //Agentを移動させる
      Vector2 conSig = Vector2.zero;
      conSig.x = actionBuffers.ContinuousActions[0];
      conSig.y = actionBuffers.ContinuousActions[1];
      rb.AddForce(conSig * moveForce);
    
      //TargetとAgentの距離を取得
      float distanceToTarget = Vector2.Distance(this.transform.localPosition, Target.localPosition);
    
      //TargetとAgentの距離が1.42より小さい場合、1.0の報酬を与えてエピソードを終了する
      if (distanceToTarget < 1.42f)
      {
         SetReward(1.0f);
         EndEpisode();
      }
    
      //Agentが壁に近づいたらエピソードを終了する
      else if (rightWall.localPosition.x - 1f < this.transform.localPosition.x || leftWall.localPosition.x + 1f > this.transform.localPosition.x || upWall.localPosition.y - 1f < this.transform.localPosition.y || downWall.localPosition.y + 1f > this.transform.localPosition.y) {
       initialPosition = true;
       EndEpisode();
      }
    
      }
    
     //人が操作するときの処理
      public override void Heuristic(in ActionBuffers actionsOut)
      {
      var continuousActionsOut = actionsOut.ContinuousActions;
      continuousActionsOut[0] = Input.GetAxis("Horizontal");
      continuousActionsOut[1] = Input.GetAxis("Vertical");
      }
    }
    
    

    ③SquareAgentのTargetにHierarchyのTarget、upWallにHierarchyのUpWall、dwonWallにHierarchyのDwonWall、rightWallにHierarchyのRightWall、leftWallにHierarchyのLeftWallをそれぞれドラッグします。

    2DでML-Agentsを導入して学習させる方法。

    ④Add ComponentからDecision Requesterを追加し、Decision Periodを10に変更します

    2DでML-Agentsを導入して学習させる方法。

    ⑤Add ComponentからBehavior Parametersを追加して、下のように設定します。
    ・Behavior NameをCollectorSquareに変更します。
    ・Vector ObservationのSpace Sizeを8に変更します。
    ・ActionsのContinuous Actionsを2に変更します。
    ・Discrete Branchesを0に変更します。
    ・ModelのInference DeviceをCPUに変更します。

    2DでML-Agentsを導入して学習させる方法。
    正しく動作するかテスト

    SquareAgentのBehavior ParametersのBehavior TypeをHeuristic Onlyに変更して、Unityエディターを再生したら、SquareAgentを矢印キーで操作できるのでSquareAgentが壁に接近した時、Targetに接近した時の動作を確認します。

    正しく動作していることが確認できたら、Behavior TypeをDefaultに戻しておきます。

    トレーニングの高速化

    トレーニングを高速化するためHierarchyウィンドウのTrainingAreaをプレハブ化して、シーン内に重ならないように複数配置します。

    2DでML-Agentsを導入して学習させる方法。
    CollectorSquare.yamlファイルを作成

    クローンしたml-agentsのファイル→configファイルにCollectorSquare.yamlファイルを作成します

    2DでML-Agentsを導入して学習させる方法。

    CollectorSquare.yamlファイルに下のコードを貼り付けます。(GitHubのMl-Agentsのサンプルのものをそのまま使用しています。)

    behaviors:
     CollectorSquare:
       trainer_type: ppo
       hyperparameters:
         batch_size: 10
         buffer_size: 100
         learning_rate: 3.0e-4
         beta: 5.0e-4
         epsilon: 0.2
         lambd: 0.99
         num_epoch: 3
         learning_rate_schedule: linear
       network_settings:
         normalize: false
         hidden_units: 128
         num_layers: 2
       reward_signals:
         extrinsic:
           gamma: 0.99
           strength: 1.0
       max_steps: 500000
       time_horizon: 64
       summary_freq: 10000
    

    yamlファイルの詳細は、下のGitHubのページで確認することができます。

    SquareAgentを学習させるための準備

    ①ターミナルでPythonのバージョンが3.8.13以降であることを確認します。

    $ python3 -V

    ②サンプルを学習させるために仮想環境を使うのでターミナルを立ち上げて任意の場所にディレクトリを作ってください。今回はSampleという名前のディレクトリを作りました。

    $ mkdir Sample

    ③cdコマンドでSampleに移動した後、今回使う新しい環境を作成します。ここでは、learning-envという名前の仮想環境を作成しました。

    $ python3 -m venv learning-env

    ④仮想環境が作成できたら、作成した仮想環境を有効化します。

    $ source learning-env/bin/activate

    ⑤仮想環境を有効化している状態でpipとsetuptoolsをアップグレードします。

    $ pip3 install --upgrade pip
    $ pip3 install --upgrade setuptools

    ⑥mlagentsPythonパッケージをインストールします。

    $ python -m pip install mlagents==0.30.0

    ⑦仮想環境を有効化している状態でprotobufのバージョンを3.19.6に変更します。

    $ pip3 install protobuf==3.19.6

    仮想環境は$ deactivateで終了することができます。

    $ deactivate
    SquareAgentを学習させる

    仮想環境を有効化している状態でターミナルでcdコマンドを使い、クローンしたml-agentsのファイルに移動します。移動できたら下のコマンドを入力します。
    (--run-id=の「CollectorSquare」は好きに変えてもらっても大丈夫です。)

    $ mlagents-learn config/CollectorSquare.yaml --run-id=CollectorSquare

    ターミナルにUnityのロゴが表示されたら、Unityエディターでシーンを再生します。

    問題なく動作すれば学習が開始されます。

    学習はターミナルでCtrl+Cを実行することで終了させることができます。

    学習させたモデルを使う

    学習させたモデルはクローンしたml-agentsのresultsの中の保存されます。今回は、resultsにCollectorSquareというディレクトリが作成されているはずなので、そのディレクトリの中のCollectorSquare.onnxをUnityのProjectウィンドウのAssetsにドラッグアンドドロップします。

    次に、SquareAgentのBehaviorParametersのModelにCollectorSquare.onnxをドラッグします。

    その状態でUnityエディターを再生すると、学習させたモデルを使うことができます。

     
    他の記事も見る
     
  • プライバシーポリシー