Condividi tramite


Distribuire il modello di analisi dei dati nell'app di Windows con le API di Windows ML

Nella parte precedente di questa esercitazione si è appreso come compilare ed esportare un modello in formato ONNX. Verrà ora illustrato come incorporare il modello esportato in un'applicazione Windows ed eseguirlo in locale in un dispositivo chiamando le API di Windows ML.

Al termine, si avrà un'app di analisi dei dati funzionante.

Informazioni sull'app di esempio

In questo passaggio dell'esercitazione si creerà un'app in grado di analizzare i dati tabulari di Iris. L'app consente di aggiungere il file excel con le informazioni di input necessarie o immettere manualmente i parametri di input, ovvero la lunghezza e la larghezza del sepale e del petalo iris in cm. Queste funzionalità verranno elaborate da un modello ONNX della rete neurale archiviata in locale creato e sottoposto a training nella parte precedente. In base all'output del modello, l'app visualizzerà il tipo Iris corretto.

In questo caso, verrà illustrato questo processo.

Nota

Se si sceglie di usare l'esempio di codice predefinito, è possibile clonare il file della soluzione. Clonare il repository, passare a questo esempio e aprire il Iris Data Analysis.csproj file con Visual Studio.Skip alla parte Avvia applicazione di questa pagina per visualizzarla in uso.

Di seguito verrà illustrato come creare l'app e aggiungere codice windows ML.

Creare un'app Desktop di Windows ML (C#)

Per creare un'app di Windows ML funzionante, è necessario eseguire le operazioni seguenti:

  • Caricare un modello di Machine Learning.
  • Associare gli input e gli output del modello.
  • Valutare il modello e visualizzare risultati significativi.

Dovrai anche creare un'interfaccia utente di base per offrire un'esperienza utente migliore.

Aprire un nuovo progetto in Visual Studio

  1. Iniziamo. Aprire Visual Studio e scegliere Create a new project.

Create new Visual Studio project

  1. Nella barra di ricerca scegliere C# come lingua, Windows come piattaforma di destinazione e Dektop come tipo di progetto. Selezionare NUnit Test Project (.NET Core) come tipo di progetto e selezionare next per aprire una finestra di configurazione per il progetto.

Create new NUnit Test Project app

  1. Nella finestra di configurazione eseguire le operazioni seguenti:
  • Assegnare un nome al progetto. In questo caso, viene chiamato Iris Data Analysis.
  • Scegliere il percorso del progetto.
  • Se si usa VS2019, verificare che Create directory for solution sia selezionata.
  • Se si usa VS2017, verificare che Place solution and project in the same directory sia deselezionata.

Premere create per creare il progetto. È possibile che venga visualizzata la finestra della versione di destinazione minima. Assicurarsi che la versione minima sia impostata su Windows 10, versione 1809 (10.0; build 17763) o successiva.

  1. Dopo aver creato il progetto, passare alla cartella del progetto, aprire la cartella [….\DataClassifier\Assets]assets e copiare il Network.onnx file in questo percorso.

Esplorare la soluzione del progetto

Si esaminerà ora la soluzione del progetto.

Visual Studio ha creato automaticamente diversi file cs-code all'interno del Esplora soluzioni. MainPage.xaml contiene il codice XAML per l'interfaccia utente grafica e MainPage.xaml.cs contiene il codice dell'applicazione. Se hai creato un'app UWP in precedenza, questi file dovrebbero essere molto familiari.

Anche se il file è stato aggiunto Network.onnx alla cartella assets, è necessario aggiungerlo correttamente a questo progetto.

  1. Fare clic con il pulsante destro del mouse sulla cartella Assets nel Esplora soluzioni e scegliere Add > Existing Item.
  2. Passare alla cartella Assets all'interno Iris Data Analysis [….\Iris Data Analysis \Assets]di , individuare l'elemento Network.onnx model copiato in precedenza e selezionare Add.
  3. Per assicurarsi che il modello venga compilato durante la compilazione dell'applicazione, fare clic con il pulsante destro del Network.onnx mouse sul file e selezionare Properties. Imposta Build Action su Content.

È anche necessario creare un nuovo file di classe cs-code per contenere codice aggiuntivo di Machine Learning, che include classi e metodi che chiameranno le API di Windows ML.

  1. Fare clic con il pulsante destro del mouse sul nome della soluzione in Visual Studio e scegliere add e new item. Nella finestra aperta selezionare Class e assegnare un nome. In questo caso si usa IrisModel.cs. Un nuovo file di classe farà appello nel progetto.

Add a new class file to your VS project.

Creare codice di Machine Learning

In questo passaggio verranno creati tutti i metodi e le classi che chiameranno le API di Windows Machine Learning. Questi consentono di caricare, associare e valutare un modello di Machine Learning ONNX nel progetto.

  1. Fare doppio clic sul IrisModel.cs file.

  2. Sostituire le istruzioni using con le istruzioni seguenti per ottenere l'accesso a tutte le API necessarie.

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

Inizializzare le classi di Machine Learning

È necessario aggiungere diverse classi per IrisModel.cs consentire l'interazione con le API di Windows Machine Learning.

Per ottenere l'accesso al modello di Machine Learning sottoposto a training, si userà la LearningModel classe . Questa classe fa parte dello spazio dei Windows.AI.MachineLearning nomi e rappresenta un modello di Machine Learning sottoposto a training. Una volta creata un'istanza, è l'oggetto LearningModel principale usato per interagire con le API di Windows ML.

Per valutare il modello di apprendimento, è necessario creare una sessione di valutazione. A tale scopo, usare la LearningModelSession classe . Questa classe viene usata per valutare i modelli di Machine Learning e associa il modello a un dispositivo che esegue e valuta il modello. Quando si crea una sessione con questa API, è anche possibile selezionare un dispositivo per eseguire il modello (il valore predefinito è la CPU).

È anche necessario specificare le etichette dell'output dei modelli di Machine Learning. È possibile connettere tali etichette all'output previsto del modello in un secondo momento.

Nota

Per altre informazioni su LearningModel e LearningModelSession classi, vedere la documentazione della classe LearningModel e la documentazione della classe LearningModelSession.

  1. Copiare il codice seguente nel IrisModel.cs file .
class IrisModel
    {
        private LearningModel _learning_model;
        private LearningModelSession _session;
        private String[] _labels = { "Iris-setosa", "Iris-versicolor", "Iris-virginica"};

Caricare il modello

Sarà quindi necessario caricare il modello di Machine Learning e creare una sessione, che verrà eseguita con le classi appena definite. Per caricare il modello, si useranno diversi metodi statici della LearningModel classe, in questo caso si userà LoadFrom Archiviazione FileAsync, che consente di caricare un modello ONNX da un'istanza ISorageFile asincrona.

Nota

Per altre informazioni sui modi aggiuntivi per caricare il modello, vedere la documentazione caricare un modello.

  1. Copiare il codice seguente nel IrisModel.cs file .
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);
}

Definire il tensore di input del modello

A questo punto, verrà definito l'input corretto in base ai requisiti del modello. Il modello di rete compilato nella parte precedente ha quattro valori di input. Ogni valore di input rappresenta le dimensioni possibili di quattro caratteristiche di iris: lunghezza sepale in cm, larghezza del sepale in cm, lunghezza dei petali in cm e larghezza petalo in cm. In base a questo input, il modello restituirà il tipo iris più adatto a tali parametri. Per questa esercitazione è necessario limitare le dimensioni dei valori di input ai valori logici validi. Per questa esercitazione si userà quanto segue:

  • lunghezza sepal - da 1cm a 100cm
  • larghezza sepal : da 1 cm a 8 cm
  • lunghezza petalo - da 0,5 cm a 10 cm
  • larghezza dei petali : da 0,1 cm a 5 cm
  1. Copiare il codice seguente nel IrisModel.cs file .
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;
        }
    }
}

Le API di Windows ML accettano valori di input delle quattro classi descrittive supportate dai modelli ONNX: tensori, sequenze, mappe e immagini. In questo caso, il modello richiede un oggetto float a 32 bit in una forma float32[batch_size,4]. Poiché la dimensione del batch è 1, la forma del tensore di input è [1x4].

Per creare un input tensor, si userà la classe TensorFloat .

La TensorFloat classe fa parte dello spazio dei Windows.AI.MachineLearning nomi e viene usata per definire un oggetto tensore float a 32 bit, ovvero un tensore di valori a virgola mobile a 32 bit. Questa classe contiene diversi metodi utili per compilare un tensore. In questo caso, si userà il metodo CreateFromArray per compilare un input tensor nella dimensione esatta richiesta dal modello. Questa chiamata verrà aggiunta all'interno del metodo di valutazione.

Associare e valutare il modello

Dopo aver definito il tensore di input del modello e aver creato un'istanza del modello e della sessione con training, è possibile creare un metodo per associare e valutare il modello di Machine Learning sottoposto a training.

Questo metodo è la parte fondamentale di un'app di Machine Learning. Include la tensorizzazione dei valori di input e l'associazione dell'input del modello. Questo modello verrà usato più avanti nel codice dell'applicazione per valutare il modello.

Per associare input e output, usare la LearningModelBinding classe . Un modello di Machine Learning include caratteristiche di input e output, che passano informazioni all'interno e all'esterno del modello. Tenere presente che le funzionalità necessarie devono essere supportate dalle API di Windows ML. La LearningModelBinding classe viene applicata a un LearningModelSession oggetto per associare valori alle funzionalità di input e output denominate.

La LearningModelBinding classe include diversi metodi predefiniti che è possibile usare per associare valori a tali funzionalità denominate. In questo caso si userà il Bind metodo per associare i valori al modello.

Per valutare il modello e ricevere i risultati da esso, chiamare i metodi di evauazione predefiniti di ripetizione da LearningModelSession , nel caso specifico, il Evaluate metodo . Questo metodo fornirà la funzionalità necessaria, valutando il modello di Machine Learning usando i valori delle funzionalità forniti dalla LearningModelBinding classe .

Nota

Per informazioni su altri metodi di valutazione per eseguire il modello, verificare quali metodi possono essere implementati in LearningModelSession esaminando la documentazione della classe LearningModelSession.

Estrarre e visualizzare i risultati

Il modello restituisce i valori stimati in formato tensor come output float tensor. Sarà ora necessario estrarre l'output del modello e visualizzare i risultati corretti. A tale scopo, si convertirà il formato del tensore in un vettore eseguendo la GetAsVectorView() funzione nell'output predicato.

Il modello restituisce tre valori di probabilità, ognuno dei quali rappresenta un tipo iris specifico. Sarà necessario restituire l'etichetta con la probabilità più alta.

  1. Copiare il codice seguente nel IrisModel.cs file .
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);
}

A questo punto è stata completata la parte di Machine Learning del codice. A questo punto, è possibile integrare facilmente il modello con l'applicazione Windows. Nell'ultima parte di questa esercitazione è stata fornita un'interfaccia utente grafica e codice di controllo di Windows di base per testare il modello, usando i metodi già creati.

Creare l'interfaccia utente grafica dell'applicazione

  1. Per creare un codice dell'app GUI per l'app, fare doppio clic sul file di MainPage.xaml codice e aprire un modello predefinito per l'interfaccia utente grafica.

  2. Copiare il codice seguente in MainPage.xaml, sotto la “Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" " Height="939"> riga .

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

Creare il controllo dell'applicazione

Il codice di controllo dell'applicazione, MainPage.xaml.cs, include il metodo principale per eseguire l'app e diversi passaggi per eseguire il modello ed eseguire l'output:

  1. Verrà creata un'istanza di un nuovo oggetto della IrisModel classe creata in precedenza in questa esercitazione.
  2. Si chiamerà il Evaluate() metodo compilato nella parte precedente del modello. Questo metodo verrà applicato quattro volte, uno per ognuno dei parametri di input: lunghezza sepale, larghezza del sepale, lunghezza petalo e larghezza petalo.

L'app visualizzerà il risultato in base all'algoritmo di stima di Machine Learning.

  1. Per creare un codice di controllo dell'applicazione, fare doppio clic sul MainPage.xaml.cs file di codice e aggiungere il codice seguente.
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();
            }
        }
    }
}

Avvia l'applicazione

A questo punto è possibile avviare l'applicazione e visualizzare i risultati.

Abilitare la modalità sviluppatore e testare l'applicazione da Visual Studio. Assicurarsi che i menu a discesa nella barra degli strumenti superiore siano impostati su Debug. Impostare Solution Platform su x64 per eseguire il progetto nel computer locale se il dispositivo è a 64 bit o x86 se è a 32 bit.

L'interfaccia utente grafica dell'app include quattro dispositivi di scorrimento per modificare l'input dei parametri necessari. Qualsiasi modifica nell'input genererà un nuovo output basato sull'algoritmo di stima. L'output viene visualizzato sotto i dispositivi di scorrimento di input.

Si può notare che dato l'input di lunghezza sepale = 40mm, larghezza sepale = 50, lunghezza petalo = 75 e larghezza petalo = 15, l'app ha generato l'input di tipo Iris-versicolor!

Successful classification in your app

Riepilogo

È stata appena creata la prima app di Windows Machine Learning, dalla creazione del modello alla corretta esecuzione.

Risorse aggiuntive

Per altre informazioni sugli argomenti presentati in questa esercitazione, vedere le risorse seguenti: