Freigeben über


Bereitstellen eines PyTorch-Datenanalysemodells in einer Windows-App mit der Windows ML-API

Im vorherigen Teil dieses Tutorials haben Sie gelernt, wie Sie ein Modell im ONNX-Format erstellen und exportieren. Nun zeigen wir Ihnen, wie Sie Ihr exportiertes Modell in eine Windows-Anwendung einbetten und lokal auf einem Gerät ausführen, indem Sie Windows ML-APIs aufrufen.

Wenn wir fertig sind, verfügen Sie über eine funktionierende Datenanalyse-App.

Infos zur Beispiel-App

In diesem Schritt des Tutorials erstellen Sie eine App, die tabellarische Daten von Schwertlilien analysieren kann. Die App ermöglicht Ihnen, die Excel-Datei mit den erforderlichen Eingabeinformationen hinzuzufügen oder die Eingabeparameter manuell einzugeben: Länge und Breite des Kelch- und Blütenblatts der Schwertlilie in cm. Diese Features werden von einem lokal gespeicherten ONNX-Modell im neuronalen Netz verarbeitet, das Sie im vorherigen Teil erstellt und trainiert haben. Basierend auf der Modellausgabe zeigt die App die richtige Schwertlilienart an.

Hier werden wir Sie durch diesen Prozess führen.

Hinweis

Wenn Sie das vordefinierte Codebeispiel verwenden möchten, können Sie die Projektmappendatei klonen. Klonen Sie das Repository, navigieren Sie zu diesem Beispiel, und öffnen Sie die Datei Iris Data Analysis.csproj mit Visual Studio. Wechseln Sie zum Teil Anwendung starten auf dieser Seite, um sie in Verwendung zu sehen.

Im Folgenden erfahren Sie, wie Sie Ihre App erstellen und Windows ML-Code hinzufügen.

Erstellen einer Windows ML-Desktop-App (C#)

Um eine funktionierende Windows ML-App erstellen zu können, müssen Sie folgende Schritte durchführen:

  • Laden eines Machine Learning-Modells.
  • Binden der Ein- und Ausgaben des Modells.
  • Auswerten des Modells und Anzeigen aussagekräftiger Ergebnisse.

Sie müssen auch eine einfache Benutzeroberfläche erstellen, um eine bessere Benutzererfahrung zu bieten.

Öffnen eines neuen Projekts in Visual Studio

  1. Los geht's. Öffnen Sie Visual Studio, und wählen Sie Create a new project aus.

Create new Visual Studio project

  1. Wählen Sie auf der Suchleiste C# als Sprache, Windows als Zielplattform und Dektop als Projekttyp aus. Wählen Sie NUnit Test Project (.NET Core) als Projekttyp und next aus, um ein Konfigurationsfenster für das Projekt zu öffnen.

Create new NUnit Test Project app

  1. Gehen Sie im Konfigurationsfenster folgendermaßen vor:
  • Geben Sie dem Projekt einen Namen. Hier nennen wir es Iris Data Analysis.
  • Wählen Sie den Speicherort Ihres Projekts aus.
  • Wenn Sie VS 2019 verwenden, stellen Sie sicher, dass Create directory for solution aktiviert ist.
  • Wenn Sie VS 2017 verwenden, stellen Sie sicher, dass Place solution and project in the same directory deaktiviert ist.

Drücken Sie create, um das Projekt zu erstellen. Möglicherweise wird das Fenster für die Mindestzielversion angezeigt. Stellen Sie sicher, dass Ihre Mindestversion auf Windows 10, Version 1809 (10.0; Build 17763) oder höher festgelegt ist.

  1. Navigieren Sie nach dem Erstellen des Projekts zum Projektordner, öffnen Sie den Ressourcenordner [….\DataClassifier\Assets], und kopieren Sie Ihre Datei Network.onnx an diesen Speicherort.

Untersuchen der Projektmappe

Sehen wir uns Ihre Projektmappe an.

Visual Studio automatisch mehrere cs-code-Dateien innerhalb des Projektmappen-Explorer erstellt. MainPage.xaml enthält den XAML-Code für Ihre Benutzeroberfläche und MainPage.xaml.cs den Anwendungscode. Wenn Sie schon einmal eine UWP-App erstellt haben, sollten Ihnen diese Dateien sehr vertraut sein.

Wir haben zwar unsere Datei Network.onnx zum Ordner „Assets“ hinzugefügt, aber wir müssen sie noch ordnungsgemäß diesem Projekt hinzufügen.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner „Assets“, und wählen Sie Add > Existing Item aus.
  2. Navigieren Sie in Iris Data Analysis [….\Iris Data Analysis \Assets] zum Ordner „Assets“. Wechseln Sie zum Network.onnx model, das Sie zuvor dorthin kopiert haben, und wählen Sie Add aus.
  3. Um sicherzustellen, dass Ihr Modell beim Kompilieren Ihrer Anwendung erstellt wird, klicken Sie mit der rechten Maustaste auf die Datei Network.onnx, und wählen Sie Properties aus. Legen Sie Build Action auf Content fest.

Sie müssen auch eine neue cs-code-Klassendatei erstellen, um zusätzlichen Code zum maschinellen Lernen aufzunehmen, der Klassen und Methoden enthält, die Windows ML-APIs aufrufen.

  1. Klicken Sie in Visual Studio mit der rechten Maustaste auf den Projektmappennamen, und wählen Sie add und new item aus. Wählen Sie im geöffneten Fenster Class aus, und vergeben Sie einen Namen. Hier verwenden wir IrisModel.cs. Unter Ihrem Projekt wird eine neue Klassendatei angezeigt.

Add a new class file to your VS project.

Erstellen von Machine Learning-Code

In diesem Schritt erstellen wir alle Klassen und Methoden, die die Windows Machine Learning-APIs aufrufen. Damit können Sie ein ONNX-Machine Learning-Modell in Ihrem Projekt laden, binden und bewerten.

  1. Doppelklicken Sie auf die Datei IrisModel.cs.

  2. Ersetzen Sie die using-Anweisungen durch Folgendes, um Zugriff auf alle benötigten APIs zu erhalten.

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Storage;

Initialisieren von Machine Learning-Klassen

Wir müssen IrisModel.cs mehrere Klassen hinzufügen, um Sie bei der Interaktion mit Windows Machine Learning-APIs zu unterstützen.

Um Zugriff auf das trainierte Machine Learning-Modell zu erhalten, verwenden wir die LearningModel-Klasse. Diese Klasse ist Teil des Namespace Windows.AI.MachineLearning und stellt ein trainiertes Machine Learning-Modell dar. Nach der Instanziierung ist LearningModel das Hauptobjekt für die Interaktion mit Windows ML.

Zum Bewerten des Lernmodells müssen Sie eine Bewertungssitzung erstellen. Hierzu verwenden Sie die LearningModelSession-Klasse. Diese Klasse wird verwendet, um Machine Learning-Modelle auszuwerten, und bindet das Modell an ein Gerät, das dann ausgeführt wird und das Modell auswertet. Wenn Sie eine Sitzung mit dieser API erstellen, können Sie auch ein Gerät auswählen, auf dem Ihr Modell ausgeführt werden soll (Standardeinstellung ist Ihre CPU).

Darüber hinaus müssen Sie die Bezeichnungen der Ausgabe Ihrer Machine Learning-Modelle angeben. Sie können diese Bezeichnungen später mit der vorhergesagten Ausgabe des Modells verbinden.

Hinweis

Weitere Informationen zu den Klassen LearningModel und LearningModelSession finden Sie in der Dokumentation zur LearningModel-Klasse und Dokumentation zur LearningModelSession-Klasse.

  1. Kopieren Sie den folgenden Code in die Datei IrisModel.cs.
class IrisModel
    {
        private LearningModel _learning_model;
        private LearningModelSession _session;
        private String[] _labels = { "Iris-setosa", "Iris-versicolor", "Iris-virginica"};

Laden des Modells

Als Nächstes müssen Sie das Machine Learning-Modell laden und eine Sitzung erstellen, wozu Sie die gerade definierten Klassen nutzen. Zum Laden des Modells verwenden Sie mehrere statische Methoden der LearningModel-Klasse. In diesem Fall verwenden wir LoadFromStorageFileAsync, mit der Sie ein ONNX-Modell asynchron aus ISorageFile laden können.

Hinweis

Weitere Informationen zu weiteren Möglichkeiten zum Laden des Modells finden Sie in der Dokumentation zum Laden eines Modells.

  1. Kopieren Sie den folgenden Code in die Datei IrisModel.cs.
public async Task Initialize()
{
    // Load and create the model and session
    var modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets//Network.onnx"));
    _learning_model = await LearningModel.LoadFromStorageFileAsync(modelFile);
    _session = new LearningModelSession(_learning_model);
}

Definieren des Modelleingabetensors

Nun definieren wir die richtige Eingabe basierend auf Ihren Modellanforderungen. Das Netzmodell, das Sie im vorherigen Teil erstellt haben, hat vier Eingabewerte. Jeder Eingabewert steht für die möglichen Größen von vier Features von Schwertlilien: Kelchblattlänge in cm, Kelchblattbreite in cm, Blütenblattlänge in cm und Blütenblattbreite in cm. Auf Grundlage dieser Eingaben gibt das Modell die Schwertlilienart zurück, die am besten zu diesen Parametern passt. Sie müssen die Größe der Eingabewerte auf die gültigen logischen Werte beschränken. In diesem Tutorial verwenden wir die folgenden Werte:

  • Kelchblattlänge: 1 cm bis 100 cm
  • Kelchblattbreite: 1 cm bis 8 cm
  • Blütenblattlänge: 0,5 cm bis 10 cm
  • Blütenblattbreit: 0,1 cm bis 5 cm
  1. Kopieren Sie den folgenden Code in die Datei IrisModel.cs.
private float _sepal_length = 1.0f;
public float Sepal_Length
{
    get
    {
        return _sepal_length;
    }
    set
    {
        // validate range [1,10]
        if (value >= 1 && value <= 10)
        {
            _sepal_length = value;
        }
    }
}

private float _sepal_width = 1.0f;
public float Sepal_Width
{
    get
    {
        return _sepal_width;
    }
    set
    {
        // validate range [1, 8]
        if (value >= 1 && value <= 8)
        {
            _sepal_width = value;
        }
    }
}

private float _petal_length = 0.5f;
public float Petal_Length
{
    get
    {
        return _petal_length;
    }
    set
    {
        // validate range [0.5, 10]
        if (value >= 0.5 && value <= 10)
        {
            _petal_length = value;
        }
    }
}

private float _petal_width = 0.1f;
public float Petal_Width
{
    get
    {
        return _petal_width;
    }
    set
    {
        // validate range [0.1, 5]
        if (value >= 0.1 && value <= 5)
        {
            _petal_width = value;
        }
    }
}

Windows ML-APIs akzeptieren Eingabewerte der vier beschreibenden Klassen, die von ONNX-Modellen unterstützt werden: Tensoren, Sequenzen, Zuordnungen und Bilder. In diesem Fall benötigt das Modell ein 32-Bit-Tensor-Float-Objekt in Form von float32[Batchgröße,4]. Da die Batchgröße 1 beträgt, ist die Form des Eingabetensors [1x4].

Um eine Tensoreingabe zu erstellen, verwenden Sie die TensorFloat-Klasse.

Die TensorFloat-Klasse ist Teil des Windows.AI.MachineLearning-Namespace und wird genutzt, um ein 32-Bit-Float-Tensorobjekt zu definieren: einen Tensor mit 32-Bit-Gleitkommawerten. Diese Klasse enthält mehrere nützliche Methoden zum Erstellen eines Tensors. In Ihrem Fall verwenden Sie die CreateFromArray-Methode, um eine Tensoreingabe in der für Ihr Modell benötigten Größe zu erstellen. Wir fügen diesen Aufruf innerhalb der Bewertungsmethode hinzu.

Binden und Auswerten des Modells

Nachdem Sie nun den Modelleingabetensor definiert sowie das trainierte Modell und die Sitzung instanziiert haben, ist es Zeit, eine Methode zum Binden und Bewerten des trainierten Machine Learning-Modells zu erstellen.

Diese Methode ist der wichtigste Teil einer Machine Learning-App. Sie umfasst die Tensorisierung der Eingabewerte und Bindung der Modelleingabe. Sie verwenden dieses Modell später in Ihrem Anwendungscode, um Ihr Modell zu bewerten.

Zum Binden von Eingabe und Ausgabe verwenden Sie die LearningModelBinding-Klasse. Ein Machine Learning-Modell verfügt über Eingabe-und Ausgabefunktionen, mit denen Informationen an das und aus dem Modell übergeben werden. Beachten Sie, dass erforderliche Features von den Window ML-APIs unterstützt werden müssen. Die LearningModelBinding-Klasse wird auf eine LearningModelSession angewendet, um Werte an benannte Eingabe- und Ausgabefeatures zu binden.

Die LearningModelBinding-Klasse bietet mehrere vordefinierte Methoden, mit denen Sie Werte an diese benannten Features binden können. Hier verwenden Sie die Bind-Methode, um Werte an Ihr Modell zu binden.

Um Ihr Modell zu bewerten und Ergebnisse daraus zu empfangen, rufen Sie die relevanten vordefinierten Methoden in LearningModelSession auf – in Ihrem Fall die Evaluate-Methode. Diese Methode stellt die Funktionalität zur Verfügung, die Sie benötigen, und bewertet das Machine Learning-Modell mithilfe der von der LearningModelBinding-Klasse bereitgestellten Featurewerte.

Hinweis

Weitere Informationen zu weiteren Auswertungsmethoden zum Ausführen des Modells finden Sie in der Dokumentation zur Klasse LearningModelSession, die zeigt, welche Methoden für die LearningModelSession implementiert werden können.

Extrahieren und Anzeigen der Ergebnisse

Das Modell gibt die vorhergesagten Werte im Tensorformat als Tensor-Float-Ausgabe zurück. Sie müssen nun die Modellausgabe extrahieren und die richtigen Ergebnisse anzeigen. Hierzu konvertieren Sie das Tensorformat in einen Vektor, indem Sie die Funktion GetAsVectorView() auf die Prädikatausgabe anwenden.

Das Modell gibt drei Wahrscheinlichkeitswerte zurück, die jeweils eine bestimmte Schwertlilienart darstellen. Sie müssen die Bezeichnung mit der höchsten Wahrscheinlichkeit zurückgeben.

  1. Kopieren Sie den folgenden Code in die Datei IrisModel.cs.
internal String Evaluate()
{
    // input tensor shape is [1x4]
    long[] shape = new long[2];
    shape[0] = 1;
    shape[1] = 4;

    // set up the input tensor
    float[] input_data = new float[4];
    input_data[0] = _sepal_length;
    input_data[1] = _sepal_width;
    input_data[2] = _petal_length;
    input_data[3] = _petal_width;
    TensorFloat tensor_float = TensorFloat.CreateFromArray(shape, input_data);

    // bind the tensor to "input"
    var binding = new LearningModelBinding(_session);
    binding.Bind("input", tensor_float);

    // evaluate
    var results = _session.Evaluate(binding, "");

    // get the results
    TensorFloat prediction = (TensorFloat)results.Outputs.First().Value;
    var prediction_data = prediction.GetAsVectorView();

    // find the highest predicted value
    int max_index = 0;
    float max_value = 0;
    for (int i = 0; i < prediction_data.Count; i++)
    {
        var val = prediction_data.ElementAt(i);
        if (val > max_value)
        {
            max_value = val;
            max_index = i;
        }
    }

    // return the label corresponding to the highest predicted value
    return _labels.ElementAt(max_index);
}

Sie haben nun den Machine Learning-Teil Ihres Codes abgeschlossen. Jetzt können Sie Ihr Modell problemlos in Ihre Windows-Anwendung integrieren. Im letzten Teil dieses Tutorials haben wir eine einfache Windows-Benutzeroberfläche und Code zum Testen des Modells mit den Methoden bereitgestellt, die Sie bereits erstellt haben.

Erstellen der Benutzeroberfläche der Anwendung

  1. Um App Code für eine Benutzeroberfläche für Ihre zu erstellen, doppelklicken Sie auf die Codedatei MainPage.xaml, und öffnen Sie eine vordefinierte Vorlage für Ihre Benutzeroberfläche.

  2. Kopieren Sie den folgenden Code, und fügen Sie ihn in MainPage.xaml unter der Zeile “Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" " Height="939"> ein.

    <Grid Margin="30,30,30,30">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="title" HorizontalAlignment="Left" Text="Data Analysis App - Windows ML" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="32" TextDecorations="Underline" FontWeight="Bold"/>
        <TextBlock x:Name="subtitle" HorizontalAlignment="Left" Text="Provide the input :" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" Grid.Row="1" FontWeight="Bold"/>
        <Grid Grid.Row="2">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="sepal_length" Text="sepal length in mm [range of 10 - 100]:" VerticalAlignment="Center"/>
            <TextBlock x:Name="sepal_width" Text="sepal width in mm [range of 10 - 80]:" VerticalAlignment="Center" Grid.Row="1"/>
            <TextBlock x:Name="petal_length" Text="petal length in mm [range of 5 - 100]:" VerticalAlignment="Center" Grid.Row="2"/>
            <TextBlock x:Name="petal_width" Text="sepal width in mm [range of 1 - 50]:" VerticalAlignment="Center" Grid.Row="3"/>

            <Slider x:Name="sepal_length_input" Minimum="10" Maximum="100" Orientation="Horizontal" Grid.Column="1" Width="200" ValueChanged="sepal_length_input_ValueChanged"/>
            <Slider x:Name="sepal_width_input" Minimum="10" Maximum="80" Orientation="Horizontal" Grid.Row="1" Grid.Column="1" Width="200" ValueChanged="sepal_width_input_ValueChanged"/>
            <Slider x:Name="petal_length_input" Minimum="5" Maximum="100" Orientation="Horizontal" Grid.Row="2" Grid.Column="1" Width="200" ValueChanged="petal_length_input_ValueChanged"/>
            <Slider x:Name="petal_width_input" Minimum="1" Maximum="50" Orientation="Horizontal" Grid.Row="3" Grid.Column="1" Width="200" ValueChanged="petal_width_input_ValueChanged"/>
        </Grid>
        <TextBlock x:Name="output" Text="Output:" FontSize="20" FontWeight="Bold" Grid.Row="3"/>
        <Grid Grid.Row="4">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="output_subtitle" Text="Based on the information provided, the Iris type is:"/>
            <TextBlock x:Name="model_output" Text="Model output" FontStyle="Italic"  Grid.Column="1" Margin="10,0,0,0"/>
        </Grid>
    </Grid>

Erstellen der Anwendungssteuerung

Der Anwendungssteuerungscode (MainPage.xaml.cs) enthält die Main-Methode zum Ausführen der App sowie mehrere Schritte zum Ausführen Ihres Modells und der Ausgabe:

  1. Sie instanziieren ein neues Objekt der IrisModel-Klasse, die Sie zuvor in diesem Tutorial erstellt haben.
  2. Sie rufen die Evaluate()-Methode auf, die Sie im vorherigen Teil des Modells erstellt haben. Diese Methode wird viermal angewendet, einmal für jeden Eingabeparameter: Kelchblattlänge, Kelchblattbreite, Blütenblattlänge und Blütenblattbreite.

Die App zeigt das Ergebnis basierend auf dem Machine Learning-Vorhersagealgorithmus an.

  1. Doppelklicken Sie zum Erstellen eines Anwendungssteuerungscodes auf die Codedatei MainPage.xaml.cs, und fügen Sie den folgenden Code hinzu.
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace Iris_Data_Analysis
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private IrisModel _iris_model;

        public MainPage()
        {
            this.InitializeComponent();
            _iris_model = new IrisModel();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            _iris_model.Initialize();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }

        private void sepal_length_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Sepal_Length = (float)sepal_length_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }

        private void sepal_width_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Sepal_Width = (float)sepal_width_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }

        private void petal_length_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Petal_Length = (float)petal_length_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }

        private void petal_width_input_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (_iris_model != null)
            {
                _iris_model.Petal_Width = (float)petal_width_input.Value / 10.0f;
                model_output.Text = _iris_model.Evaluate();
            }
        }
    }
}

Die Anwendung starten

Nun können Sie Ihre Anwendung starten und die Ergebnisse einsehen.

Aktivieren Sie den Entwicklermodus, und testen Sie Ihre Anwendung über Visual Studio. Stellen Sie sicher, dass die Dropdownmenüs in der oberen Symbolleiste auf Debug festgelegt sind. Ändern Sie die Projektmappenplattform in x64, um das Projekt auf dem lokalen Computer auszuführen, wenn es sich um ein 64-Bit-Gerät handelt, oder in x86 für einen 32-Bit-Computer.

Die Benutzeroberfläche der App enthält vier Schieberegler, mit denen die Eingabe der erforderlichen Parameter geändert werden kann. Jede Änderung der Eingabe generiert eine neue Ausgabe auf Grundlage des Vorhersagealgorithmus. Die Ausgabe wird unterhalb der Eingabeschieberegler angezeigt.

Sie können sehen, dass die App bei der Eingabe von Kelchblattlänge = 40 mm, Kelchblattbreite = 50, Blütenblattlänge = 75 und Blütenblattbreite = 15 die Eingabe des Typs „Iris-versicolor“ generiert hat!

Successful classification in your app

Zusammenfassung

Sie haben soeben Ihre erste Windows Machine Learning-App erstellt: von der Modellerstellung bis zur erfolgreichen Ausführung.

Weitere Ressourcen

Weitere Informationen zu den in diesem Tutorial erwähnten Themen finden Sie in den folgenden Ressourcen: