Развертывание модели в приложении Windows с помощью API машинного обучения Windows

В предыдущей части этого руководства вы узнали, как создать и экспортировать модель в формате ONNX. Теперь, когда у вас есть эта модель, вы можете внедрить его в приложение Windows и запустить его локально на устройстве, вызвав API WinML.

После завершения работы у вас будет приложение WinML UWP с рабочим классификатором изображений (C#).

Сведения о примере приложения

С помощью нашей модели мы создадим приложение, которое может классифицировать изображения продуктов питания. Он предоставляет возможность выбрать изображение с вашего локального устройства и обработать его классификационной моделью ONNX, которая хранится локально и была создана и обучена в предыдущей части. Возвращаемые теги отображаются рядом с изображением, а также вероятность достоверности классификации.

Если вы выполнили это руководство до сих пор, у вас уже должны быть необходимые предварительные требования для разработки приложений. Если вам нужно освежить память, ознакомьтесь с первой частью этого руководства.

Замечание

Если вы предпочитаете скачать полный пример кода, можно клонировать файл решения. Клонируйте репозиторий, перейдите к этому образцу ImageClassifierAppUWP.sln , а затем откройте файл с помощью Visual Studio. Затем можно перейти к шагу [Запустить приложение](#Launch_the_application).

Создание WinML UWP (C#)

Ниже показано, как создать приложение и код WinML с нуля. Вы узнаете, как:

  • Загрузите модель машинного обучения.
  • Загрузите изображение в требуемом формате.
  • Свяжите входные и выходные данные модели.
  • Оцените модель и отобразите значимые результаты.

Вы также будете использовать базовый КОД XAML для создания простого графического интерфейса, чтобы протестировать классификатор изображений.

Создание приложения

  1. Откройте Visual Studio и выберите create a new project.

Создание проекта Visual Studio

  1. В строке поиска введите UWP и выберите Blank APP (Universal Windows). Откроется новый проект C# для одностраничного приложения универсальной платформы Windows (UWP), не имеющего предопределенных элементов управления или макета. Выберите Next , чтобы открыть окно конфигурации для проекта.

Создание нового приложения UWP

  1. В окне конфигурации:
  • Выберите имя проекта. Здесь мы используем ImageClassifierAppUWP.
  • Выберите расположение проекта.
  • Если вы используете VS 2019, убедитесь, что флажок Place solution and project in the same directory снят.
  • Если вы используете VS 2017, убедитесь, что Create directory for solution установлен флажок.

Нажмите, create чтобы создать проект. Окно минимально целевой версии может появиться. Убедитесь, что минимальная версия установлена на Windows 10 сборки 17763 или более поздней.

Чтобы создать приложение и развернуть модель с помощью приложения WinML, вам потребуется следующее:

  1. После создания проекта перейдите в папку проекта, откройте папку ресурсов [....\ImageClassifierAppUWP\Assets], а затем скопируйте модель в это расположение.

  2. Измените имя модели с model.onnx на classifier.onnx. Это делает ситуацию более понятной и приводит её в соответствие с форматом учебника.

Изучите вашу модель

Давайте познакомимся со структурой файла модели.

  1. classifier.onnx Откройте файл модели с помощью Netron.

  2. Нажмите, Data чтобы открыть свойства модели.

Свойства модели

Как видно, модель требует 32-битный тензор (многомерный массив) с плавающей запятой в качестве входных данных и возвращает два результата: первый, названный classLabel, является тензором строк, а второй, названный loss, представляет собой последовательность карт соответствий строки с числами с плавающей запятой, описывающих вероятность каждой классификации с метками. Эти сведения потребуются для успешного отображения выходных данных модели в приложении Windows.

Изучение решения проекта

Давайте рассмотрим решение проекта.

Visual Studio автоматически создал несколько файлов cs-code в обозревателе решений. MainPage.xaml содержит код XAML для графического интерфейса MainPage.xaml.cs и содержит код приложения. Если вы создали приложение UWP раньше, эти файлы должны быть очень знакомы с вами.

Создание графического интерфейса приложения

Сначала создадим простой графический интерфейс для приложения.

  1. Дважды щелкните файл MainPage.xaml. В пустом приложении шаблон XAML для графического интерфейса приложения пуст, поэтому нам потребуется добавить некоторые функции пользовательского интерфейса.

  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

Генератор кода Машинного обучения Windows или mlgen — это расширение Visual Studio, помогающее приступить к работе с API WinML в приложениях UWP. Он генерирует шаблонный код при добавлении обученного файла ONNX в проект UWP.

Генератор кода Windows Machine Learning mlgen создает интерфейс (для C#, C++/WinRT и C++/CX) с классами-оболочками, которые вызывают API машинного обучения Windows для вас. Это позволяет легко загружать, привязывать и оценивать модель в проекте. Мы будем использовать его в данном руководстве для обработки многих из этих функций для нас.

Генератор кода доступен для Visual Studio 2017 и более поздних версий. Помните, что в Windows 10 версии 1903 и более поздних версий mlgen больше не входит в пакет SDK для Windows 10, поэтому необходимо скачать и установить расширение. Если вы следовали этому руководству с самого начала, вы уже должны были это сделать; если нет, вам следует скачать для VS 2019 или VS 2017.

Замечание

Дополнительные сведения о mlgen см. в документации по mlgen

  1. Если вы еще не сделали этого, установите mlgen.

  2. Щелкните правой кнопкой мыши Assets папку в обозревателе решений в Visual Studio и выберите Add > Existing Item.

  3. Перейдите в папку assets внутри ImageClassifierAppUWP [….\ImageClassifierAppUWP\Assets], найдите модель ONNX, скопированную ранее, и выберите add.

  4. После добавления модели ONNX (имя: "классификатор") в папку ресурсов в обозревателе решений в VS проект должен иметь два новых файла:

  • classifier.onnx — это ваша модель в формате ONNX.
  • classifier.cs — автоматически созданный файл кода WinML.

Структура проекта с добавленной моделью ONNX

  1. Чтобы убедиться, что модель собирается, когда вы компилируете наше приложение, выберите файл classifier.onnx и выполните действие Properties. В Build Action выберите Content.

Теперь давайте рассмотрим только что созданный код в файле classifier.cs.

Созданный код включает три класса:

  • classifierModel: этот класс включает два метода для создания экземпляра модели и оценки модели. Это поможет нам создать представление модели машинного обучения, создать сеанс на устройстве по умолчанию системы, привязать определенные входные и выходные данные к модели и асинхронно оценить модель.
  • classifierInput: этот класс инициализирует типы входных данных, которые ожидает модель. Входные данные модели зависят от требований модели для входных данных. В нашем случае входные данные ожидают ImageFeatureValue, класс, описывающий свойства изображения, используемого для передачи в модель.
  • classifierOutput: этот класс инициализирует типы, которые будет выводить модель. Выходные данные модели зависят от того, как она определена моделью. В нашем случае выходные данные будут последовательностью карт (словарей) типа String и TensorFloat (Float32) с именем loss.

Теперь эти классы будут использоваться для загрузки, привязки и оценки модели в нашем проекте.

Загрузка модели и входных данных

Загрузка модели

  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. Добавьте следующие объявления переменных после инструкций using внутри класса MainPage, в пространстве имен 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, поэтому вам не нужно реализовать этот метод. Этот метод можно просмотреть, дважды щелкнув classifier.cs файл, созданный mlgen.

Дополнительные сведения о LearningModel классе см. в документации по классу LearningModel. Дополнительные сведения о дополнительных способах загрузки модели см. в документации по загрузке модели.

  1. Вставьте метод loadModel в ваш файл кода MainPage.xaml.cs, находящийся внутри класса MainPage.
        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. Необходимо определить событие щелчка, чтобы инициировать последовательность четырех вызовов метода для выполнения модели— преобразования, привязки и оценки, извлечения выходных данных и отображения результатов. Добавьте следующий метод в MainPage.xaml.cs файл кода внутри MainPage класса.
        // 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.xaml.cs файл кода внутри MainPage класса.
        // 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;
        }

Теперь вы реализуете метод Bind(), чтобы получить представление файла в формате растрового изображения BGRA8.

  1. Добавьте реализацию метода convert() в ваш файл кода MainPage.xaml.cs внутри класса MainPage. Метод 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 класс. Этот класс используется для оценки моделей машинного обучения и привязывает модель к устройству, который затем запускает и оценивает модель. Вы можете выбрать устройство при создании сеанса для выполнения модели на определенном устройстве компьютера. Устройство по умолчанию — это ЦП.

Замечание

Дополнительные сведения о выборе устройства см. в документации по созданию сеанса .

Привязка входных и выходных данных модели:

Для привязки входных и выходных данных используется LearningModelBinding класс. Модель машинного обучения имеет функции ввода и вывода, которые передают информацию в модель и из нее. Помните, что необходимые функции должны поддерживаться API Windows ML. Класс LearningModelBinding применяется к привязке значений LearningModelSession к именованным функциям ввода и вывода.

Реализация привязки автоматически генерируется mlgen, поэтому вам не нужно об этом беспокоиться. Привязка реализуется путем вызова предопределенных методов LearningModelBinding класса. В нашем случае он использует Bind метод для привязки значения к именованным типу признаков.

В настоящее время Windows ML поддерживает все типы объектов ONNX, такие как тензоры (многомерные массивы), последовательности (векторы значений), отображения (пары значений информации) и изображения (определенные форматы). Все изображения будут представлены в windows ML в тензорном формате. Tensorization — это процесс преобразования изображения в тензор и происходит во время привязки.

К счастью, вам не нужно заботиться о преобразовании тензоризации. Метод ImageFeatureValue , используемый в предыдущей части, отвечает за преобразование и тензоризацию, поэтому изображения соответствуют требуемому формату изображения модели.

Замечание

Чтобы узнать больше о том, как привязать LearningModel, и о типах функций, поддерживаемых WinML, пожалуйста, ознакомьтесь с документацией по привязке модели.

Оцените модель:

После создания сеанса для привязки модели и привязанных значений к входным и выходным данным модели можно оценить входные данные модели и получить его прогнозы. Чтобы выполнить выполнение модели, необходимо вызвать любой из предопределенных методов оценки в LearningModelSession. В нашем случае мы будем использовать метод EvaluateAsync.

CreateFromStreamAsyncАналогично тому, EvaluateAsync метод также был автоматически создан генератором кода WinML, поэтому вам не нужно реализовать этот метод. Этот метод можно просмотреть в classifier.cs файле.

Метод EvaluateAsync асинхронно оценивает модель машинного обучения с помощью значений признаков, уже привязанных в привязках. Он создаст сеанс с LearningModelSession, привязывает входные и выходные данные с LearningModelBinding, выполняет оценку модели и получает выходные функции модели с помощью LearningModelEvaluationResult класса.

Замечание

Чтобы узнать о других методах оценки для запуска модели, проверьте, какие методы можно реализовать в LearningModelSession, просмотрите документацию по классу LearningModelSession.

  1. Добавьте следующий метод в файл кода MainPage.xaml.cs внутри класса MainPage, чтобы создать сеанс, привязать модель и выполнить её оценку.
        // A method to evaluate the model
        private async Task evaluate()
        {
            output = await modelGen.EvaluateAsync(input);
        }

Извлечение и отображение результатов

Теперь необходимо извлечь выходные данные модели и отобразить правильные результаты. Вы сделаете это, реализовав метод extractResult и метод displayResult.

Как вы изучили ранее, модель возвращает два выходных данных: первый, именованный classLabel, это тензор строк, а второй, именованный loss, — это последовательность отображений строк в числа с плавающей запятой, которая описывает вероятность для каждой помеченной классификации. Таким образом, чтобы успешно отобразить результат и вероятность, необходимо извлечь выходные данные из выходных данных потери. Нам потребуется найти самую высокую вероятность возврата правильного результата.

  1. Добавьте метод extractResult в файл кода MainPage.xaml.cs внутри класса MainPage.
        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. Добавьте метод displayResult в файл кода MainPage.xaml.cs внутри класса MainPage.
        // 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();
        }

Вот и все! Вы успешно создали приложение машинного обучения Windows с базовым графическим интерфейсом для тестирования модели классификации. Следующим шагом является запуск приложения и его локальное запуск на устройстве Windows.

Запуск приложения

После завершения интерфейса приложения добавьте модель и создав код WinML, можно протестировать приложение. Убедитесь, что в раскрывающемся меню на верхней панели инструментов задано значение Debug. Измените Solution Platform на x64, чтобы запустить проект на локальном компьютере, если ваше устройство является 64-разрядным, или на x86, если оно 32-разрядное.

Чтобы протестировать наше приложение, вы будете использовать приведенный ниже образ фруктов. Давайте посмотрим, как наше приложение классифицирует содержимое изображения.

Пример изображения фруктов

  1. Сохраните этот образ на локальном устройстве, чтобы протестировать приложение. При необходимости измените формат изображения на jpg. Вы также можете добавить любое другое соответствующее изображение с локального устройства в подходящем формате — .jpg, .png, .bmpили .gif форматах.

  2. Чтобы запустить проект, нажмите Start Debugging кнопку на панели инструментов или нажмите клавишу F5.

  3. При запуске приложения нажмите Pick Image и выберите изображение на локальном устройстве.

Диалоговое окно выбора изображения

Результат появится на экране сразу. Как видно, наше приложение WinML успешно классифицирует изображение как фрукты или овощи, с рейтингом достоверности 99,9%.

Успешная классификация изображений

Сводка

Вы только что сделали свое первое приложение Машинного обучения Windows, начиная с создания модели до успешного выполнения.

Дополнительные ресурсы

Дополнительные сведения о разделах, упомянутых в этом руководстве, см. в следующих ресурсах: