0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CyberAgent 26th Fresh Engineer'sAdvent Calendar 2024

Day 24

【Unity 6】Sentis 2.xでONNXの拡張をしたい

Last updated at Posted at 2024-12-24

自己紹介

CyberAgentの26卒ゲームクライアントエンジニアとして内定を頂いています海道敦也(@kaidoatsuya)です。
最近はUnity Sentisを触っているものの、なかなかうまく動いてくれないですw

本記事について

この記事はCyberAgent 26th Fresh Engineer's Advent Calendar 2024の24日目です。

本アドベントカレンダーは、サイバーエージェント26卒の有志がお送りするものです。
あくまで有志での開催となります。楽しんでいってください!

Unity Senitsについて

Unity SentisとはUnity公式が提供するランタイムでAIモデルを動かすUnityパッケージです。
実態はテンソル(n次元の行列のようなもの)演算を行うライブラリです。

ONNXファイルに対応しており、Unity用に最適化するSentisファイルというものに変換できます。

ONNXについて

ONNXは汎用的なAIモデルを表現するフォーマットです。

ONNXを拡張する

Unity Sentigsでは画像を入力データとしてテンソル(Tensor)に変換するときにRGBを0-1の値として生成します。
一方、一部のモデルでは入力データがRGBの値が0-255である必要があります。

こういったときにONNXを拡張する、もしくはONNXなしでモデルを簡易的に作る必要があります。
公式ドキュメントには、出力を変更するサンプルコードが掲載されていますが、入力を変更するコードは存在しません。

今回は入力を変更するコードを基にSentisの演算プロセスの構築方法を見ていきます。

主要なクラス

モデルの拡張や作成に使うクラスは2つあります。FunctionalGraphFunctionalというクラスです。

FunctionalGraph

これは構造全体を構築するクラスです。
このクラスが最終的なアウトプットを出力してくれます。

Functional

これはどのような演算をするのか指定する静的クラスです。
掛け算だとか、キャストなどが静的なメソッドを呼び出して構造を作っていきます。

実際のコード

言葉では上手く理解できないと思うので、ソースコードです。

RGB0-1 to 0-255
public void CreateRGB255()
{
    // FunctionalGraphのインスタンスを生成
    var graph = new FunctionalGraph();

    // 1. インプットを追加(Shapeはモデルに合わせて作成)
    var input = graph.AddInput(DataType.Float, new DynamicTensorShape(1, -1, -1, 3));

    // 2. 255で乗算する
    var rgb255 = Functional.Mul(input, Functional.Constant(255.0f));

    // 3. Intにキャスト
    var castInt = Functional.Int(rgb255);

    // 4. モデルをコンパイル
    var newModel = graph.Compile(castInt);
    
    // モデルを保存(Sentisファイルとして出力されます。)
    ModelWriter.Save($"{Application.dataPath}/Onnx/ToRGB255.sentis", newModel);
    
    Debug.Log("Saved the new model.");
}

FunctionalGraphとFunctionalの静的なメソッドから来る引数の関係が極めて分かりにくいですが、このような形です。

実際の処理・解説

デバッカーを用いて、どのような処理となっているのか自分なりに考察しました。

  1. インプットを追加
    • inputは入力だけを持ちます
  2. 255で乗算する
    • rgb255は入力と乗算するという構造を持ちます
  3. Intにキャスト
    • castIntは入力と乗算とキャストという構造を持ちます
  4. モデルをコンパイル
    • castIntは今までの構造すべてを持っているため、これをコンパイルすればOK!

おまけ

ちなみに、DynamicTensorShapeという記述がありますが、これは動的な形状の入力です。
-1に値を設定したときはどのようなサイズの配列(厳密に言うと配列ではない?)がそこに入ってきてもOK!になります。

まとめ

公式ドキュメントにもあるものの、分かりにくいところを記事にしてみました!
もう少しFunctionalGraphFunctionalの関係性が分かりやすければ良いなぁと思うばかりです。

おわりに

CyberAgent 26th Fresh Engineer's Advent Calendar 2024もそろそろ終わりですね!
それでは、さようなら!

ほかの記事も見てね~

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?