C#でのResNet50v2による画像認識
C#でのResNet50v2による画像認識
Section titled “C#でのResNet50v2による画像認識”このサンプルでは、Onnx Runtime C# APIを使用して、事前トレーニング済みのResNet50 v2 ONNXモデルを実行する方法を順を追って説明します。
このサンプルのソースコードはこちらで入手できます。
このサンプルを実行するには、次のものが必要です。
- お使いのOS(Mac、Windows、またはLinux)に.NET Core 3.1以上をインストールします。
- ResNet50 v2 ONNXモデルをローカルシステムにダウンロードします。
- モデルをテストするためにこの犬の写真をダウンロードします。お好きな画像を使用することもできます。
始めましょう
Section titled “始めましょう”これで準備が整いましたので、画像上でモデルを実行するためのコードの追加を開始できます。簡単にするために、プログラムのmainメソッドでこれを行います。
パスの読み取り
Section titled “パスの読み取り”まず、プログラムの引数を介して、モデルへのパスとテストしたい画像へのパスを読み取ります。
string modelFilePath = args[0];string imageFilePath = args[1];画像の読み取り
Section titled “画像の読み取り”次に、クロスプラットフォームの画像ライブラリImageSharpを使用して画像を読み取ります。
using Image<Rgb24> image = Image.Load<Rgb24>(imageFilePath, out IImageFormat format);後のステップで画像を効率的に前処理できるように、特にRgb24型を読み取っていることに注意してください。
画像のリサイズ
Section titled “画像のリサイズ”次に、モデルが期待する適切なサイズ(224ピクセル×224ピクセル)に画像をリサイズします。
using Stream imageStream = new MemoryStream();image.Mutate(x =>{ x.Resize(new ResizeOptions { Size = new Size(224, 224), Mode = ResizeMode.Crop });});image.Save(imageStream, format);アスペクト比を維持するために、中央クロップリサイズを行っていることに注意してください。
画像の前処理
Section titled “画像の前処理”次に、モデルの要件に従って画像を前処理します。
// 画像データを入力するために多次元アクセスにDenseTensorを使用しますvar mean = new[] { 0.485f, 0.456f, 0.406f };var stddev = new[] { 0.229f, 0.224f, 0.225f };DenseTensor<float> processedImage = new(new[] { 1, 3, 224, 224 });image.ProcessPixelRows(accessor =>{ for (int y = 0; y < accessor.Height; y++) { Span<Rgb24> pixelSpan = accessor.GetRowSpan(y); for (int x = 0; x < accessor.Width; x++) { processedImage[0, 0, y, x] = ((pixelSpan[x].R / 255f) - mean[0]) / stddev[0]; processedImage[0, 1, y, x] = ((pixelSpan[x].G / 255f) - mean[1]) / stddev[1]; processedImage[0, 2, y, x] = ((pixelSpan[x].B / 255f) - mean[2]) / stddev[2]; } }});ここでは、必要なサイズ(バッチサイズ、チャネル、高さ、幅)のテンソルを作成し、ピクセル値にアクセスして前処理し、最後に適切なインデックスでテンソルに割り当てています。
次に、モデルへの入力を作成します。
// テンソルバッファをピン留めし、// DenseTensorバッファを直接利用するネイティブテンソルを持つOrtValueを作成します。// これにより、OnnxRuntime内での余分なデータコピーが回避されます。// ortValueの破棄時にピン留めが解除されますusing var inputOrtValue = OrtValue.CreateTensorValueFromMemory(OrtMemoryInfo.DefaultInstance, processedImage.Buffer, new long[] { 1, 3, 224, 224 });
var inputs = new Dictionary<string, OrtValue>{ { "data", inputOrtValue }}ONNXモデルの入力ノード名を確認するには、Netronを使用してモデルを視覚化し、入力/出力名を確認できます。この場合、このモデルの入力ノード名はdataです。
次に、推論セッションを作成し、それに入力を通します。
using var session = new InferenceSession(modelFilePath);using var runOptions = new RunOptions();using IDisposableReadOnlyCollection<OrtValue> results = session.Run(runOptions, inputs, session.OutputNames);出力の後処理
Section titled “出力の後処理”次に、モデル自体では処理されないため、softmaxベクトルを取得するために出力を後処理する必要があります。
// アルゴリズムを適用するためにのみ結果を配列にコピーします。// それ以外の場合、データはReadOnlySpan<T>またはSpan<T>を介してネイティブバッファから直接アクセスできますvar output = results[0].GetTensorDataAsSpan<float>().ToArray();float sum = output.Sum(x => (float)Math.Exp(x));IEnumerable<float> softmax = output.Select(x => (float)Math.Exp(x) / sum);他のモデルでは、出力の前にSoftmaxノードを適用する場合があり、その場合はこのステップは不要です。繰り返しになりますが、Netronを使用してモデルの出力を確認できます。
上位10件の抽出
Section titled “上位10件の抽出”次に、上位10件のクラス予測を抽出します。
IEnumerable<Prediction> top10 = softmax.Select((x, i) => new Prediction { Label = LabelMap.Labels[i], Confidence = x }) .OrderByDescending(x => x.Confidence) .Take(10);次に、上位10件の結果をコンソールに出力します。
Console.WriteLine("Top 10 predictions for ResNet50 v2...");Console.WriteLine("--------------------------------------------------------------");foreach (var t in top10){ Console.WriteLine($"Label: {t.Label}, Confidence: {t.Confidence}");}プログラムの実行
Section titled “プログラムの実行”プログラムが作成されたので、次のコマンドで実行できます。
dotnet run [path-to-model] [path-to-image]例:
dotnet run ~/Downloads/resnet50-v2-7.onnx ~/Downloads/dog.jpegこれを次の画像で実行すると:

次の出力が得られます。
Top 10 predictions for ResNet50 v2...--------------------------------------------------------------Label: Golden Retriever, Confidence: 0.9212826Label: Kuvasz, Confidence: 0.026514154Label: Clumber Spaniel, Confidence: 0.012455719Label: Labrador Retriever, Confidence: 0.004103844Label: Saluki, Confidence: 0.0033182495Label: Flat-Coated Retriever, Confidence: 0.0032045357Label: English Setter, Confidence: 0.002513516Label: Brittany, Confidence: 0.0023459378Label: Cocker Spaniels, Confidence: 0.0019343802Label: Sussex Spaniel, Confidence: 0.0019247672