Condividi tramite


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

In questa esercitazione verrà creata una semplice applicazione UWP (Universal Windows Platform) che usa un modello di Machine Learning con training per riconoscere una cifra numerica disegnata dall'utente. Questa esercitazione è incentrata principalmente su come caricare e usare Windows ML nell'applicazione UWP.

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


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

Prerequisiti

  • Windows 10 (versione 1809 o successiva)
  • Windows 10 SDK (Build 17763 o versione successiva)
  • Visual Studio 2019 (o Visual Studio 2017, versione 15.7.4 o successiva)
  • Estensione Generatore di codice di Windows Machine Learning per Visual Studio 2019 o 2017
  • Alcune conoscenze di base sulla piattaforma UWP e C#

1. Aprire il progetto in Visual Studio

Dopo aver scaricato il progetto da GitHub, avviare Visual Studio e aprire il file di MNIST_Demo.sln (dovrebbe trovarsi in <Percorso per il repository>\Windows-Machine-Learning\Samples\MNIST\Tutorial\cs). Se la soluzione non è disponibile, è necessario fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e selezionare Ricarica progetto.

È stato fornito un modello con i controlli e gli eventi XAML implementati, tra cui:

  • InkCanvas per disegnare la cifra.
  • Pulsanti per interpretare la cifra e cancellare l'area di disegno.
  • Routine di supporto per convertire l'output InkCanvas in un VideoFrame.

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

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

Esplora soluzioni di Visual Studio con file di progetto

2. Compilare ed eseguire il progetto

Nella barra degli strumenti di Visual Studio impostare Piattaforma soluzione su x64 per eseguire il progetto nel computer locale se il dispositivo è a 64 bit o x86 se è a 32 bit. È possibile controllare le impostazioni di Windows: Sistema > informazioni sulle > specifiche del > dispositivo Tipo di sistema.

Per eseguire il progetto, fare clic sul pulsante Avvia debug sulla barra degli strumenti oppure premere F5. L'applicazione dovrebbe mostrare un InkCanvas su cui gli utenti possono scrivere una cifra, un pulsante Riconosci per interpretare il numero, un campo etichetta vuoto in cui verrà visualizzata la cifra interpretata come testo, e un pulsante Cancella cifra per pulire l'InkCanvas.

Screenshot dell'applicazione

Annotazioni

Se il progetto non verrà compilato, potrebbe essere necessario modificare la versione di destinazione della distribuzione del progetto. Fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Proprietà. Nella scheda Applicazione impostare Versione di destinazione e Versione minima in modo che corrisponda al sistema operativo e all'SDK.

Annotazioni

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

3. Scaricare un modello

Si otterrà quindi un modello di Machine Learning da aggiungere all'applicazione. Per questa esercitazione, useremo un modello MNIST pre-addestrato che è stato addestrato con il Microsoft Cognitive Toolkit (CNTK) ed esportato in formato ONNX.

Il modello MNIST è già stato incluso nella cartella Assets ed è necessario aggiungerlo all'applicazione come elemento esistente. È anche possibile scaricare il modello pre-addestrato dallo zoo dei modelli ONNX su GitHub.

4. Aggiungere il modello

Fare clic con il pulsante destro del mouse sulla cartella Assets in Esplora soluzioni e selezionare Aggiungi>elemento esistente. Indicare il selettore di file alla posizione del modello ONNX e fai clic su Aggiungi.

Il progetto dovrebbe ora avere due nuovi file:

  • mnist.onnx - Il tuo modello addestrato.
  • mnist.cs : codice generato da Windows ML.

Esplora soluzioni con nuovi file

Per assicurarsi che il modello venga compilato durante la compilazione dell'applicazione, fare clic con il pulsante destro del mouse sul file mnist.onnx e selezionare Proprietà. Per Azione di compilazione selezionare Contenuto.

Esaminiamo ora il codice appena generato nel file mnist.cs . Sono disponibili tre classi:

  • mnistModel crea la rappresentazione del modello di Machine Learning, crea una sessione nel dispositivo predefinito del sistema, associa gli input e gli 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 restituiti dal modello. In questo caso, l'output sarà un elenco denominato Plus214_Output_0 di tipo TensorFloat.

Queste classi verranno ora 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.

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

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

Prima di tutto, in MainPage.xaml.cs, instanziamo il modello, gli input e gli output. Aggiungere le variabili membro seguenti alla classe MainPage :

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

Quindi, in LoadModelAsync, il modello verrà caricato. Questo metodo deve essere chiamato prima di usare uno dei metodi del modello, ovvero nell'evento Loaded di MainPage, in un override OnNavigatedTo o in qualsiasi punto prima della chiamata di recognizeButton_Click. La classe mnistModel rappresenta il modello MNIST e crea la sessione nel 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);
}

Annotazioni

Se si ottengono sottolineature rosse in IRandomAccessStreamReference, è necessario includerne lo spazio dei nomi. Posizionare il cursore su di esso, premere CTRL+ e selezionare usando Windows.Storage.Streams dal menu a discesa.

Successivamente, si vogliono associare gli input e gli output al modello. Il codice generato include anche classi wrapper mnistInput e mnistOutput . La classe mnistInput rappresenta gli input previsti del modello e la classe mnistOutput rappresenta gli output previsti del modello.

Per inizializzare l'oggetto di input del modello, chiamare il costruttore della classe mnistInput , passare i dati dell'applicazione e assicurarsi che i dati di input corrispondano al tipo di input previsto dal modello. La classe mnistInput prevede un ImageFeatureValue, quindi viene usato un metodo helper per ottenere un ImageFeatureValue per l'input.

Usando le funzioni helper incluse in helper.cs, copiare il contenuto di InkCanvas, convertirlo nel tipo ImageFeatureValue e associarlo 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. Dopo aver inizializzato gli input, chiamare il metodo EvaluateAsync del modello per valutare il modello sui dati di input. EvaluateAsync associa gli input e gli output all'oggetto modello e valuta il modello sugli input.

Poiché il modello restituisce un tensore di output, è necessario prima convertirlo in un tipo di dati descrittivo e quindi analizzare l'elenco restituito per determinare quale cifra ha la probabilità più alta e visualizzarla.

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, si vuole cancellare 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

Dopo aver compilato e avviato l'applicazione (premere F5), saremo in grado di riconoscere un numero disegnato in InkCanvas.

applicazione completa

Ecco fatto - hai creato la tua prima applicazione di Windows ML! Per altri esempi che illustrano come usare Windows ML, vedere il repository Windows-Machine-Learning in GitHub.

Annotazioni

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.