その他
    ホーム エンジニア AI Unity SentisとML-Agentsを試してみた
    Unity SentisとML-Agentsを試してみた
     

    Unity SentisとML-Agentsを試してみた

    はじめに

    おうさぎ様との同居生活が三年目に入りました。ゲームデザイン(GD)部クライアントエンジニアの中村です。

    最近AIが流行っているらしいので、Unity使いとしても何らかAIを取り入れていかなければと思っていました。そんなときにUnity Sentisがオープンベータになったという記事を見かけたので、せっかくだからML-Agentsと併せて触ってみようと思った次第です。

    Unity Sentis

    ONNX ファイル形式でインポートされた AI モデルは、Unity がサポートするすべてのプラットフォームで直接実行することができます。つまり、クラウドインフラストラクチャを必要とせず、直接ユーザーデバイス上の Unity ランタイムで、大半の AI モデルを実行できます。

    https://blog.unity.com/ja/games/create-next-gen-ai-models-with-unity-sentis

    なんとモバイル端末でもAIモデルを利用した推論が可能となります。githubにサンプルが公開されていますが、ニューラルネットワークによってオセロを学習したAIとの対戦や、MNISTによる手書き文字認識を行うことができます。その他にも、AIモデルを用意すれば音声認識やText-To-Speech、物体認識も可能であり、Hugging Faceなどで公開されているモデルも動作させることができます。

    Unity ML-Agents

    Unity Machine Learning Agents(ML-Agents)なら、創発的挙動を「コーディング」することなく、代わりに深層強化学習と模倣学習の組み合わせを通じて「学習」するよう、知的エージェントに教育できます。

    https://unity.com/ja/products/machine-learning-agents

    Sentisで公開されていたサンプルのような「ターン制ボードゲーム」「手書き文字認識」などの学習データが容易に用意できるゲームでは、知識があれば独自AIモデルを作成することも難しくありません。しかし、対戦格闘ゲームやシューティングゲームなどのアクション要素が強いゲームでは学習データの用意が難しくなります。

    ML-Agentsではこれら学習対象となる「エージェント」をもとにしたAIモデルの作成をサポートします。こちらもgithubにサンプルが公開されています。

    SentisとML-Agentsの関係

    SentisはAIモデルを読み込み、推論に必要なパラメータを与えるとその結果を返すという仕組みになっています。

    ML-AgentsはSentisを介してAIモデルによる推論を行いエージェント(GameObject)の行動を決定します。

    この2つの関係性は、個人的な理解ですが以下のようになっていると思っています。Sentis単体で動作することはできるが、ML-Agentsはその内部でSentisに依存していることになるでしょう。

    Unity内でのML-AgentsとSentisの関係

    ML-Agentsサンプルを動かす

    さっそくサンプルに触れていきます。

    搭載されたAIモデルを利用する

    まずダウンロードしたサンプルの中にあるUnityプロジェクトから「3DBall」を開きます。今回はUnity2022.3.19で動作しています。

    プレイすると、青い箱が頭にボールを乗せて落とさないようにしている様子を見ることができます。青い箱1つ1つがエージェントであり、その姿勢とボールの速度からボールを落とさないように学習されたAIモデルを搭載しています。健気で可愛いですね。

    ML-Agentsによってボールを落とすことができなくなった青い箱たち

    これはサンプルに含まれる学習済みのAIモデルをそのまま利用しています。それではAIモデルの生成も行ってみましょう。

    AIモデルを生成する

    ML-Agentsのサンプルプロジェクトには学習モデルを生成するためのPythonコードも含まれています。

    今回はM1Macで行った影響か、Pythonやパッケージのバージョンにかなり縛りがありました。まず、なぜかPython3.10.12でなければ動作しませんでした。さらにReadMeにあるインストールコマンドもそのままではエラーが出るため、issuesに記載された暫定対策を行って環境を整備しました。

    基本的にはPython3を用意し、以下のコマンドを実行するだけで準備ができます。ml-agentsのPythonパッケージをインストールするのでvenvの使用を推奨します。

    $ pip install ./ml-agents-envs 
    $ pip install ./ml-agents 

    環境が整ったら以下のコマンドでml-agents(Pythonのほう)を起動します。

    $ mlagents-learn config/ppo/3DBall.yaml --run-id=first3DBallRun_mine

    すると、以下のようにUnityからの接続を待つ待機状態となります。

     Version information:
      ml-agents: 1.0.0,
      ml-agents-envs: 1.0.0,
      Communicator API: 1.5.0,
      PyTorch: 2.2.1 training by pressing the Play button in the Unity Editor.

    この状態でUnityからプレイすると、自動的に学習モードに入ることができ、青い箱たちがひたすらボールの位置と自分の姿勢を計算・学習し続けます。最初はただボールを落とすだけですが、3,4分すると徐々にボールを落とさなくなっていく様子を見ることができます。

    はじめのうちは何も知らずにボールを落とす青い箱たち
    4分経過するとボールを落としてはいけないと理解する

    学習が終了すると Results ディレクトリにAIモデル(onnxファイル)が生成されます。このファイルをUnity内に移動し、Inspectorから割り当てます。

    これだけの操作で自作したAIモデルをエージェントに搭載することができます。

    学習内容を「落としたもの勝ち」に変更してみる

    今回のエージェントの学習内容は、「ボールを頭に乗せている間ずっと報酬を得られる」「ボールを落としてしまうとマイナスの報酬が得られる」という仕組みになっています。そこで実験としてこの関係を逆転させてみようと思います。

    Ball3DAgentの内容を以下のように変更しました。

    if ((ball.transform.position.y - gameObject.transform.position.y) -2f ||
        Mathf.Abs(ball.transform.position.x - gameObject.transform.position.x) > 3f ||
        Mathf.Abs(ball.transform.position.z - gameObject.transform.position.z) > 3f)
    {
        // 落としたらプラス報酬.
        SetReward(1f);
        //SetReward(-1f);
        EndEpisode();
    }
    else
    {
        // 頭に乗せている間マイナス報酬.
        SetReward(-0.1f);
        //SetReward(0.1f);
    }

    早速学習させ、生成されたAIモデルを読み込んだ結果以下のようになりました。

    頭の上にボールを乗せたくない

    みんな頭の上にボールを乗せたくないので、とにかく傾けて落としています。

    まとめ

    Unity SentisとML-Agentsについて調査し、ML-Agentsのサンプルプロジェクトを少し動作させてみました。その中で独自のAIモデルを生成できるようになり、報酬の与え方を変更するだけで異なる特徴を持つAIモデルが生成できました。ML-Agentsは学習の対象、報酬の与え方がすべてUnity C#で記述されているため、Unity使いならばすぐに独自のAIモデルを生成できるのではないでしょうか。

    今回はUnity Sentis自体に触れることなくAIモデルの動作が確認できてしまったので、いずれSentis単体での動作確認もやってみたいと思います。