ML.NETでONNX形式のモデルを扱えないかどうか調べていたところ以下の動画で解説されていました。
https://www.youtube.com/watch?v=lamnwHvjEV0
この動画で説明されていることでもあるのですが、少しまとめてみようと思います。
プロジェクトの作成
ここでは、プロジェクトはコンソールアプリ(.NET Core)で作成しています。
依存関係の追加
NuGetパッケージの管理から次のパッケージを探します。
- Microsoft.ML.OnnxRuntime
実は、はじめML .NETの方(Microsoft.ML)でOnnxの実行環境を探していたのですが、別のパッケージになるようでした。
プログラム
using Microsoft.ML.OnnxRuntime;
float[] input = new float[16 * 16]; // モデルの入力に合わせる var session = new InferenceSession("model.onnx"); Tensor<float> tensor = new DenseTensor<float>(input, session.InputMetadata.First().Value.Dimensions); var namedValues = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("0", tensor) }; var results = session.Run(namedValues); var resultValues = results.First().AsTensor<float>().ToArray(); int resultValue = Array.IndexOf(resultValues, resultValues.Max()); Console.WriteLine("value is {0}", resultValue);
ONNX形式のファイルの読み込み
一番初めのInferenceSessionの初期化の箇所で指定しています。各機械学習のライブラリで出力されたものを使用します。
var session = new InferenceSession("model.onnx");
モデルに入力する値と名前と形式を指定
この例では、入力はinputに入れています。1次元のfloat型の配列で作成して、ここからTensor
Tensor<float> tensor = new DenseTensor<float>(input, session.InputMetadata.First().Value.Dimensions);
ここで作成したテンソルをモデルのどの入力に指定するかどうかをNamedOnnxValueを使用して指定しています。ここで、入力名"0"が指定されていますが、これはONNXモデルを作成したときに指定されているものになりますので、ONNX形式の出力部分などを確認します(指定していないと"0"のようになっていました。)
モデルを実行と結果の取得
var results = session.Run(namedValues); var resultValues = results.First().AsTensor<float>().ToArray(); int resultValue = Array.IndexOf(resultValues, resultValues.Max());
session.Runを実行すると入力した値から結果を計算してくれます。そのあとは、出力された結果で一番大きい値を取り出し最終的な結果としています。