Dela via


Distribuera dataanalysmodellen i Windows-appen med Windows ML-API:er

I föregående del av den här självstudien lärde du dig hur du skapar och exporterar en modell i ONNX-format. Nu ska vi visa dig hur du bäddar in din exporterade modell i ett Windows-program och kör den lokalt på en enhet genom att anropa Windows ML-API:er.

När vi är klara har du en fungerande dataanalysapp.

Om exempelappen

I det här steget i självstudien skapar du en app som kan analysera tabelldata för Irises. Med appen kan du lägga till Excel-filen med nödvändig indatainformation eller manuellt ange indataparametrarna – längden och bredden på Iris sepal och kronblad i cm. Dessa funktioner bearbetas av en lokalt lagrad ONNX-modell för neurala nätverk som du skapade och tränade i föregående del. Baserat på modellutdata visar appen rätt Iris-typ.

Här går vi igenom den processen.

Anmärkning

Om du väljer att använda det fördefinierade kodexemplet kan du klona lösningsfilen. Klona förvaret, gå till det här exemplet och öppna filen Iris Data Analysis.csproj med Visual Studio. Hoppa till delen Starta programmet för att se den i användning.

Nedan visar vi hur du skapar din app och lägger till Windows ML-kod.

Skapa en Windows ML Desktop-app (C#)

Om du vill skapa en fungerande Windows ML-app måste du göra följande:

  • Läs in en maskininlärningsmodell.
  • Binda modellens indata och utdata.
  • Utvärdera modellen och visa meningsfulla resultat.

Du måste också skapa ett grundläggande användargränssnitt för att ge en bättre användarupplevelse.

Öppna ett nytt projekt i Visual Studio

  1. Nu ska vi komma igång. Öppna Visual Studio och välj Create a new project.

Skapa ett nytt Visual Studio-projekt

  1. I sökfältet väljer du C# som språk, Windows som målplattform och Dektop som projekttyp. Välj NUnit Test Project (.NET Core) som projekttyp och välj next för att öppna ett konfigurationsfönster för projektet.

Skapa ny NUnit Test Project-app

  1. Gör följande i konfigurationsfönstret:
  • Ge projektet ett namn. Här kallar vi det Iris Data Analysis.
  • Välj platsen för projektet.
  • Om du använder VS2019 kontrollerar du att Create directory for solution är markerad.
  • Om du använder VS2017, se till att Place solution and project in the same directory är avmarkerad.

Tryck create för att skapa projektet. Det lägsta målversionsfönstret kan dyka upp. Kontrollera att din lägsta version är inställd på Windows 10, version 1809 (10.0; build 17763) eller senare.

  1. När projektet har skapats navigerar du till projektmappen, öppnar mappen [….\DataClassifier\Assets] och kopierar Network.onnx filen till den här platsen.

Utforska projektlösning

Nu ska vi utforska din projektlösning.

Visual Studio skapade automatiskt flera cs-code-filer i Solution Explorer. MainPage.xaml innehåller XAML-koden för ditt GUI och MainPage.xaml.cs innehåller programkoden. Om du har skapat en UWP-app tidigare bör dessa filer vara mycket bekanta för dig.

Även om vi har lagt till filen Network.onnx i mappen assets måste vi lägga till den korrekt i det här projektet.

  1. Högerklicka på mappen Tillgångar i Solution Explorer och välj Add > Existing Item.
  2. Gå till mappen Tillgångar i Iris Data Analysis [….\Iris Data Analysis \Assets], leta reda på den Network.onnx model du kopierade tidigare där och välj Add.
  3. För att säkerställa att modellen byggs när du kompilerar ditt program högerklickar du på Network.onnx filen och väljer Properties. Ange Build Action till Content.

Du måste också skapa en ny cs-code-klassfil för att hantera lite extra maskininlärningskod, som innehåller klasser och metoder som anropar Windows ML-API:er.

  1. Högerklicka på lösningsnamnet i Visual Studio och välj add och new item. I det öppna fönstret väljer du Class och ger det ett namn – här använder IrisModel.csvi . En ny klassfil kommer att visas under ditt projekt.

Lägg till en ny klassfil i DITT VS-projekt .

Skapa Machine Learning-kod

I det här steget skapar vi alla klasser och metoder som anropar Windows Machine Learning-API:er. Med dessa kan du läsa in, binda och utvärdera en ONNX-maskininlärningsmodell i projektet.

  1. Dubbelklicka på IrisModel.cs filen.

  2. Ersätt användningsinstruktionerna med följande för att få åtkomst till alla API:er som du behöver.

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

Initiera maskininlärningsklasser

Vi måste lägga till flera klasser i IrisModel.cs så att du kan interagera med Windows Machine Learning-API:er.

För att få åtkomst till den tränade maskininlärningsmodellen använder LearningModel vi klassen. Den här klassen är en del av Windows.AI.MachineLearning namnområdet och representerar en tränad maskininlärningsmodell. När du har instansierat LearningModel är det huvudobjektet som du använder för att interagera med Windows ML-API:er.

För att utvärdera inlärningsmodellen måste du skapa en utvärderingssession. För att göra det använder LearningModelSession du klassen . Den här klassen används för att utvärdera maskininlärningsmodeller och binder modellen till en enhet som sedan kör och utvärderar modellen. När du skapar en session med det här API:et kan du också välja en enhet för att köra din modell (standardvärdet är din CPU).

Dessutom måste du ange etiketterna för utdata för dina maskininlärningsmodeller. Du kan ansluta dessa etiketter till modellens förutsagda utdata senare.

Anmärkning

För att lära dig mer om LearningModel och LearningModelSession-klasser, vänligen granska dokumentationen för LearningModel-klassen och dokumentationen för LearningModelSession-klassen.

  1. Kopiera följande kod till IrisModel.cs filen.
class IrisModel
    {
        private LearningModel _learning_model;
        private LearningModelSession _session;
        private String[] _labels = { "Iris-setosa", "Iris-versicolor", "Iris-virginica"};

Läs in modellen

Därefter måste du läsa in maskininlärningsmodellen och skapa en session, vilket du ska göra med de klasser som du precis har definierat. För att läsa in modellen använder du flera statiska metoder LearningModel i klassen – i vårt fall använder vi LoadFromStorageFileAsync, vilket gör att du kan läsa in en ONNX-modell från en ISorageFile asynkront.

Anmärkning

Mer information om ytterligare sätt att läsa in modellen finns i dokumentationen Läsa in en modell.

  1. Kopiera följande kod till IrisModel.cs filen.
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);
}

Definiera modellens innmatningstensor

Nu ska vi definiera rätt indata baserat på dina modellkrav. Nätverksmodellen som du skapade i föregående del har fyra indatavärden. Varje indatavärde representerar de möjliga storlekarna på fyra funktioner i iris: sepallängd i cm, sepalbredd i cm, kronbladslängd i cm och kronbladsbredd i cm. Baserat på dessa indata returnerar modellen den iristyp som passar bäst för dessa parametrar. Du måste begränsa storleken på indatavärdena till giltiga logiska värden – i den här självstudien använder vi följande:

  • sepal längd - 1cm till 100cm
  • sepal bredd – 1cm till 8cm
  • kronbladslängd – 0,5 cm till 10cm
  • kronblad bredd – 0.1cm till 5cm
  1. Kopiera följande kod till IrisModel.cs filen.
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 API:er accepterar indatavärden för de fyra beskrivande klasser som stöds av ONNX-modeller: tensorer, sekvenser, kartor och bilder. I det här fallet kräver modellen ett 32-bitars tensor float-objekt i en form av float32[batch_size,4]. Eftersom batchstorleken är 1 är indatatensorformen [1x4].

Om du vill skapa en tensor-indata använder du klassen TensorFloat .

Klassen TensorFloat är en del av Windows.AI.MachineLearning namnområdet och används för att definiera ett 32-bitars flyttals tensor-objekt – en tensor med 32-bitars flyttalsvärden. Den här klassen innehåller flera användbara metoder för att skapa en tensor. I ditt fall använder du metoden CreateFromArray för att skapa en tensor-indata i den exakta storlek som din modell kräver. Vi kommer att lägga till det anropet i utvärderingsmetoden.

Binda och utvärdera modellen

Nu när du har definierat modellens indata tensor och instansierat den tränade modellen och sessionen är det dags att skapa en metod för att binda och utvärdera den tränade maskininlärningsmodellen.

Den här metoden är den viktigaste delen i en maskininlärningsapp. Den innehåller tensorization av indatavärden och bindning av modellindata. Du använder den här modellen senare i programkoden för att utvärdera din modell.

Om du vill binda indata och utdata använder LearningModelBinding du klassen . En maskininlärningsmodell har indata- och utdatafunktioner som skickar information till och från modellen. Tänk på att nödvändiga funktioner måste stödjas av Windows ML-API:er. Klassen LearningModelBinding tillämpas på en LearningModelSession för att binda värden till namngivna indata- och utdatafunktioner.

Klassen LearningModelBinding har flera fördefinierade metoder som du kan använda för att binda värden till de namngivna funktionerna. Här använder Bind du metoden för att binda värden till din modell.

Om du vill utvärdera din modell och ta emot resultat från den anropar du de relevanta fördefinierade utvärderingsmetoderna från LearningModelSession - i ditt fall, Evaluate-metoden. Den här metoden tillhandahåller de funktioner du behöver och utvärderar maskininlärningsmodellen med hjälp av de funktionsvärden som tillhandahålls av LearningModelBinding klassen.

Anmärkning

Om du vill veta mer om andra utvärdera metoder för att köra modellen kontrollerar du vilka metoder som kan implementeras på LearningModelSession genom att läsa dokumentationen om LearningModelSession Class.

Extrahera och visa resultatet

Modellen returnerar de förutsagda värdena i tensorformat som tensor-flyttalsutdata. Nu måste du extrahera modellutdata och visa rätt resultat. För att göra detta konverterar du tensor-formatet till en vektor genom att köra GetAsVectorView() funktionen på de predikaterade utdata.

Modellen returnerar tre sannolikhetsvärden som var och en representerar en specifik iristyp. Du måste returnera etiketten med högst sannolikhet.

  1. Kopiera följande kod till IrisModel.cs filen.
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);
}

Nu har du slutfört maskininlärningsdelen av koden. Nu kan du enkelt integrera din modell med Windows-programmet. I den sista delen av den här självstudien har vi tillhandahållit ett grundläggande Windows-GUI och kontrollkod för att testa modellen med hjälp av de metoder som du redan har skapat.

Skapa programmets GUI

  1. Om du vill skapa en GUI-appkod för din app dubbelklickar du på MainPage.xaml kodfilen och öppnar en fördefinierad mall för ditt GUI.

  2. Kopiera och klistra in koden nedan till MainPage.xaml, under “Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" " Height="939"> raden.

    <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>

Skapa programkontrollen

Programkontrollkoden , MainPage.xaml.csinnehåller huvudmetoden för att köra appen och flera steg för att köra din modell och köra utdata:

  1. Du instansierar ett nytt objekt i klassen IrisModel som du skapade tidigare i den här självstudien.
  2. Du anropar den Evaluate() metod som du skapade i föregående del av modellen. Den här metoden tillämpas fyra gånger, en på var och en av indataparametrarna: sepallängd, sepalbredd, kronbladslängd och kronbladsbredd.

Appen visar resultatet baserat på algoritmen för maskininlärningsförutsägelse.

  1. Om du vill skapa en programkontrollkod dubbelklickar du på MainPage.xaml.cs kodfilen och lägger till följande kod.
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();
            }
        }
    }
}

Starta programmet

Nu är du redo att starta programmet och se resultatet.

Aktivera utvecklarläge och testa ditt program från Visual Studio. Kontrollera att de nedrullningsbara menyerna i det övre verktygsfältet är inställda på Debug. Ändra Solution Platform till x64 för att köra projektet på den lokala datorn om enheten är 64-bitars eller x86 om den är 32-bitars.

Appens GUI innehåller fyra skjutreglage för att ändra indata för de obligatoriska parametrarna. Alla ändringar i indata genererar nya utdata baserat på förutsägelsealgoritmen. Utdata visas under indata-skjutreglagen.

Du kan se att den givna datainmatningen av foderbladslängd = 40mm, foderbladsbredd = 50, kronbladslängd = 75, och kronbladsbredd = 15, appen genererade data av typen Iris-versicolor!

Lyckad klassificering i din app

Sammanfattning

Du har precis gjort din första Windows Machine Learning-app, från att skapa modellen till att köra den framgångsrikt.

Ytterligare resurser

Mer information om ämnen som nämns i den här självstudien finns i följande resurser: