Unity ML-Agents Toolkitを触って機械学習を体験してみる
Unityで機械学習が使えるようになる「Unity ML-Agents Toolkit」を試してみました。
使用したML-Agentsのバージョンは0.5.0です
今回は下のアニメのように、転がってボールをバッテングで打ち返す部分を学習させてみましたのでML-Agentsをさわる際にポイントになる部分をまとめたいと思います。

学習回数: 10万回

学習回数: 1万回

学習回数: 千回
学習回数別の学習結果です。回数を重ねるごとに上達していますね。
バットの振る前に一度反対側に振りかぶるところまで学習しているところなど面白いです!
設定していった箇所を、参考にさせていただいた下記サイトにあった、アクション、ステート、リワードの順に説明していきます。
・【Unity】Unityで機械学習する「ML-Agent」を色々と試して得た知見とか - テラシュールブログ
アクション
機械学習AIからの指示されるアクションは、今回の場合はfloat値が1つのみで、バットを回転させる AddTorque() に使う数値に使用しています。
下の方にあるソースコードでいう vectorAction[0] です。
vectorAction[0] に渡される数値は-1~1の範囲が来るみたいです。
vectorAction の配列の個数を増やしたい場合は以下の赤枠のところで設定します。

ステート
観測していく値の設定ですね。
今回は以下の9つを観測させるようにしました。
・ボールの localPosition.x
・ボールの localPosition.z
・ボールの velocity.z
・バットの localRotation.x
・バットの localRotation.y
・バットの localRotation.z
・バットの velocity.x
・バットの velocity.y
・バットの velocity.z
以下、アクションとステートを設定したソースです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BattingAgent : Agent {
public GameObject ball;
public GameObject bat;
private Rigidbody ballRb;
private Rigidbody batRb;
public BattingArea area;
public override void InitializeAgent()
{
ballRb = ball.GetComponent<Rigidbody>();
batRb = bat.GetComponent<Rigidbody>();
}
public override void CollectObservations()
{
AddVectorObs(ball.transform.localPosition.x);
AddVectorObs(ball.transform.localPosition.z);
AddVectorObs(ballRb.velocity.z);
AddVectorObs(bat.transform.localRotation.x);
AddVectorObs(bat.transform.localRotation.y);
AddVectorObs(bat.transform.localRotation.z);
AddVectorObs(batRb.velocity);
}
public override void AgentAction(float[] vectorAction, string textAction)
{
float forceY = Mathf.Clamp(vectorAction[0], -1f, 1f) * 10000f;
bat.GetComponent<Rigidbody>().AddTorque(new Vector3(0, forceY, 0),ForceMode.Force);
}
public override void AgentReset()
{
area.set_bat();//バットの位置初期化
area.start_throw();//ボールを投げる
}
}
リワード
報酬の設定です。今回は以下のようにしました。
・ボールがバットに当たるとちょっとだけプラス報酬
・ボールが緑のゾーンに当たるとプラス報酬
・さらにボールの勢いが強いと追加でプラス報酬
・緑のゾーン以外に飛んでいくとマイナス報酬
以下、報酬を設定したコードです。(ボールにアタッチしたクラスの該当箇所)
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("hitWall")) {
float velocityZ = GetComponent<Rigidbody>().velocity.z;
if (velocityZ < -5) {
agent.SetReward(1f);
} else if (velocityZ < -3.5) {
agent.SetReward(0.8f);
} else if (velocityZ < -2) {
agent.SetReward(0.5f);
} else {
agent.SetReward(0.3f);
}
agent.Done();
} else if (collision.gameObject.CompareTag("outWall")) {
agent.AddReward(-1f);
agent.Done();
} else if (collision.gameObject.name== "bat") {
agent.SetReward(0.1f);
}
}
感想
最初はボールをコロコロ転がすタイプじゃなくて、普通のピッチングみたいにボールを空中に投げるタイプのものを作ってたのですが、最初のテストには複雑すぎたみたいで、学習回数30万回でもうまくバットでボールを前へ飛ばすところまでもっていけませんでした。(報酬の与え方やパラメータ設定のコツが分かってくるとうまくいくんじゃないかとは思いますが)、まずは学習がうまくいくか試したかったので今回のコロコロタイプに変更しました。
あと、最初はPythonを編集する必要があるのかなーと思っていたのですが、Pythonのインストールは必要ですけど、Tensorflowとのやりとりは全てML-Agent側で用意されているので、Unity用のC#をいじるのみで済みました。





こんにちは。
takaと申します。
私は現在ml-agentsでの強化学習を勉強しており、ml-agentsについて調べている際に当サイトを見つけました。
とても参考になり、このようなサイトを作っていただいたことに大変感謝しております。
特に、バッティングの強化学習には興味を引かれ、私もこのようなものを作ってみたいと思ったのですが参考にしながら作ってもなかなかうまくいきません。
そこで、まずは一度動かしてみたいのですが、このunityプロジェクトは公開してはいないのでしょうか。
コメントありがとうございます!
このUnityプロジェクトは公開する前提で作ってなくて、ちょっと公開する予定はないのですが、(ML-Agents のバージョンも 0.5.0で古いですし)
まず一度ML-Agentsの動作を確認したいということでしたら下記のML-AgentsのUnityプロジェクトに入っているExamples内のシンプルなものでテストするのが一番確実な気がします。
https://github.com/Unity-Technologies/ml-agents
既に試していたらすみません。