Partager via


Tutoriel : Entraîner un modèle de classification ML.NET pour catégoriser des images

Découvrez comment entraîner un modèle de classification pour catégoriser des images à l’aide d’un modèle TensorFlow préentraîné pour le traitement d’images.

Le modèle TensorFlow a été entraîné pour classifier des images en mille catégories. Étant donné que le modèle TensorFlow sait reconnaître des modèles dans des images, le modèle ML.NET peut l’utiliser dans son pipeline pour convertir des images brutes en caractéristiques ou en entrées pour entraîner un modèle de classification.

Dans ce tutoriel, vous allez apprendre à :

  • Comprendre le problème
  • Incorporer le modèle TensorFlow préentraîné dans le pipeline ML.NET
  • Entraîner et évaluer le modèle ML.NET
  • Classifier une image de test

Vous trouverez le code source de ce didacticiel dans le référentiel dotnet/samples . Par défaut, la configuration du projet .NET pour ce didacticiel cible .NET Core 2.2.

Prerequisites

Sélectionner la tâche machine learning appropriée

Apprentissage approfondi

Le Deep Learning est un sous-ensemble de Machine Learning, qui révolutionne les domaines tels que la vision par ordinateur et la reconnaissance vocale.

Les modèles d’apprentissage profond sont entraînés à l’aide de grands ensembles de données étiquetées et de réseaux neuronaux qui contiennent plusieurs couches d’apprentissage. Deep Learning :

  • Fonctionne mieux dans certaines tâches telles que la vision par ordinateur.
  • Nécessite d’énormes quantités de données d’apprentissage.

La classification d’images est une tâche de classification spécifique qui nous permet de classifier automatiquement des images en catégories telles que :

  • Détection d’un visage humain dans une image ou non.
  • Détection des chats et des chiens.

Ou comme dans les images suivantes, déterminez si une image est un aliment, un jouet ou un appareil :

image de pizza image d'ours en peluche image grille-pain

Note

Les images précédentes appartiennent à Wiki Commons et sont attribuées comme suit :

L’apprentissage d’un modèle de classification d’images à partir de zéro nécessite la définition de millions de paramètres, une tonne de données d’entraînement étiquetées et une grande quantité de ressources de calcul (centaines d’heures GPU). Bien qu’il ne soit pas aussi efficace que d’entraîner un modèle personnalisé à partir de zéro, l’utilisation d’un modèle préentraîné vous permet de raccourcir ce processus en travaillant avec des milliers d’images par rapport à des millions d’images étiquetées et de créer un modèle personnalisé assez rapidement (dans une heure sur une machine sans GPU). Ce tutoriel simplifie encore davantage le processus en utilisant seulement une douzaine d’images d'entraînement.

Il Inception model est formé pour classer des images dans mille catégories, mais pour ce didacticiel, vous devez classer les images dans un ensemble de catégories plus restreint, uniquement celles-là. Vous pouvez utiliser la Inception modelpossibilité de reconnaître et de classer des images dans les nouvelles catégories limitées de votre classifieur d’images personnalisées.

  • Nourriture
  • Jouet
  • Appareil

Ce tutoriel utilise le modèle D’apprentissage profond TensorFlow Inception , un modèle de reconnaissance d’image populaire formé sur le ImageNet jeu de données. Le modèle TensorFlow classifie des images entières en mille classes, telles que « Umbrella », « Jersey » et « Lave-vaisselle ».

Étant donné que l’image Inception model a déjà été préentraînée sur des milliers d’images différentes, elle contient en interne les fonctionnalités d’image nécessaires à l’identification de l’image. Nous pouvons utiliser ces fonctionnalités d’image internes dans le modèle pour entraîner un nouveau modèle avec beaucoup moins de classes.

Comme illustré dans le diagramme suivant, vous ajoutez une référence aux packages NuGet ML.NET dans vos applications .NET ou .NET Framework. En coulisse, ML.NET inclut et référence la bibliothèque native TensorFlow qui vous permet d’écrire du code qui charge un fichier de modèle préalablement entraîné TensorFlow existant.

Diagramme de transformation TensorFlow ML.NET Arch

Classification multiclasse

Après avoir utilisé le modèle d’inception TensorFlow pour extraire des fonctionnalités adaptées à l’entrée d’un algorithme Machine Learning classique, vous ajoutez un classifieur multiclasse ML.NET.

L’entraîneur spécifique utilisé dans ce cas est l’algorithme de régression logistique multinomiale.

L’algorithme implémenté par ce formateur fonctionne bien sur les problèmes liés à un grand nombre de fonctionnalités, ce qui est le cas pour un modèle d’apprentissage profond fonctionnant sur des données d’image.

Pour plus d’informations, consultez Deep Learning et Machine Learning.

Data

Il existe deux sources de données : le .tsv fichier et les fichiers image. Le tags.tsv fichier contient deux colonnes : la première est définie comme ImagePath et la seconde correspond Label à l’image. L’exemple de fichier suivant n’a pas de ligne d’en-tête et ressemble à ceci :

broccoli.jpg	food
pizza.jpg	food
pizza2.jpg	food
teddy2.jpg	toy
teddy3.jpg	toy
teddy4.jpg	toy
toaster.jpg	appliance
toaster2.png	appliance

Les images d’apprentissage et de test se trouvent dans les dossiers de ressources que vous allez télécharger dans un fichier zip. Ces images appartiennent à Wikimédia Commons.

Wikimédia Commons, le référentiel multimédia gratuit. Récupéré le 10:48, le 17 octobre 2018 à partir de : https://commons.wikimedia.org/wiki/Pizzahttps://commons.wikimedia.org/wiki/Toasterhttps://commons.wikimedia.org/wiki/Teddy_bear

Configuration

Création d’un projet

  1. Créez une application console C# appelée « TransferLearningTF ». Cliquez sur le bouton Suivant .

  2. Choisissez .NET 8 comme framework à utiliser. Cliquez sur le bouton Créer.

  3. Installez le package NuGet Microsoft.ML :

    Note

    Cet exemple utilise la dernière version stable des packages NuGet mentionnés, sauf indication contraire.

    • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Gérer les packages NuGet.
    • Choisissez « nuget.org » comme source du package, sélectionnez l’onglet Parcourir, recherchez Microsoft.ML.
    • Sélectionnez le bouton Installer.
    • Sélectionnez le bouton OK dans la boîte de dialogue Aperçu des modifications .
    • Sélectionnez le bouton J’accepte dans la boîte de dialogue Acceptation de licence si vous acceptez les termes du contrat de licence pour les packages répertoriés.
    • Répétez ces étapes pour Microsoft.ML.ImageAnalytics, SciSharp.TensorFlow.Redist et Microsoft.ML.TensorFlow.

Télécharger des ressources

  1. Téléchargez le fichier zip du répertoire des ressources du projet et décompressez-le.

  2. Copiez le assets répertoire dans votre répertoire de projet TransferLearningTF . Ce répertoire et ses sous-répertoires contiennent les fichiers de données et de support (à l’exception du modèle Inception, que vous allez télécharger et ajouter à l’étape suivante) nécessaires pour ce didacticiel.

  3. Téléchargez le modèle Inception et décompressez-le.

  4. Copiez le contenu du répertoire inception5h que vous venez de décompresser dans le répertoire de projet TransferLearningTFassets/inception. Ce répertoire contient le modèle et les fichiers de support supplémentaires nécessaires pour ce didacticiel, comme illustré dans l’image suivante :

    Contenu du répertoire d’inception

  5. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur chacun des fichiers du répertoire de ressources et sous-répertoires, puis sélectionnez Propriétés. Sous Avancé, modifiez la valeur de Copie dans le répertoire de sortie pour copier si elle est plus récente.

Créer des classes et définir des chemins d’accès

  1. Ajoutez les directives supplémentaires using suivantes en haut du fichier Program.cs :

    using Microsoft.ML;
    using Microsoft.ML.Data;
    
  2. Ajoutez le code suivant à la ligne située en dessous des using directives pour spécifier les chemins d’accès aux ressources :

    string _assetsPath = Path.Combine(Environment.CurrentDirectory, "assets");
    string _imagesFolder = Path.Combine(_assetsPath, "images");
    string _trainTagsTsv = Path.Combine(_imagesFolder, "tags.tsv");
    string _testTagsTsv = Path.Combine(_imagesFolder, "test-tags.tsv");
    string _predictSingleImage = Path.Combine(_imagesFolder, "toaster3.jpg");
    string _inceptionTensorFlowModel = Path.Combine(_assetsPath, "inception", "tensorflow_inception_graph.pb");
    
  3. Créez des classes pour vos données d’entrée et prédictions.

    public class ImageData
    {
        [LoadColumn(0)]
        public string? ImagePath;
    
        [LoadColumn(1)]
        public string? Label;
    }
    

    ImageData est la classe de données d’image d’entrée et comporte les champs suivants String :

    • ImagePath contient le nom du fichier image.
    • Label contient une valeur pour l’étiquette d’image.
  4. Ajoutez une nouvelle classe à votre projet pour ImagePrediction:

    public class ImagePrediction : ImageData
    {
        public float[]? Score;
    
        public string? PredictedLabelValue;
    }
    

    ImagePrediction est la classe de prédiction d’image et comporte les champs suivants :

    • Score contient le pourcentage de confiance pour une classification d’images donnée.
    • PredictedLabelValue contient une valeur pour l’étiquette de classification d’images prédite.

    ImagePrediction est la classe utilisée pour la prédiction après l’apprentissage du modèle. Il a un string (ImagePath) pour le chemin d’accès de l’image. Label est utilisé pour réutiliser et entraîner le modèle. Il PredictedLabelValue est utilisé pendant la prédiction et l’évaluation. Pour l’évaluation, une entrée avec des données d’apprentissage, les valeurs prédites et le modèle sont utilisés.

Initialiser les variables

  1. Initialisez la mlContext variable avec une nouvelle instance de MLContext. Remplacez la Console.WriteLine("Hello World!") ligne par le code suivant :

    MLContext mlContext = new MLContext();
    

    La MLContext classe est un point de départ pour toutes les opérations de ML.NET, et l’initialisation mlContext crée un environnement ML.NET qui peut être partagé entre les objets de flux de travail de création de modèle. Il est similaire, conceptuellement, à DBContext entity Framework.

Créer un struct pour les paramètres de modèle Inception

  1. Le modèle Inception comporte plusieurs paramètres que vous devez transmettre. Créez une structure pour mapper les valeurs des paramètres aux noms faciles à comprendre avec le code suivant, juste après avoir initialisé la variable mlContext.

    struct InceptionSettings
    {
        public const int ImageHeight = 224;
        public const int ImageWidth = 224;
        public const float Mean = 117;
        public const float Scale = 1;
        public const bool ChannelsLast = true;
    }
    

Créer une méthode d’utilitaire d’affichage

Étant donné que vous affichez les données d’image et les prédictions associées plusieurs fois, créez une méthode d’utilitaire d’affichage pour gérer l’affichage de l’image et des résultats de prédiction.

  1. Créez la DisplayResults() méthode, juste après le InceptionSettings struct, à l’aide du code suivant :

    void DisplayResults(IEnumerable<ImagePrediction> imagePredictionData)
    {
    
    }
    
  2. Renseignez le corps de la DisplayResults méthode :

    foreach (ImagePrediction prediction in imagePredictionData)
    {
        Console.WriteLine($"Image: {Path.GetFileName(prediction.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} ");
    }
    

Créer une méthode pour effectuer une prédiction

  1. Créez la ClassifySingleImage() méthode, juste avant la DisplayResults() méthode, à l’aide du code suivant :

    void ClassifySingleImage(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. Créez un ImageData objet qui contient le chemin d’accès complet et le nom du fichier image pour le seul ImagePath. Ajoutez le code suivant comme lignes suivantes dans la ClassifySingleImage() méthode :

    var imageData = new ImageData()
    {
        ImagePath = _predictSingleImage
    };
    
  3. Effectuez une prédiction unique en ajoutant le code suivant comme ligne suivante dans la ClassifySingleImage méthode :

    // Make prediction function (input = ImageData, output = ImagePrediction)
    var predictor = mlContext.Model.CreatePredictionEngine<ImageData, ImagePrediction>(model);
    var prediction = predictor.Predict(imageData);
    

    Pour obtenir la prédiction, utilisez la méthode Predict(). PredictionEngine est une API pratique, qui vous permet d’effectuer une prédiction sur une seule instance de données. PredictionEngine n’est pas thread-safe. Il est acceptable d’utiliser dans des environnements monothreads ou prototypes. Pour améliorer les performances et la sécurité des threads dans les environnements de production, utilisez le PredictionEnginePool service, qui crée un ObjectPool objet PredictionEngine à utiliser dans votre application. Consultez ce guide sur l’utilisation PredictionEnginePool dans une API web ASP.NET Core.

    Note

    PredictionEnginePool l’extension de service est actuellement en préversion.

  4. Affichez le résultat de prédiction comme ligne de code suivante dans la ClassifySingleImage() méthode :

    Console.WriteLine($"Image: {Path.GetFileName(imageData.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} ");
    

Construire le pipeline de modèle ML.NET

Un pipeline de modèle ML.NET est une chaîne d’estimateurs. Aucune exécution ne se produit pendant la construction du pipeline. Les objets estimateur sont créés, mais pas exécutés.

  1. Ajouter une méthode pour générer le modèle

    Cette méthode est le cœur du didacticiel. Il crée un pipeline pour le modèle et entraîne le pipeline pour produire le modèle ML.NET. Il évalue également le modèle par rapport à certaines données de test précédemment invisibles.

    Créez la GenerateModel() méthode, juste après le InceptionSettings struct et juste avant la DisplayResults() méthode, à l’aide du code suivant :

    ITransformer GenerateModel(MLContext mlContext)
    {
    
    }
    
  2. Ajoutez les estimateurs pour charger, redimensionner et extraire les pixels des données d’image :

    IEstimator<ITransformer> pipeline = mlContext.Transforms.LoadImages(outputColumnName: "input", imageFolder: _imagesFolder, inputColumnName: nameof(ImageData.ImagePath))
                    // The image transforms transform the images into the model's expected format.
                    .Append(mlContext.Transforms.ResizeImages(outputColumnName: "input", imageWidth: InceptionSettings.ImageWidth, imageHeight: InceptionSettings.ImageHeight, inputColumnName: "input"))
                    .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "input", interleavePixelColors: InceptionSettings.ChannelsLast, offsetImage: InceptionSettings.Mean))
    

    Les données d’image doivent être traitées au format attendu par le modèle TensorFlow. Dans ce cas, les images sont chargées en mémoire, redimensionnées à une taille cohérente et les pixels sont extraits dans un vecteur numérique.

  3. Ajouter l’estimateur pour charger le modèle TensorFlow et l’évaluer :

    .Append(mlContext.Model.LoadTensorFlowModel(_inceptionTensorFlowModel).
        ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))
    

    Cette étape du pipeline charge le modèle TensorFlow en mémoire, puis traite le vecteur de valeurs de pixels via le réseau de modèle TensorFlow. L’application d’entrées à un modèle d’apprentissage profond et la génération d’une sortie à l’aide du modèle est appelée Scoring. Lorsque vous utilisez le modèle dans son intégralité, l'évaluation effectue une inférence ou une prédiction.

    Dans ce cas, vous utilisez tout le modèle TensorFlow à l’exception de la dernière couche, qui est la couche qui effectue l’inférence. La sortie de la dernière couche est étiquetée softmax_2_preactivation. La sortie de cette couche est effectivement un vecteur de caractéristiques qui caractérisent les images d’entrée d’origine.

    Ce vecteur de fonctionnalité généré par le modèle TensorFlow sera utilisé comme entrée à un algorithme d’entraînement ML.NET.

  4. Ajoutez l’estimateur pour associer les étiquettes de chaînes de caractères dans les données d’apprentissage aux valeurs de clés entières.

    .Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelKey", inputColumnName: "Label"))
    

    Le formateur ML.NET suivant nécessite que ses étiquettes soient au format key, plutôt que dans des chaînes arbitraires. Une clé est un nombre qui a une correspondance un à un avec une valeur textuelle.

  5. Ajoutez l’algorithme d’entraînement ML.NET :

    .Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelKey", featureColumnName: "softmax2_pre_activation"))
    
  6. Ajoutez l’estimateur pour convertir la valeur clé prédite en une chaîne :

    .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabelValue", "PredictedLabel"))
    .AppendCacheCheckpoint(mlContext);
    

Entraîner le modèle

  1. Chargez les données d’entraînement à l’aide du wrapper LoadFromTextFile . Ajoutez le code suivant comme ligne suivante dans la GenerateModel() méthode :

    IDataView trainingData = mlContext.Data.LoadFromTextFile<ImageData>(path:  _trainTagsTsv, hasHeader: false);
    

    Les données de ML.NET sont représentées sous forme d’interface IDataView. IDataView est un moyen flexible et efficace de décrire les données tabulaires (numériques et textuelles). Les données peuvent être chargées à partir d’un fichier texte ou en temps réel (par exemple, des fichiers de base de données SQL ou des fichiers journaux) dans un IDataView objet.

  2. Entraîner le modèle avec les données chargées ci-dessus :

    ITransformer model = pipeline.Fit(trainingData);
    

    La Fit() méthode entraîne votre modèle en appliquant le jeu de données d’entraînement au pipeline.

Évaluer la précision du modèle

  1. Chargez et transformez les données de test en ajoutant le code suivant à la ligne suivante de la GenerateModel méthode :

    IDataView testData = mlContext.Data.LoadFromTextFile<ImageData>(path: _testTagsTsv, hasHeader: false);
    IDataView predictions = model.Transform(testData);
    
    // Create an IEnumerable for the predictions for displaying results
    IEnumerable<ImagePrediction> imagePredictionData = mlContext.Data.CreateEnumerable<ImagePrediction>(predictions, true);
    DisplayResults(imagePredictionData);
    

    Il existe quelques exemples d’images que vous pouvez utiliser pour évaluer le modèle. Comme les données d’apprentissage, celles-ci doivent être chargées dans un IDataView, afin qu’elles puissent être transformées par le modèle.

  2. Ajoutez le code suivant à la GenerateModel() méthode pour évaluer le modèle :

    MulticlassClassificationMetrics metrics =
        mlContext.MulticlassClassification.Evaluate(predictions,
            labelColumnName: "LabelKey",
            predictedLabelColumnName: "PredictedLabel");
    

    Une fois le jeu de prédictions défini, la méthode Evaluate() :

    • Évalue le modèle (compare les valeurs prédites avec le jeu de données labelsde test).
    • Retourne les métriques de performances du modèle.
  3. Afficher les métriques de précision du modèle

    Utilisez le code suivant pour afficher les métriques, partager les résultats, puis agir dessus :

    Console.WriteLine($"LogLoss is: {metrics.LogLoss}");
    Console.WriteLine($"PerClassLogLoss is: {String.Join(" , ", metrics.PerClassLogLoss.Select(c => c.ToString()))}");
    

    Les métriques suivantes sont évaluées pour la classification d’images :

    • Log-loss - voir Perte de journal. Vous souhaitez que la perte de journal soit aussi proche de zéro que possible.
    • Per class Log-loss. Vous souhaitez que la perte de journal par classe soit aussi proche de zéro que possible.
  4. Ajoutez le code suivant pour retourner le modèle entraîné comme ligne suivante :

    return model;
    

Exécuter l’application

  1. Ajoutez l’appel après GenerateModel la création de la MLContext classe :

    ITransformer model = GenerateModel(mlContext);
    
  2. Ajoutez l’appel à la ClassifySingleImage() méthode après l’appel à la GenerateModel() méthode :

    ClassifySingleImage(mlContext, model);
    
  3. Exécutez votre application console (Ctrl + F5). Vos résultats doivent être similaires à la sortie suivante. (Vous pouvez voir les avertissements ou le traitement des messages, mais ces messages ont été supprimés des résultats suivants pour plus de clarté.)

    =============== Training classification model ===============
    Image: broccoli2.jpg predicted as: food with score: 0.8955513
    Image: pizza3.jpg predicted as: food with score: 0.9667718
    Image: teddy6.jpg predicted as: toy with score: 0.9797683
    =============== Classification metrics ===============
    LogLoss is: 0.0653774699265059
    PerClassLogLoss is: 0.110315812569315 , 0.0204391272836966 , 0
    =============== Making single image classification ===============
    Image: toaster3.jpg predicted as: appliance with score: 0.9646884
    

Félicitations! Vous avez maintenant créé un modèle de classification dans ML.NET pour catégoriser des images à l’aide d’un TensorFlow préentraîné pour le traitement d’images.

Vous trouverez le code source de ce didacticiel dans le référentiel dotnet/samples .

Dans ce didacticiel, vous avez appris à :

  • Comprendre le problème
  • Incorporer le modèle TensorFlow préentraîné dans le pipeline ML.NET
  • Entraîner et évaluer le modèle ML.NET
  • Classifier une image de test

Consultez le référentiel GitHub d’exemples Machine Learning pour explorer un exemple de classification d’images développé.