MRが楽しい

MRやVRについて学習したことを書き残す

Unity AIのドキュメントを読む その49(モデルを作成する)

本日はUnityの技術調査枠です。
Unity AIのドキュメントを読みながら実際に操作を試して記事に残します。

Unity AI

以下のUnity AIのドキュメントを試しながら実行時のキャプチャをしていきます。
docs.unity3d.com

新しいモデルの作成

推論エンジンを使用すればONNXファイルなしで新しいランタイムモデルを作成できます。
例えば重みなしで一連のテンソル演算を実行したり、別のモデル形式から独自のモデルシリアル化を構築したりする場合などです。

Functional APIの使用

Functional APIを使用してモデルを作成するには以下の手順に従います。

  1. FunctionalGraph オブジェクトを作成します。
  2. データ型、形状、名前を指定してグラフに入力を追加します。これにより、各入力に対してFunctionalTensorオブジェクトが返されます。
  3. Functionalテンソルオブジェクトに一連のFunction APIメソッドを適用して必要な出力関数テンソルを作成します。
  4. 出力関数テンソルと名前を指定してAddOutputメソッドを呼び出してグラフに出力を追加します。
  5. Compileメソッドを使用してモデルをコンパイルします。

以下の例は2つのベクトルのドット積を計算する単純なモデルの作成を示しています。

using System;
using Unity.InferenceEngine;
using UnityEngine;

public class CreateNewModel : MonoBehaviour
{
    Model model;

    void Start()
    {
        // 関数グラフを作成します。
        FunctionalGraph graph = new FunctionalGraph();

        // データ型と形状を持つ2つの入力をグラフに追加します。
        // ドット積は同じサイズ「6」の2つのベクトルテンソルに対して演算を行います。
        FunctionalTensor x = graph.AddInput<float>(new TensorShape(6), "input_x");
        FunctionalTensor y = graph.AddInput<float>(new TensorShape(6), "input_y");

        // 演算子を使用して入力「FunctionalTensor」の要素ごとの積を計算します。
        FunctionalTensor prod = x * y;

        // 最初の軸に沿って積を合計し、合計次元を平坦化します。
        FunctionalTensor reduce = Functional.ReduceSum(prod, dim: 0, keepdim: false);

        graph.AddOutput(reduce, "output_reduce");
        graph.AddOutput(prod, "output_prod");

        // 「Compile」メソッドを使用してモデルを構築します。
        model = graph.Compile();
        
        // モデル情報をデバッグログに出力する
        Debug.Log("Model created with inputs and outputs.");
        Debug.Log("Model: " + model);
        Debug.Log("Inputs: " + string.Join(", ", model.inputs));
        Debug.Log("Outputs: " + string.Join(", ", model.outputs));
    }
}

コードをデバッグするにはToStringを使用して形状やデータ型などの情報を取得します。
その後、モデルを実行するためのエンジンを作成できます。

モデルの入力と出力

Compileメソッドを使用してモデルをコンパイルすると、結果のモデルにはAddInputとAddOutputで定義した入力と出力が含まれます。
入力と出力をグラフに追加する際に、名前を割り当てることができます。
名前を指定しない場合、推論エンジンはinput_0、input_1、output_0、output_1といった形式で番号順にデフォルトの名前を自動的に割り当てます。