見出し画像

Unityではじめる強化学習入門 / カスタムメッセージの作成

「Unity ML-Agents」では、「Unity環境」と「Pythonスクリプト」が、「protobuf」形式のメッセージで通信しています。デフォルトで含まれていない構造化データを交換したい場合は、「カスタムメッセージ」を作成することができます。

1. カスタムメッセージの実装

「カスタムメッセージ」のフィールドを変更するたびに、以下のドキュメントに従って、新しいメッセージに対応するC#/Pythonファイルを作成し、「ML-Agent」sのPythonパッケージを再インストールする必要があります。

Unity ML-Agents Protobuf Definitions

2. カスタムメッセージの種別

現在サポートされているカスタムメッセージの種別は次の3つです。

・カスタム行動
・カスタム観察
・カスタムリセットパラメータ

3. カスタム行動

デフォルトの「Pythonスクリプト」は、行動を「浮動小数リスト」および「文字列」形式で「Unity環境」に渡します。

◎カスタム行動の定義
「pprotobuf-definitions/proto/mlagents/envs/communicator_objects/custom_action.proto」を編集することで、カスタム行動を定義して利用することができます。

【custom_action.proto】

syntax = "proto3";

option csharp_namespace = "MLAgents.CommunicatorObjects";
package communicator_objects;

message CustomAction {
}

◎カスタム行動の利用
「カスタム行動」は、「Pythonスクリプト」のenv.step()の「custom_action」によって、「Unity環境」に渡します。

env.step(action, memory=None, text_action=None, value=None, custom_action=None)

「Unity環境」では、AgentAction()で受け取ります。

public void AgentAction(float[] vectorAction, string textAction, CommunicatorObjects.CustomAction customAction)

◎カスタム行動の定義と利用の例
以下は、エージェントが歩く基本的な方向と歩く距離を選択するように指示するカスタム行動の例です。

【custom_action.proto】

syntax = "proto3";

option csharp_namespace = "MLAgents.CommunicatorObjects";
package communicator_objects;

message CustomAction {
   enum Direction {
       NORTH=0;
       SOUTH=1;
       EAST=2;
       WEST=3;
   }
   float walkAmount = 1;
   Direction direction = 2;
}

「Pythonスクリプト」でのカスタム行動を渡すコードは、次の通りです。

from mlagents.envs.communicator_objects import CustomAction
env = mlagents.envs.UnityEnvironment(...)
...
action = CustomAction(direction=CustomAction.NORTH, walkAmount=2.0)
env.step(custom_action=action)

「Unity環境」でカスタム行動を受け取るコードは、次の通りです。

...
using MLAgents;
using MLAgents.CommunicatorObjects;

class MyAgent : Agent {
   ...
   override public void AgentAction(float[] vectorAction, string textAction, CustomAction customAction) {
       switch(customAction.Direction) {
           case CustomAction.Types.Direction.North:
               transform.Translate(0, 0, customAction.WalkAmount);
               break;
           ...
       }
   }
}

protobufコンパイラは、CustomActionメッセージで定義したカスタムフィールド名のC#バージョン大文字化スキームを、C#規則に合わせて自動的に変換することに注意してください。「NORTH」は「North」、「walkAmount」は「WalkAmount」になります。

4. カスタム観察

デフォルトの「Unity環境」は、観察を「浮動小数点ベクトル」形式で「Pythonスクリプト」に渡します。

◎カスタム行動の定義
「pprotobuf-definitions/proto/mlagents/envs/communicator_objects/custom_observation.proto」を編集することで、カスタム観察を定義して利用することができます。

【custom_observation.proto】

syntax = "proto3";

option csharp_namespace = "MLAgents.CommunicatorObjects";
package communicator_objects;

message CustomObservation {
}

◎カスタム観察の利用
「カスタム観察」は、「Unity環境」のCollectObservations()によって、「Unity環境」に渡します。

class MyAgent : Agent {
   override public void CollectObservations() {
       var obs = new CustomObservation();
       obs.CustomField = 1.0;
       SetCustomObservation(obs);
   }
}

「Pythonスクリプト」では、「custom_observations」で受け取ります。

...
result = env.step(...)
result[brain_name].custom_observations[0].customField

5. カスタムリセットパラメータ

デフォルトの「Pythonスクリプト」は、リセットパラメータを、「キーが文字列で値がfloatの辞書形式」で「Unity環境」に渡します。

◎カスタムリセットパラメータの定義
「pprotobuf-definitions/proto/mlagents/envs/communicator_objects/custom_reset_parameters.proto」を編集することで、カスタムリセットパラメータを定義して利用することができます。

syntax = "proto3";

option csharp_namespace = "MLAgents.CommunicatorObjects";
package communicator_objects;

message CustomResetParameters {
}

◎カスタムリセットパラメータの利用
「カスタムリセットパラメータ」は、「Pythonスクリプト」のenv.reset()の「custom_reset_parameters」によって、「Unity環境」に渡します。

env.reset(train_model=True, config=None, custom_reset_parameters=None)

「Unity環境」では、「Academy」の「customResetParameters」で受け取ります。

customResetParameters

◎カスタム行動の定義と利用の例
以下は、ボックスの初期位置と色を指定するリセットパラメータの例です。

【custom_reset_parameters.proto】

message CustomResetParameters {
   message Position {
       float x = 1;
       float y = 2;
       float z = 3;
   }
   message Color {
       float r = 1;
       float g = 2;
       float b = 3;
   }
   Position initialPos = 1;
   Color color = 2;
}

「Pythonスクリプト」でのカスタムリセットパラメータを渡すコードは、次の通りです。

from mlagents.envs.communicator_objects import CustomResetParameters
env = ...
pos = CustomResetParameters.Position(x=1, y=1, z=2)
color = CustomResetParameters.Color(r=.5, g=.1, b=1.0)
params = CustomResetParameters(initialPos=pos, color=color)
env.reset(custom_reset_parameters=params)

「Unity環境」でカスタムリセットパラメータを受け取るコードは、次の通りです。

public class MyAcademy : Academy
{
   public GameObject box;

   override public void AcademyReset()
   {
       var boxParams = customResetParameters;
       if (boxParams != null)
       {
           var pos = boxParams.InitialPos;
           var color = boxParams.Color;
           box.transform.position = new Vector3(pos.X, pos.Y, pos.Z);
           box.GetComponent<Renderer>().material.color = new Color(color.R, color.G, color.B);
       }
   }
}


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