Share via


Windows Machine Learning API を使用してモデルを Windows アプリにデプロイする

このチュートリアルの前のパートでは、モデルを ONNX 形式で構築し、エクスポートする方法を学習しました。 そのモデルができたので、Windows アプリケーションに組み込み、WinML API を呼び出してデバイス上でローカルに実行できるようになりました。

完了すると、画像分類子 WinML UWP アプリ (C#) を使用できるようになります。

サンプル アプリケーションについて

このモデルを使用して、食べ物の画像を分類できるアプリを作成します。 これを使用すると、ローカル デバイスから画像を選択し、前のパートで構築し、トレーニングしたローカルに格納された分類 ONNX モデルを使用して画像を処理できます。 返されたタグは画像の横に表示され、分類の信頼確率も表示されます。

これまでこのチュートリアルを実行している場合は、アプリ開発に必要な前提条件が既に整っているはずです。 復習が必要な方は、このチュートリアルの最初のパートを参照してください。

Note

完成したサンプル コードをダウンロードしたい場合は、ソリューション ファイルを複製してください。 リポジトリを複製し、このサンプルに移動して、Visual Studio で ImageClassifierAppUWP.sln ファイルを開きます。 これで、[アプリケーションの起動] (#アプリケーションの起動) の手順にスキップすることができます。

WinML UWP を作成する (C#)

ここでは、アプリと WinML のコードを一から作成する方法について説明します。 学習内容は次のとおりです。

  • 機械学習モデルを読み込みます。
  • 必要な形式の画像を読み込む。
  • モデルの入力と出力をバインドします。
  • モデルを評価し、意味のある結果を表示します。

また、画像分類子をテストできるように、基本的な XAML を使用して簡単な GUI を作成する。

アプリを作成する

  1. Visual Studio を開き、create a new project を選択します。

Create a new Visual Studio project

  1. 検索バーに「UWP」と入力し、[Blank APP (Universal Windows)] を選択します。 これで、事前に定義されたコントロールやレイアウトがない単一ページのユニバーサル Windows プラットフォーム (UWP) アプリ用の新しい C# プロジェクトが開きます。 [Next] を選択して、プロジェクトの構成ウィンドウを開きます。

Create a new UWP app

  1. 構成ウィンドウで:
  • プロジェクトの名前を選択します。 ここでは、ImageClassifierAppUWP を使用します。
  • プロジェクトの場所を選択します。
  • VS 2019 を使用している場合は、[Place solution and project in the same directory] をオフにします。
  • VS 2017 を使用している場合は、[Create directory for solution] をオンにします。

[create] を選択してプロジェクトを作成します。 最小ターゲット バージョン ウィンドウがポップアップ表示される場合があります。 最小バージョンは必ず Windows 10 ビルド 17763 以降に設定してください。

WinML アプリを使用してアプリを作成し、モデルを展開するには、以下が必要です。

  1. プロジェクトが作成されたら、プロジェクト フォルダーに移動し、assets フォルダー [….\ImageClassifierAppUWP\Assets] を開き、この場所にモデルをコピーします。

  2. モデル名を model.onnx から classifier.onnx に変更します。 こうすることで少しわかりやすくなり、チュートリアルの形式に合ったものになります。

モデルを探索する

モデル ファイルの構造を理解しましょう。

  1. Netron を使用して、classifier.onnx モデル ファイルを開きます。

  2. Data を選択してモデルのプロパティを開きます。

Model properties

ご覧のように、このモデルには入力として 32 ビットのテンソル (多次元配列) 浮動小数点型オブジェクトが必要であり、2 つの出力が返されます。classLabel という名前の 1 つ目は文字列のテンソルであり、loss という名前の 2 つ目はラベル付けされた各分類の確率を示す文字列から浮動小数点数へのマップのシーケンスです。 Windows アプリでモデルの出力を表示するには、この情報が必要になります。

プロジェクトのソリューションを調べる

プロジェクトのソリューションを調べてみましょう。

Visual Studio によって、ソリューション エクスプローラー内にいくつかの cs-code ファイルが自動的に作成されました。 MainPage.xaml には GUI の XAML コード、MainPage.xaml.cs にはアプリケーションのコードが含まれています。 UWP アプリを作成したことがあるなら、これらのファイルはとても見慣れたものでしょう。

アプリケーションの GUI を作成する

まず、アプリ用にシンプルな GUI を作成しましょう。

  1. MainPage.xaml ファイルをダブルクリックします。 この空のアプリでは、アプリの GUI 用の XAML テンプレートは空なので、UI 機能を追加する必要があります。

  2. 次のコードを MainPage.xaml の本体に追加します。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <StackPanel Margin="1,0,-1,0">
            <TextBlock x:Name="Menu" 
                       FontWeight="Bold" 
                       TextWrapping="Wrap"
                       Margin="10,0,0,0"
                       Text="Image Classification"/>
            <TextBlock Name="space" />
            <Button Name="recognizeButton"
                    Content="Pick Image"
                    Click="OpenFileButton_Click" 
                    Width="110"
                    Height="40"
                    IsEnabled="True" 
                    HorizontalAlignment="Left"/>
            <TextBlock Name="space3" />
            <Button Name="Output"
                    Content="Result is:"
                    Width="110"
                    Height="40"
                    IsEnabled="True" 
                    HorizontalAlignment="Left" 
                    VerticalAlignment="Top">
            </Button>
            <!--Display the Result-->
            <TextBlock Name="displayOutput" 
                       FontWeight="Bold" 
                       TextWrapping="Wrap"
                       Margin="30,0,0,0"
                       Text="" Width="1471" />
            <Button Name="ProbabilityResult"
                    Content="Probability is:"
                    Width="110"
                    Height="40"
                    IsEnabled="True" 
                    HorizontalAlignment="Left"/>
            <!--Display the Result-->
            <TextBlock Name="displayProbability" 
                       FontWeight="Bold" 
                       TextWrapping="Wrap"
                       Margin="30,0,0,0"
                       Text="" Width="1471" />
            <TextBlock Name="space2" />
            <!--Image preview -->
            <Image Name="UIPreviewImage" Stretch="Uniform" MaxWidth="300" MaxHeight="300"/>
        </StackPanel>
    </Grid>

Windows Machine Learning コード ジェネレーター

Windows Machine Learning コード ジェネレーター (mlgen) は、UWP アプリ上で WinML API を使い始めるときに役立つ Visual Studio 拡張機能です。 トレーニング済みの ONNX ファイルを UWP プロジェクトに追加すると、テンプレート コードが生成されます。

Windows Machine Learning のコード ジェネレーター mlgen により、Windows ML API を呼び出すラッパー クラスを備えたインターフェイス (C#、C++/WinRT、C++/CX 用) が自動的に作成されます。 そのため、プロジェクト内のモデルの読み込み、バインド、評価を簡単に行うことができます。 このチュートリアルでは、こうした多数の関数を自動的に処理するために使用します。

コード ジェネレーターは、Visual Studio 2017 以降で使用できます。 Windows 10 バージョン 1903 以降では、mlgen が Windows 10 SDK に含まれなくなったため、拡張機能をダウンロードしてインストールする必要があることに注意してください。 最初からこのチュートリアルを実行している場合は済んでいますが、そうでない場合は VS 2019 用または VS 2017 用にダウンロードしてください。

Note

mlgen の詳細については、mlgen のドキュメントを参照してください。

  1. まだの場合は、mlgen をインストールします。

  2. Visual Studio のソリューション エクスプローラーで Assets フォルダーを右クリックし、[Add > Existing Item] を選択します。

  3. ImageClassifierAppUWP [….\ImageClassifierAppUWP\Assets] 内の assets フォルダーに移動し、そこにコピーした ONNX モデルを探し、[add] を選択します。

  4. VS のソリューション エクスプローラーで assets フォルダーに ONNX モデル (名前: "classifier") を追加した後、プロジェクトには 2 つの新しいファイルができているはずです。

  • classifier.onnx - これは ONNX 形式のモデルです。
  • classifier.cs - 自動生成された WinML コード ファイルです。

Project structure with ONNX model added

  1. アプリケーションをコンパイルするときにモデルが確実に構築されるように、classifier.onnx ファイルを選択し、[Properties] を選択します。 [Build Action] では、[Content] を選択します。

それでは、classifier.cs ファイルに新しく生成されたコードを見てみましょう。

生成されたコードには、3 つのクラスが含まれています。

  • classifierModel: このクラスには、モデルのインスタンス化とモデルの評価のための 2 つのメソッドが含まれています。 これを使用すると、機械学習モデルの表現を作成し、システムの既定のデバイスでセッションを作成し、特定の入力と出力をモデルにバインドして、モデルを非同期に評価することができます。
  • classifierInput: このクラスを使用すると、モデルが想定する入力の型を初期化することができます。 モデルの入力は、入力データに対するモデルの要件によって変わります。 この例では、モデルに渡すために使用される画像のプロパティを記述するクラスである ImageFeatureValue が入力として想定されています。
  • classifierOutput: このクラスを使用すると、モデルによる出力の型を初期化することができます。 モデルの出力は、モデルによってどのように定義されているかによって変わります。 この例では、出力は loss という文字列型と TensorFloat (Float32) 型のマップ (ディクショナリ) のシーケンスになります。

これらのクラスを使って、プロジェクトでモデルを読み込み、バインドし、評価していきます。

モデルと入力を読み込む

モデルを読み込む

  1. MainPage.xaml.cs コード ファイルをダブルクリックし、アプリケーション コードを開きます。

  2. "using" ステートメントを次のように置き換えて、必要なすべての API にアクセスできるようにします。

// Specify all the using statements which give us the access to all the APIs that you'll need
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Graphics.Imaging;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
  1. MainPage クラス内の using ステートメントの後に、名前空間 ImageClassifierAppUWP の下に次の変数宣言を追加します。
        // All the required variable declaration
        private classifierModel modelGen;
        private classifierInput input = new classifierModelInput();
        private classifierOutput output;
        private StorageFile selectedStorageFile;
        private string result = "";
        private float resultProbability = 0;

結果は次のようになります。

// Specify all the using statements which give us the access to all the APIs that we'll need
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Graphics.Imaging;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace ImageClassifierAppUWP
{
    public sealed partial class MainPage : Page
    {
        // All the required fields declaration
        private classifierModel modelGen;
        private classifierInput input = new classifierInput();
        private classifierOutput output;
        private StorageFile selectedStorageFile;
        private string result = "";
        private float resultProbability = 0;

次は LoadModel メソッドを実装します。 このメソッドを使用すると、ONNX モデルにアクセスし、それをメモリに格納することができます。 次に、CreateFromStreamAsync メソッドを使用して、モデルを LearningModel オブジェクトとしてインスタンス化します。 LearningModel クラスは、トレーニング済みの機械学習モデルを表します。 インスタンス化された LearningModel は、Windows ML との対話に使用する最初のオブジェクトになります。

モデルを読み込むために、LearningModel クラスのいくつかの静的メソッドを使用することができます。 この例では、CreateFromStreamAsync メソッドを使用します。

CreateFromStreamAsync メソッドは mlgen で自動的に作成されているので、このメソッドを実装する必要はありません。 mlgen で生成された classifier.cs ファイルをダブルクリックすると、このメソッドを確認することができます。

LearningModel クラスの詳細については、LearningModel クラスのドキュメントを参照してください。 モデルを読み込むその他の方法については、モデルの読み込みに関するドキュメントを参照してください。

  1. MainPage クラス内の MainPage.xaml.cs コード ファイルに loadModel メソッドを追加します。
        private async Task loadModel()
        {
            // Get an access the ONNX model and save it in memory.
            StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/classifier.onnx"));
            // Instantiate the model. 
            modelGen = await classifierModel.CreateFromStreamAsync(modelFile);
        }
  1. 次に、クラスのコンストラクターに新しいメソッドの呼び出しを追加します。
        // The main page to initialize and execute the model.
        public MainPage()
        {
            this.InitializeComponent();
            loadModel();
        }

結果は次のようになります。

        // The main page to initialize and execute the model.
        public MainPage()
        {
            this.InitializeComponent();
            loadModel();
        }

        // A method to load a machine learning model.
        private async Task loadModel()
        {
            // Get an access the ONNX model and save it in memory.  
            StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/classifier.onnx"));
            // Instantiate the model. 
            modelGen = await classifierModel.CreateFromStreamAsync(modelFile);
        }

画像を読み込む

  1. モデル実行のための 4 つのメソッド呼び出し (変換、バインドと評価、出力の抽出、結果の表示) のシーケンスを開始するために、クリック イベントを定義する必要があります。 MainPage クラス内の MainPage.xaml.cs コード ファイルに次のメソッドを追加します。
        // Waiting for a click event to select a file 
        private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
        {
            if (!await getImage())
            {
                return;
            }
            // After the click event happened and an input selected, begin the model execution. 
            // Bind the model input
            await imageBind();
            // Model evaluation
            await evaluate();
            // Extract the results
            extractResult();
            // Display the results  
            await displayResult();
        }
  1. 次は getImage() メソッドを実装します。 このメソッドにより、入力画像ファイルが選択され、メモリに保存されます。 MainPage クラス内の MainPage.xaml.cs コード ファイルに次のメソッドを追加します。
        // A method to select an input image file
        private async Task<bool> getImage()
        {
            try
            {
                // Trigger file picker to select an image file
                FileOpenPicker fileOpenPicker = new FileOpenPicker();
                fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                fileOpenPicker.FileTypeFilter.Add(".jpg");
                fileOpenPicker.FileTypeFilter.Add(".png");
                fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
                selectedStorageFile = await fileOpenPicker.PickSingleFileAsync();
                if (selectedStorageFile == null)
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

次に、ファイルの表現をビットマップ BGRA8 形式で取得するために、image Bind() メソッドを実装します。

  1. MainPage クラス内の MainPage.xaml.cs コード ファイルに convert() メソッドの実装を追加します。 convert メソッドにより、BGRA8 形式の入力ファイルの表現が得られます。
// A method to convert and bind the input image.  
        private async Task imageBind()
        {
            UIPreviewImage.Source = null;
            try
            {
                SoftwareBitmap softwareBitmap;
                using (IRandomAccessStream stream = await selectedStorageFile.OpenAsync(FileAccessMode.Read))
                {
                    // Create the decoder from the stream 
                    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
                    // Get the SoftwareBitmap representation of the file in BGRA8 format
                    softwareBitmap = await decoder.GetSoftwareBitmapAsync();
                    softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
                }
                // Display the image
                SoftwareBitmapSource imageSource = new SoftwareBitmapSource();
                await imageSource.SetBitmapAsync(softwareBitmap);
                UIPreviewImage.Source = imageSource;
                // Encapsulate the image within a VideoFrame to be bound and evaluated
                VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
                // bind the input image
                ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
                input.data = imageTensor;
            }
            catch (Exception e)
            {
            }
        }

このセクションで行った作業の結果は次のようになります。

        // Waiting for a click event to select a file 
        private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
        {
            if (!await getImage())
            {
                return;
            }
            // After the click event happened and an input selected, we begin the model execution. 
            // Bind the model input
            await imageBind();
            // Model evaluation
            await evaluate();
            // Extract the results
            extractResult();
            // Display the results  
            await displayResult();
        }

        // A method to select an input image file
        private async Task<bool> getImage()
        {
            try
            {
                // Trigger file picker to select an image file
                FileOpenPicker fileOpenPicker = new FileOpenPicker();
                fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                fileOpenPicker.FileTypeFilter.Add(".jpg");
                fileOpenPicker.FileTypeFilter.Add(".png");
                fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
                selectedStorageFile = await fileOpenPicker.PickSingleFileAsync();
                if (selectedStorageFile == null)
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        // A method to convert and bind the input image.  
        private async Task imageBind()
        {
            UIPreviewImage.Source = null;

            try
            {
                SoftwareBitmap softwareBitmap;
                using (IRandomAccessStream stream = await selectedStorageFile.OpenAsync(FileAccessMode.Read))
                {
                    // Create the decoder from the stream 
                    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

                    // Get the SoftwareBitmap representation of the file in BGRA8 format
                    softwareBitmap = await decoder.GetSoftwareBitmapAsync();
                    softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
                }
                // Display the image
                SoftwareBitmapSource imageSource = new SoftwareBitmapSource();
                await imageSource.SetBitmapAsync(softwareBitmap);
                UIPreviewImage.Source = imageSource;

                // Encapsulate the image within a VideoFrame to be bound and evaluated
                VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);

                // bind the input image
                ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
                input.data = imageTensor;
            }
            catch (Exception e)
            {
            }
        }

モデルのバインドと評価

次に、モデルに基づいてセッションを作成し、セッションからの入力と出力を結合し、モデルを評価します。

モデルをバインドするセッションを作成します。

セッションの作成には LearningModelSession クラスを使用します。 このクラスは、機械学習モデルを評価するために使用されます。また、モデルの実行と評価を行うデバイスにモデルがバインドされます。 セッションを作成する際にデバイスを選択して、マシンの特定のデバイス上でモデルを実行することができます。 既定のデバイスは CPU です。

Note

デバイスの選択方法の詳細については、セッションの作成に関するドキュメントを参照してください。

モデルの入力と出力をバインドする:

入力と出力をバインドするには、LearningModelBinding クラスを使用します。 機械学習モデルには、モデルとの間で情報をやり取りする入力および出力機能があります。 必要な機能は Window ML API でサポートされている必要があることに注意してください。 LearningModelBinding クラスは LearningModelSession に適用され、名前付きの入力機能と出力機能に値がバインドされます。

バインドの実装は mlgen によって自動的に生成されるので、これに対応する必要ありません。 バインドは LearningModelBinding クラスの定義済みメソッドを呼び出すことで実装されます。 この例では、Bind メソッドを使用して、名前付きの特徴の種類に値をバインドします。

現在、Windows ML は、テンソル (多次元配列)、シーケンス (値のベクトル)、マップ (情報の値のペア)、画像 (特定の形式) など、ONNX の特徴の種類をすべてサポートしています。 Windows ML では、すべての画像がテンソル形式で表現されます。 テンソル化は、イメージをテンソルに変換するプロセスであり、バインド中に発生します。

幸いなことに、テンソル化変換の面倒を見る必要はありません。 前のパートで使用した ImageFeatureValue メソッドによって変換とテンソル化の両方が実行されるので、モデルに必要な画像形式と一致した画像になります。

Note

LearningModel をバインドする方法と、WinML がサポートする機能の種類については、モデルのバインドに関するドキュメントを参照してください。

モデルを評価する:

セッションを作成してモデルをバインドし、バインドされた値をモデルの入力と出力に設定すると、モデルの入力を評価して予測値を取得できるようになります。 モデル実行を行うには、LearningModelSession に対して定義済みの evaluate メソッドのいずれかを呼び出す必要があります。 この例では EvaluateAsync メソッドを使用します。

CreateFromStreamAsync と同様に、EvaluateAsync メソッドも WinML コード ジェネレーターによって自動生成されるので、このメソッドを実装する必要はありません。 このメソッドは classifier.cs ファイルで確認できます。

EvaluateAsync メソッドを使用すると、既にバインドにバインドされている特徴量の値を使用し、機械学習モデルを非同期的に評価することができます。 また、LearningModelSession を使用してセッションを作成し、LearningModelBinding を使用して入力と出力をバインドし、モデルの評価を実行し、LearningModelEvaluationResult クラスを使用してモデルの出力特徴量を取得することができます。

Note

モデルを実行するための他の評価メソッドについては、LearningModelSession クラスのドキュメントを参照して、LearningModelSession にどのようなメソッドを実装できるかを確認してください。

  1. MainPage クラス内の MainPage.xaml.cs コード ファイルに次のメソッドを追加し、セッションの作成、モデルのバインドと評価を行います。
        // A method to evaluate the model
        private async Task evaluate()
        {
            output = await modelGen.EvaluateAsync(input);
        }

結果の抽出と表示

次に、モデルの出力を抽出し、正しい結果を表示する必要があります。 そのために、extractResultdisplayResult のメソッドを実装します。

前述のように、このモデルによって 2 つの出力が返されます。classLabel という名前の 1 つ目は文字列のテンソルです。loss という名前の 2 つ目は文字列から浮動小数点数へのマップのシーケンスであり、ラベル付けされた各分類の確率を表しています。 つまり、結果と確率を正しく表示するために必要なのは、loss の出力から出力を抽出することです。 正しい結果を返すには、最も高い確率を見つける必要があります。

  1. MainPage クラス内の MainPage.xaml.cs コード ファイルに extractResult メソッドを追加します。
        private void extractResult()
        {
        // A method to extract output (result and a probability) from the "loss" output of the model 
            var collection = output.loss;
            float maxProbability = 0;
            string keyOfMax = "";

            foreach (var dictionary in collection)
            {
                foreach (var key in dictionary.Keys)
                {
                    if (dictionary[key] > maxProbability)
                    {
                        maxProbability = dictionary[key];
                        keyOfMax = key;
                    }
                }
            }
            result = keyOfMax;
            resultProbability = maxProbability;
        }
  1. MainPage クラス内の MainPage.xaml.cs コード ファイルに displayResult メソッドを追加します。
        // A method to display the results
        private async Task displayResult()
        {
            displayOutput.Text = result.ToString();
            displayProbability.Text = resultProbability.ToString();
        }

このアプリの WinML コードのバインドと実行結果の抽出と表示の部分の結果は次のようになります。

        // A method to evaluate the model
        private async Task evaluate()
        {
            output = await modelGen.EvaluateAsync(input);
        }

        // A method to extract output (string and a probability) from the "loss" output of the model 
        private void extractResult()
        {
            var collection = output.loss;
            float maxProbability = 0;
            string keyOfMax = "";

            foreach (var dictionary in collection)
            {
                foreach (var key in dictionary.Keys)
                {
                    if (dictionary[key] > maxProbability)
                    {
                        maxProbability = dictionary[key];
                        keyOfMax = key;
                    }
                }
            }
            result = keyOfMax;
            resultProbability = maxProbability;
        }

        // A method to display the results
        private async Task displayResult()
        {
            displayOutput.Text = result.ToString();
            displayProbability.Text = resultProbability.ToString();
        }

完了です! 分類モデルをテストするための基本的な GUI を備えた Windows Machine Learning アプリを作成することができました。 次の手順は、アプリケーションを起動して、Windows デバイス上でローカルに実行することです。

アプリケーションを起動します

アプリケーション インターフェイスを完成させ、モデルを追加し、WinML コードを生成したら、アプリケーションをテストすることができます。 上部のツール バーのドロップダウン メニューが Debug に設定されていることを確認します。 デバイスが 64 ビットの場合は Solution Platformx64 に、32 ビットの場合は x86 に変更して、ローカル マシン上でプロジェクトを実行します。

このアプリをテストするために、次のフルーツの画像を使用します。 画像の内容がアプリによってどのように分類されるかを見てみましょう。

Example fruit image

  1. アプリをテストするために、この画像をローカル デバイスに保存します。 必要に応じて、画像形式を jpg に変更します。 また、ローカル デバイスから適切な形式 (.jpg、.png、.bmp、.gif 形式) の他の関連する画像を追加することもできます。

  2. プロジェクトを実行するには、ツール バーの [Start Debugging] ボタンを選択するか、F5 キーを押します。

  3. アプリケーションが起動したら、[Pick Image] を選択し、ローカル デバイスから画像を選択します。

Pick image dialog

結果はすぐに画面に表示されます。 ご覧のとおり、WinML アプリは 99.9% の信頼度で、画像をフルーツと野菜に分類することに成功しました。

Successful image classification

まとめ

これで、モデルの作成から実行まで、最初の Windows Machine Learning アプリが完成しました。

その他のリソース

このチュートリアルで説明しているトピックについて詳しくは、次のリソースを参照してください。