Partager via


Déployer votre modèle d’analyse des données dans une application Windows avec des API Windows ML

Dans la partie précédente de ce tutoriel, vous avez appris à créer et à exporter un modèle au format ONNX. À présent, nous allons vous montrer comment incorporer votre modèle exporté dans une application Windows et l’exécuter localement sur un appareil en appelant des API Windows ML.

Lorsque vous aurez terminé, vous disposerez d’une application d’analyse des données opérationnelle.

À propos de l’exemple d’application

Dans cette étape du tutoriel, vous allez créer une application qui peut analyser les données tabulaires relatives aux iris. Cette application vous permet d’ajouter le fichier Excel avec les informations d’entrée requises ou d’entrer manuellement les paramètres d’entrée, à savoir la longueur et la largeur (en cm) des sépales et des pétales des iris. Ces caractéristiques sont ensuite traitées par un modèle ONNX de réseau neuronal stocké localement que vous avez créé et entraîné dans la partie précédente. En se basant sur la sortie du modèle, l’application affiche le type d’iris exact.

Ici, nous allons vous guider tout au long de ce processus.

Remarque

Si vous choisissez d’utiliser l’exemple de code prédéfini, vous pouvez cloner le fichier solution. Clonez le dépôt, accédez à cet exemple et ouvrez le fichier Iris Data Analysis.csproj avec Visual Studio. Passez à la partie Lancer l’application de cette page pour la voir en cours d’utilisation.

Ci-dessous, nous allons vous guider dans la création de votre application et l’ajout de code Windows ML.

Créer une application de bureau Windows ML (en C#)

Pour créer une application Windows ML fonctionnelle, vous devez effectuer les opérations suivantes :

  • Charger un modèle Machine Learning.
  • Lier les entrées et les sorties du modèle.
  • Évaluer le modèle et afficher des résultats significatifs.

Vous devez également créer une interface utilisateur simple pour améliorer l’expérience utilisateur.

Ouvrez un nouveau projet dans Visual Studio.

  1. C’est parti. Ouvrez Visual Studio et choisissez Create a new project.

Create new Visual Studio project

  1. Dans la barre de recherche, choisissez C# comme langage, Windows comme plateforme cible et Dektop comme type de projet. Sélectionnez le type de projet NUnit Test Project (.NET Core) et sélectionnez next pour ouvrir une fenêtre de configuration du projet.

Create new NUnit Test Project app

  1. Dans la fenêtre de configuration, suivez les étapes ci-dessous :
  • Nommez votre projet. Ici, nous l’appellerons Iris Data Analysis.
  • Choisissez l’emplacement du projet.
  • Si vous utilisez VS 2019, vérifiez que la case Create directory for solution est cochée.
  • Si vous utilisez VS2017, vérifiez que la case Place solution and project in the same directory n’est pas cochée.

Appuyez sur create pour créer votre projet. La fenêtre version cible minimale peut s’afficher. Assurez-vous que la version minimale est définie sur Windows 10 version 1809 (10.0, build 17763) ou ultérieure.

  1. Une fois le projet créé, accédez au dossier du projet, ouvrez le dossier des ressources [….\DataClassifier\Assets], puis copiez votre fichier Network.onnx à cet emplacement.

Explorer la solution de projet

Explorons votre solution de projet.

Visual Studio a créé automatiquement plusieurs fichiers cs-code à l’intérieur de l’Explorateur de solutions. MainPage.xaml contient le code XAML pour votre interface utilisateur graphique et MainPage.xaml.cs contient le code de votre application. Si vous avez déjà créé une application UWP, ces fichiers doivent vous être familiers.

Nous avons ajouté le fichier Network.onnx dans le dossier des ressources (Assets), mais nous devons maintenant l’ajouter correctement à ce projet.

  1. Cliquez avec le bouton droit sur le dossier Assets dans l’Explorateur de solutions, puis sélectionnez Add > Existing Item.
  2. Accédez au dossier Assets dans Iris Data Analysis [….\Iris Data Analysis \Assets], recherchez le modèle Network.onnx model que vous avez copié précédemment, puis sélectionnez Add.
  3. Pour vous assurer que le modèle se génère bien quand vous compilez l’application, cliquez avec le bouton droit sur le fichier Network.onnx et sélectionnez Properties. Définissez la propriété Build Action sur Content.

Vous devez également créer un fichier de classe cs-code qui contiendra le code Machine Learning supplémentaire, notamment les classes et les méthodes qui appelleront les API Windows ML.

  1. Cliquez avec le bouton droit sur le nom de la solution dans Visual Studio, puis choisissez add et new item. Dans la fenêtre ouverte, sélectionnez Class et nommez le fichier, par exemple IrisModel.cs ici. Un nouveau fichier de classe apparaît sous votre projet.

Add a new class file to your VS project.

Créer le code Machine Learning

Dans cette étape, nous allons créer toutes les classes et méthodes qui appelleront les API Windows Machine Learning (Windows ML). Ces éléments vous permettront de charger, de lier et d’évaluer un modèle Machine Learning ONNX dans votre projet.

  1. Double-cliquez sur le fichier IrisModel.cs.

  2. Remplacez les instructions using par les instructions suivantes pour accéder à toutes les API dont vous avez besoin.

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

Initialiser les classes Machine Learning

Nous devons ajouter plusieurs classes à IrisModel.cs pour vous aider à interagir avec les API Windows ML.

Pour accéder au modèle Machine Learning entraîné, nous utilisons la classe LearningModel. Cette classe fait partie de l’espace de noms Windows.AI.MachineLearning et représente un modèle Machine Learning entraîné. Une fois instanciée, la classe LearningModel est le principal objet à utiliser pour interagir avec les API Windows ML.

Pour évaluer le modèle d’entraînement, vous devez créer une session d’évaluation. Pour ce faire, vous utilisez la classe LearningModelSession. Cette classe est utilisée pour évaluer les modèles Machine Learning, et lie le modèle à un dispositif qui exécute et évalue ensuite le modèle. Lorsque vous créez une session avec cette API, vous pouvez également sélectionner le dispositif qui exécute votre modèle (par défaut, c’est votre CPU).

De plus, vous devez spécifier les étiquettes de la sortie de vos modèles Machine Learning. Vous pourrez lier ces étiquettes à la sortie prédite du modèle ultérieurement.

Remarque

Pour en savoir plus sur les classes LearningModel et LearningModelSession, consultez la documentation de la classe LearningModel et la documentation de la classe LearningModelSession.

  1. Copiez le code suivant dans le fichier IrisModel.cs.
class IrisModel
    {
        private LearningModel _learning_model;
        private LearningModelSession _session;
        private String[] _labels = { "Iris-setosa", "Iris-versicolor", "Iris-virginica"};

Charger le modèle

Vous devez maintenant charger le modèle Machine Learning et créer une session, ce que vous allez faire en utilisant les classes que vous venez de définir. Pour charger le modèle, vous pouvez utiliser plusieurs méthodes statiques de la classe LearningModel. Dans notre exemple, nous utilisons la méthode LoadFromStorageFileAsync, qui vous permet de charger un modèle ONNX à partir d’un ISorageFile de façon asynchrone.

Remarque

Pour en savoir plus sur les autres méthodes de chargement du modèle, consultez Charger un modèle.

  1. Copiez le code suivant dans le fichier IrisModel.cs.
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);
}

Définir le tenseur d’entrée du modèle

À présent, nous allons définir les valeurs d’entrée appropriées pour votre modèle. Le modèle de réseau que vous avez créé dans la partie précédente a quatre valeurs d’entrée. Chaque valeur d’entrée représente la taille possible de quatre caractéristiques des iris : la longueur des sépales en cm (sepal length in cm), la largeur des sépales en cm (sepal width in cm), la longueur des pétales en cm (petal length in cm) et la largeur des pétales en cm (petal width in cm). Sur la base de cette entrée, le modèle retourne le type d’iris qui se rapproche le plus de ces caractéristiques. Veillez à limiter la taille des valeurs d’entrée aux seules valeurs logiques valides. Pour ce tutoriel, nous utilisons les valeurs suivantes :

  • sepal length : 1 cm à 100 cm
  • sepal width : 1 cm à 8 cm
  • petal length : 0,5 cm à 10 cm
  • petal width : 0,1 cm à 5 cm
  1. Copiez le code suivant dans le fichier IrisModel.cs.
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;
        }
    }
}

Les API Windows ML acceptent les valeurs d’entrée des quatre classes descriptives prises en charge par les modèles ONNX : tenseurs, séquences, cartes et images. Dans ce cas, le modèle a besoin d’un objet tenseur de type float 32 bits sous la forme float32[batch_size,4]. Sachant que la taille du lot est 1, le tenseur d’entrée a la forme [1x4].

Pour créer une entrée tenseur, vous utiliserez la classe TensorFloat.

La classe TensorFloat fait partie de l’espace de noms Windows.AI.MachineLearning ; elle sert à définir un objet tenseur float 32 bits, qui est un tenseur de valeurs à virgule flottante de 32 bits. Cette classe contient plusieurs méthodes utiles pour créer un tenseur. Dans votre cas, vous utiliserez la méthode CreateFromArray pour créer une entrée tenseur de la taille exacte requise par votre modèle. Nous ajouterons cet appel dans la méthode d’évaluation.

Lier et évaluer le modèle

Maintenant que vous avez défini le tenseur d’entrée du modèle, et instancié le modèle entraîné et la session, il est temps de créer une méthode pour lier et évaluer le modèle Machine Learning entraîné.

Cette méthode est l’élément clé d’une application Machine Learning. Elle fournit la tenseurisation des valeurs d’entrée et la liaison de l’entrée du modèle. Plus tard, vous utiliserez ce modèle dans le code de votre application pour évaluer votre modèle.

La classe LearningModelBinding permet de lier une entrée et une sortie. Un modèle Machine Learning a des caractéristiques d’entrée et de sortie, qui transmettent des informations dans et hors du modèle. Sachez que les caractéristiques requises doivent être prises en charge par les API Windows ML. La classe LearningModelBinding est appliquée sur un LearningModelSession pour lier des valeurs aux fonctionnalités d’entrée et de sortie nommées.

La classe LearningModelBinding comporte plusieurs méthodes prédéfinies qui vous permettent de lier des valeurs à ces caractéristiques nommées. Ici, vous utiliserez la méthode Bind pour lier des valeurs à votre modèle.

Pour évaluer le modèle et obtenir les résultats de l’évaluation, vous appelez les méthodes d’évaluation prédéfinies pertinentes à partir de LearningModelSession (dans votre cas, la méthode Evaluate). Cette méthode fournit les fonctionnalités dont vous avez besoin, en évaluant le modèle Machine Learning par rapport aux valeurs de caractéristiques fournies par la classe LearningModelBinding.

Remarque

Pour en savoir plus sur les autres méthodes d’évaluation en vue d’exécuter le modèle, vérifiez les méthodes qui peuvent être implémentées sur le LearningModelSession en consultant la documentation de la classe LearningModelSession.

Extraire et afficher les résultats

Le modèle retourne les valeurs prédites sous la forme d’une sortie de tenseur au format float. Vous devez maintenant extraire la sortie du modèle et afficher les résultats appropriés. Pour cela, vous convertissez le format du tenseur en vecteur en exécutant la fonction GetAsVectorView() sur la sortie prédite.

Le modèle retourne trois valeurs de probabilité, chacune représentant un type d’iris spécifique. Vous devez retourner l’étiquette ayant la probabilité la plus élevée.

  1. Copiez le code suivant dans le fichier IrisModel.cs.
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);
}

Vous avez terminé la partie Machine Learning de votre code. À présent, vous pouvez facilement intégrer votre modèle à l’application Windows. Dans la dernière partie de ce tutoriel, nous avons fourni une interface utilisateur graphique Windows simple et le code de contrôle pour tester le modèle, en utilisant les méthodes que vous aviez déjà créées.

Créer l’interface graphique utilisateur de l’application

  1. Pour créer le code de l’interface graphique utilisateur de votre application, double-cliquez sur le fichier de code MainPage.xaml et ouvrez un modèle prédéfini pour votre interface utilisateur graphique.

  2. Copiez-collez le code ci-dessous dans MainPage.xaml, sous la ligne “Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" " Height="939">.

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

Créer le code de contrôle de l’application

Le code de contrôle de l’application, MainPage.xaml.cs, comprend la méthode principale qui exécute l’application ainsi que les différentes étapes pour exécuter votre modèle et afficher la sortie :

  1. Vous allez instancier un nouvel objet de la classe IrisModel que vous avez créée précédemment dans ce tutoriel.
  2. Vous allez appeler la méthode Evaluate() que vous avez créée dans la partie précédente du modèle. Cette méthode sera appliquée quatre fois, une fois sur chacun des paramètres d’entrée : sepal length, sepal width, petal length et petal width.

L’application affichera le résultat obtenu de l’algorithme de prédiction Machine Learning.

  1. Pour créer un code de contrôle d’application, double-cliquez sur le fichier de code MainPage.xaml.cs et ajoutez le code suivant.
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();
            }
        }
    }
}

Lancer l’application

Vous êtes maintenant prêt à lancer votre application et à voir le résultat.

Activez le mode développeur et testez votre application à partir de Visual Studio. Assurez-vous que les menus déroulants de la barre d’outils supérieure sont définis sur Debug. 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.

L’interface graphique utilisateur de l’application comprend quatre curseurs permettant de changer l’entrée des paramètres requis. Tout changement apporté à l’entrée générera une nouvelle sortie basée sur l’algorithme de prédiction. La sortie s’affiche sous les curseurs d’entrée.

Comme vous pouvez le voir, avec l’entrée sepal length = 40mm, sepal width = 50, petal length = 75 et petal width = 15, l’application a généré l’entrée du type Iris-versicolor !

Successful classification in your app

Résumé

Vous venez de créer votre première application Windows Machine Learning, de la création du modèle à l’exécution réussie de l’application.

Ressources complémentaires

Pour en savoir plus sur les rubriques mentionnées dans ce tutoriel, consultez les ressources suivantes :