Tutoriel : Créer une application UWP Windows Machine Learning (C#)

Dans ce tutoriel, nous allons générer une application de plateforme Windows universelle (UWP) simple qui utilise un modèle Machine Learning entraîné pour reconnaître un chiffre dessiné par l’utilisateur. Ce tutoriel se concentre principalement sur le chargement et l’utilisation de Windows ML dans votre application UWP.

La vidéo suivante présente l’exemple sur lequel s’appuie ce tutoriel.


Si vous préférez simplement examiner le code du tutoriel terminé, vous pouvez le trouver dans le dépôt GitHub WinML. Il est également disponible en C++/CX.

Prérequis

  • Windows 10 (version 1809 ou ultérieure)
  • SDK Windows 10 (build 17763 ou version ultérieure)
  • Visual Studio 2019 (ou Visual Studio 2017, version 15.7.4 ou ultérieure)
  • Extension de générateur de code Windows Machine Learning pour Visual Studio 2019 ou 2017
  • Des connaissances de base sur UWP et C#

1. Ouvrir le projet dans Visual Studio

Une fois que vous avez téléchargé le projet à partir de GitHub, lancez Visual Studio et ouvrez le fichier MNIST_Demo.sln (il doit se trouver dans <Chemin du dépôt>\Windows-Machine-Learning\Samples\MNIST\Tutorial\cs). Si la solution s’affiche comme non disponible, vous devez cliquer avec le bouton droit sur le projet dans l’Explorateur de solutions, puis sélectionner Recharger le projet.

Nous avons fourni un modèle avec des contrôles et des événements XAML implémentés, notamment :

  • Un InkCanvas pour dessiner le chiffre.
  • Des boutons (button) pour interpréter le chiffre et effacer la zone de dessin.
  • Des routines d’assistance pour convertir la sortie d’InkCanvas en un VideoFrame.

Dans l’Explorateur de solutions, le projet comporte trois fichiers de code principaux :

  • MainPage.xaml : tout notre code XAML pour créer l’interface utilisateur de l’InkCanvas, des boutons et des étiquettes.
  • MainPage.xaml.cs : emplacement où réside notre code d’application.
  • Helper.cs : des routines d’assistance pour rogner et convertir les formats d’image.

Visual Studio solution explorer with project files

2. Générer et exécuter le projet

Dans la barre d’outils Visual Studio, remplacez la plateforme de solution par la plateforme x64 pour exécuter le projet sur votre ordinateur local s’il s’agit d’un appareil 64 bits, ou par la plateforme x86 s’il s’agit d’un appareil 32 bits. (Vous pouvez vérifier dans l’application Paramètres Windows : Système > À propos de > Spécifications de l’appareil > Type de système.)

Pour exécuter le projet, cliquez sur le bouton Démarrer le débogage sur la barre d’outils, ou appuyez sur F5. L’application doit afficher un InkCanvas où les utilisateurs peuvent écrire un chiffre, un bouton Reconnaître pour interpréter ce chiffre, un champ d’étiquette vide où le chiffre interprété s’affichera sous forme de texte et un bouton Effacer le chiffre pour effacer l’InkCanvas.

Application screenshot

Remarque

Si le projet n’est pas généré, vous devrez peut-être changer la version cible du déploiement du projet. Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions, puis sélectionnez Propriétés. Sous l’onglet Application, définissez la Version cible et la Version minimale pour faire correspondre votre système d’exploitation et le SDK.

Remarque

Si vous recevez un avertissement indiquant que l’application est déjà installée, sélectionnez simplement Oui pour poursuivre le déploiement. Vous devrez peut-être fermer Visual Studio et le rouvrir si le problème persiste.

3. Télécharger un modèle

Ensuite, nous allons obtenir un modèle Machine Learning à ajouter à notre application. Pour ce tutoriel, nous allons utiliser un modèle MNIST préentraîné avec Microsoft Cognitive Toolkit (CNTK) et exporté au format ONNX.

Le modèle MNIST a déjà été inclus dans votre dossier Ressources, et vous devez l’ajouter à votre application comme un élément existant. Vous pouvez également télécharger le modèle préentraîné à partir du modèle ONNX Zoo sur GitHub.

4. Ajouter le modèle

Cliquez avec le bouton droit sur le dossier Ressources dans l’Explorateur de solutions, puis sélectionnez Ajouter>Élément existant. Pointez le sélecteur de fichiers sur l’emplacement de votre modèle ONNX, puis cliquez sur Ajouter.

Le projet doit désormais comporter deux nouveaux fichiers :

  • mnist.onnx : votre modèle entraîné.
  • mnist.cs : le code généré par Windows ML.

Solution explorer with new files

Pour garantir que le modèle se génère quand nous compilons notre application, cliquez avec le bouton droit sur le fichier mnist.onnx, puis sélectionnez Propriétés. Pour Action de génération, sélectionnez Contenu.

À présent, examinons le code qui vient d’être généré dans le fichier mnist.cs. Nous avons trois classes :

  • mnistModel crée la représentation du modèle Machine Learning, crée une session sur l’appareil par défaut du système, associe les entrées et sorties spécifiques au modèle et évalue le modèle de manière asynchrone.
  • mnistInput initialise les types d’entrée attendus par le modèle. Il s’agit dans ce cas de ImageFeatureValue.
  • mnistOutput initialise les types de sortie générés par le modèle. Dans le cas présent, la sortie est une liste appelée Plus214_Output_0 de type TensorFloat.

Nous allons maintenant utiliser ces classes pour charger, associer et évaluer le modèle dans notre projet.

5. Charger, associer et évaluer le modèle

Pour les applications Windows ML, le modèle à suivre sera le suivant : Charger > Associer > Évaluer.

  1. Chargez le modèle Machine Learning.
  2. Liez les entrées et les sorties au modèle.
  3. Évaluez le modèle et affichez les résultats.

Nous allons utiliser le code d’interface généré dans mnist.cs pour charger, associer et évaluer le modèle dans notre application.

Tout d’abord, dans MainPage.xaml.cs, instancions le modèle, les entrées et les sorties. Ajoutez les variables membres suivantes à la classe MainPage :

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

Ensuite, dans LoadModelAsync, nous allons charger le modèle. Cette méthode doit être appelée avant d’utiliser l’une des méthodes du modèle (autrement dit, sur l’événementLoaded de MainPage, sur un remplacement d’OnNavigatedTo ou n’importe où avant l’appel de recognizeButton_Click). La classe mnistModel représente le modèle MNIST et crée la session sur l’appareil par défaut du système. Pour charger le modèle, nous appelons la méthode CreateFromStreamAsync, en passant le fichier ONNX comme paramètre.

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);
}

Remarque

Si un soulignement en rouge s’affiche sous IRandomAccessStreamReference, vous devez inclure son espace de noms. Placez votre curseur dessus, appuyez sur Ctrl + ., puis sélectionnez en utilisant Windows.Storage.Streams dans le menu déroulant.

Ensuite, nous voulons associer des entrées et des sorties au modèle. Le code généré inclut également des classes wrapper mnistInput et mnistOutput. La classe mnistInput représente les entrées attendues du modèle, et la classe mnistOutput, les sorties attendues du modèle.

Pour initialiser l’objet d’entrée du modèle, appelez le constructeur de classe mnistInput, en passant vos données d’application, et vérifiez que vos données d’entrée correspondent au type d’entrée attendu par votre modèle. La classe mnistInput attend un ImageFeatureValue. Par conséquent, nous utilisons une méthode d’assistance afin d’obtenir un ImageFeatureValue pour l’entrée.

À l’aide de nos fonctions d’assistance incluses dans helper.cs, nous allons copier le contenu de InkCanvas, le convertir au type ImageFeatureValue et l’associer à notre modèle.

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);
}

Pour la sortie, nous appellerons simplement EvaluateAsync avec l’entrée spécifiée. Une fois que vos entrées sont initialisées, appelez la méthode EvaluateAsync du modèle pour évaluer votre modèle sur les données d’entrée. EvaluateAsync associe vos entrées et sorties à l’objet modèle et évalue le modèle sur les entrées.

Dans la mesure où le modèle retourne un tenseur de sortie, nous voulons d’abord le convertir en un type de données convivial, puis analyser la liste retournée pour déterminer quel chiffre présente la probabilité la plus élevée afin de l’afficher.

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();
}

Enfin, nous allons effacer InkCanvas pour permettre aux utilisateurs de dessiner un autre chiffre.

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

6. Lancer l’application

Une fois que nous aurons généré et lancé l’application (en appuyant sur F5), nous serons en mesure de reconnaître un nombre dessiné sur InkCanvas.

complete application

Et voilà, vous avez créé votre première application Windows ML ! Pour obtenir d’autres exemples qui montrent comment utiliser Windows ML, consultez notre dépôt Windows-Machine-Learning sur GitHub.

Remarque

Utilisez les ressources suivantes pour obtenir de l’aide sur Windows ML :

  • Pour poser des questions techniques ou apporter des réponses à des questions techniques sur Windows ML, veuillez utiliser le mot clé windows-machine-learning sur Stack Overflow.
  • Pour signaler un bogue, veuillez signaler un problème dans notre plateforme GitHub.