Esercitazione: Creare un'applicazione UWP di Windows Machine Learning (C#)

In questa esercitazione verrà creata una semplice applicazione della piattaforma UWP (Universal Windows Platform) che usa un modello di Machine Learning già sottoposto a training per riconoscere una cifra numerica disegnata dall'utente. L'esercitazione è incentrata principalmente su come caricare e usare Windows ML nella tua applicazione UWP.

Il video seguente illustra l'esempio su cui si basa l'esercitazione.


Se preferisci semplicemente esaminare il codice dell'esercitazione completata, puoi trovarlo nel repository WinML in GitHub. È disponibile anche in C++/CX.

Prerequisiti

  • Windows 10 (versione 1809 o successive)
  • Windows 10 SDK (build 17763 o successive)
  • Visual Studio 2019 (o Visual Studio 2017 versione 15.7.4 o successive)
  • Estensione Generatore di codice di Windows Machine Learning per Visual Studio 2019 o 2017
  • Conoscenza di base della piattaforma UWP e di C#

1. Aprire il progetto in Visual Studio

Dopo aver scaricato il progetto da GitHub, avvia Visual Studio e apri il file MNIST_Demo.sln (dovrebbe trovarsi in <percorso del repository>\Windows-Machine-Learning\Samples\MNIST\Tutorial\cs). Se la soluzione viene visualizzata come non disponibile, dovrai fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Ricarica progetto.

È stato preparato un modello (template) con eventi e controlli XAML implementati, tra cui:

  • Un controllo InkCanvas per disegnare la cifra.
  • Controlli Button per interpretare la cifra e cancellare il contenuto dell'area di disegno.
  • Routine di supporto per convertire l'output di InkCanvas in un oggetto VideoFrame.

All'interno di Esplora soluzioni il progetto include tre file di codice principali:

  • MainPage.xaml: tutto il codice XAML per creare l'interfaccia utente per InkCanvas, i pulsanti e le etichette.
  • MainPage.xaml.cs: posizione in cui si trova il codice dell'applicazione.
  • Helper.cs: routine di supporto per ritagliare e convertire i formati immagine.

Visual Studio solution explorer with project files

2. Compilare ed eseguire il progetto

Nella barra degli strumenti di Visual Studio imposta la piattaforma della soluzione su x64 per eseguire il progetto nel computer locale se il dispositivo è a 64 bit oppure su x86 se il dispositivo è a 32 bit. È possibile archiviare l'app Windows Impostazioni: System About Device specifications System type (Sistema > informazioni sulle > specifiche del > dispositivo Tipo di sistema).

Per eseguire il progetto, fai clic sul pulsante Avvia debug sulla barra degli strumenti oppure premi F5. Nell'applicazione dovrebbe essere visualizzato un controllo InkCanvas in cui gli utenti possono scrivere una cifra, un pulsante Recognize (Riconosci) per interpretare il numero, un campo etichetta vuoto in cui la cifra interpretata verrà visualizzata come testo e un pulsante Clear Digit (Cancella cifra) per cancellare il contenuto di InkCanvas.

Application screenshot

Nota

Se il progetto non viene compilato, potresti dover cambiare la versione di destinazione della distribuzione del progetto. Fai clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegli Proprietà. Nella scheda Applicazione imposta i campi Versione di destinazione e Versione minima in modo che corrispondano al sistema operativo e all'SDK in uso.

Nota

Se viene visualizzato un avviso che indica che l'applicazione è già installata, è sufficiente selezionare per continuare con la distribuzione. Potrebbe essere necessario chiudere Visual Studio e riaprirlo se ancora non funziona.

3. Scaricare un modello

Successivamente, sarà necessario ottenere un modello di Machine Learning da aggiungere all'applicazione. Per questa esercitazione verrà usato un modello MNIST già sottoposto a training con Microsoft Cognitive Toolkit (CNTK) ed esportato nel formato ONNX.

Il modello MNIST è già stato incluso nella cartella degli asset e dovrai aggiungerlo all'applicazione come un elemento esistente. Puoi inoltre scaricare il modello con training preliminare da ONNX Model Zoo in GitHub.

4. Aggiungere il modello

Fai clic con il pulsante destro del mouse sulla cartella degliasset in Esplora soluzioni e scegli Aggiungi>Elemento esistente. Punta lo strumento di selezione file sul percorso del modello ONNX e fai clic su Aggiungi.

Il progetto ora dovrebbe avere due nuovi file:

  • mnist.onnx: il modello sottoposto a training.
  • mnist.cs: il codice generato da Windows ML.

Solution explorer with new files

Per assicurarti che il modello venga creato durante la compilazione dell'applicazione, fai clic con il pulsante destro del mouse sul file mnist.onnx e scegli Proprietà. Per Azione di compilazione seleziona Contenuto.

A questo punto, è possibile esaminare il codice appena generato nel file mnist.cs. Sono presenti tre classi:

  • mnistModel crea la rappresentazione del modello di Machine Learning, crea una sessione sul dispositivo predefinito del sistema, associa gli input e output specifici al modello e valuta il modello in modo asincrono.
  • mnistInput inizializza i tipi di input previsti dal modello. In questo caso, l'input prevede un ImageFeatureValue.
  • mnistOutput inizializza i tipi di output previsti dal modello. In questo caso, l'output sarà un elenco denominato Plus214_Output_0 di tipo TensorFloat.

Ora queste classi verranno usate per caricare, associare e valutare il modello nel progetto.

5. Caricare, associare e valutare il modello

Per le applicazioni Windows ML, il modello che si vuole seguire è: Load Bind Evaluate.For Windows ML applications, the pattern we want to follow is: Load > Bind > Evaluate.

  1. Caricare il modello di Machine Learning.
  2. Associare gli input e gli output al modello.
  3. Valutare i modello e visualizzare i risultati.

Il codice dell'interfaccia generato in mnist.cs verrà usato per caricare, associare e valutare il modello nell'applicazione.

Prima di tutto, nel file MainPage.xaml.cs è necessario creare un'istanza del modello e dei relativi input e output. Aggiungi le variabili membro seguenti alla classe MainPage:

private mnistModel ModelGen;
private mnistInput ModelInput = new mnistInput();
private mnistOutput ModelOutput;

Quindi, in LoadModelAsync sarà possibile caricare il modello. Questo metodo deve essere chiamato prima di usare uno dei metodi del modello, ovvero quando si verifica l'evento Loaded di MainPage, in un override di OnNavigatedTo o in qualsiasi punto prima che venga chiamato recognizeButton_Click. La classe mnistModel rappresenta il modello MNIST e crea la sessione sul dispositivo predefinito del sistema. Per caricare il modello, viene chiamato il metodo CreateFromStreamAsync, passando il file ONNX come parametro.

private async Task LoadModelAsync()
{
    // Load a machine learning model
    StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/mnist.onnx"));
    ModelGen = await mnistModel.CreateFromStreamAsync(modelFile as IRandomAccessStreamReference);
}

Nota

Se sotto IRandomAccessStreamReference vengono visualizzate sottolineature rosse, devi includere il relativo spazio dei nomi. Posizionare il cursore su di esso, premere CTRL+ e selezionare windows.Archiviazione. Flussi dal menu a discesa.

È quindi possibile associare gli input e output al modello. Il codice generato include anche le classi wrapper mnistInput e mnistOutput. La classe mnistInput rappresenta gli input previsti del modello, mentre la classe mnistOutput rappresenta gli output previsti del modello.

Per inizializzare l'oggetto di input del modello, chiama il costruttore della classe mnistInput passando i dati dell'applicazione, quindi verifica che i dati di input corrispondano al tipo di input previsto dal tuo modello. La classe mnistInput prevede un tipo ImageFeatureValue, pertanto viene usato un metodo di supporto per ottenere un tipo ImageFeatureValue per l'input.

Tramite le funzioni di supporto incluse in helper.cs, il contenuto di InkCanvas verrà copiato, convertito al tipo ImageFeatureValue e associato al modello.

private async void recognizeButton_Click(object sender, RoutedEventArgs e)
{
    // Bind model input with contents from InkCanvas
    VideoFrame vf = await helper.GetHandWrittenImage(inkGrid);
    ModelInput.Input3 = ImageFeatureValue.CreateFromVideoFrame(vf);
}

Per l'output, è sufficiente chiamare EvaluateAsync con l'input specificato. Una volta inizializzati gli input, chiama il metodo EvaluateAsync del modello per valutare il modello nei dati di input. EvaluateAsync associa gli input e gli output all'oggetto del modello e valuta il modello negli input.

Poiché il modello restituisce un tensore di output, sarà necessario prima convertirlo a un tipo di dati facile da usare, quindi analizzare l'elenco restituito per determinare la cifra con la probabilità più elevata e visualizzare tale cifra.

private async void recognizeButton_Click(object sender, RoutedEventArgs e)
{
    // Bind model input with contents from InkCanvas
    VideoFrame vf = await helper.GetHandWrittenImage(inkGrid);
    ModelInput.Input3 = ImageFeatureValue.CreateFromVideoFrame(vf);

    // Evaluate the model
    ModelOutput = await ModelGen.EvaluateAsync(ModelInput);

    // Convert output to datatype
    IReadOnlyList<float> vectorImage = ModelOutput.Plus214_Output_0.GetAsVectorView();
    IList<float> imageList = vectorImage.ToList();

    // Query to check for highest probability digit
    var maxIndex = imageList.IndexOf(imageList.Max());

    // Display the results
    numberLabel.Text = maxIndex.ToString();
}

Infine, è preferibile cancellare il contenuto di InkCanvas per consentire agli utenti di disegnare un altro numero.

private void clearButton_Click(object sender, RoutedEventArgs e)
{
    inkCanvas.InkPresenter.StrokeContainer.Clear();
    numberLabel.Text = "";
}

6. Avviare l'applicazione

Una volta compilata e avviata l'applicazione (premendo F5), sarà possibile riconoscere un numero disegnato nel controllo InkCanvas.

complete application

E questo è tutto: hai creato la tua prima applicazione di Windows ML. Per altri esempi che illustrano come usare Windows ML, vedi il repository Windows-Machine-Learning in GitHub.

Nota

Per informazioni su Windows Machine Learning, usa le risorse seguenti:

  • Per porre domande tecniche o rispondere a domande tecniche su Windows Machine Learning, usa il tag windows-machine-learning in Stack Overflow.
  • Per segnalare un bug, registra il problema in GitHub.