Tutorial: Automatisierte visuelle Überprüfung mithilfe von Transferlernen mit der ML.NET-Bildklassifizierungs-APITutorial: Automated visual inspection using transfer learning with the ML.NET Image Classification API

Erfahren Sie, wie Sie ein benutzerdefiniertes Deep-Learning-Modell mithilfe von Transferlernen, einem vorab trainierten TensorFlow-Modell und der ML.NET-Bildklassifizierungs-API trainieren, um Bilder von Betonoberflächen als gerissen oder nicht gerissen zu klassifizieren.Learn how to train a custom deep learning model using transfer learning, a pretrained TensorFlow model and the ML.NET Image Classification API to classify images of concrete surfaces as cracked or uncracked.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:In this tutorial, you learn how to:

  • Das Problem verstehenUnderstand the problem
  • Informationen zur ML.NET-Bildklassifizierungs-APILearn about ML.NET Image Classification API
  • Grundlegendes zum vorab trainierten ModellUnderstand the pretrained model
  • Trainieren eines benutzerdefinierten TensorFlow-Bildklassifizierungsmodells mithilfe von TransferlernenUse transfer learning to train a custom TensorFlow image classification model
  • Klassifizieren von Bildern mit dem benutzerdefinierten ModellClassify images with the custom model

Erforderliche KomponentenPrerequisites

Beispielübersicht zur Bildklassifizierung mit TransferlernenImage classification transfer learning sample overview

Bei diesem Beispiel handelt es sich um eine C#.NET Core-Konsolenanwendung, die Bilder mit einem vorab mit Deep Learning trainierten TensorFlow-Modell klassifiziert.This sample is a C# .NET Core console application that classifies images using a pretrained deep learning TensorFlow model. Den Code für dieses Beispiel finden Sie im dotnet/machinelearning-Beispielrepository auf GitHub.The code for this sample can be found on the dotnet/machinelearning-samples repository on GitHub.

Das Problem verstehenUnderstand the problem

Bildklassifizierung ist ein Problem des maschinellen Sehens.Image classification is a computer vision problem. Bei der Bildklassifizierung wird ein Bild eingegeben, das dann in eine bestimmte Klasse eingeordnet wird.Image classification takes an image as input and categorizes it into a prescribed class. Die Bildklassifizierung kann zum Beispiel in diesen Szenarios hilfreich sein:Some scenarios where image classification is useful include:

  • GesichtserkennungFacial recognition
  • EmotionserkennungEmotion detection
  • Medizinische DiagnoseMedical diagnosis
  • OrientierungspunkterkennungLandmark detection

In diesem Tutorial wird ein benutzerdefiniertes Bildklassifizierungsmodell trainiert, um eine automatisierte visuelle Überprüfung von Brückenbelägen durchzuführen, bei der durch Risse unterbrochene Strukturen identifiziert werden.This tutorial trains a custom image classification model to perform automated visual inspection of bridge decks to identify structures that are damaged by cracks.

ML.NET-Bildklassifizierungs-APIML.NET Image Classification API

ML.NET bietet verschiedene Methoden zum Durchführen einer Bildklassifizierung.ML.NET provides various ways of performing image classification. In diesem Tutorial wird die Methode des Transferlernens unter Verwendung der Bildklassifizierungs-API angewendet.This tutorial applies transfer learning using the Image Classification API. Die Bildklassifizierungs-API nutzt TensorFlow.NET, eine Low-Level-Bibliothek, die C#-Bindungen für die TensorFlow-C++-API bereitstellt.The Image Classification API makes use of TensorFlow.NET, a low-level library that provides C# bindings for the TensorFlow C++ API.

Was ist Übertragungslernen?What is transfer learning?

Beim Transferlernen werden Erkenntnisse aus der Lösung eines Problems für ein anderes verwandtes Problem genutzt.Transfer learning applies knowledge gained from solving one problem to another related problem.

Das von Grund auf neue Trainieren eines Deep-Learning-Modells erfordert das Festlegen mehrerer Parameter, zahlreiche bezeichnete Trainingsdaten und eine große Menge an Computeressourcen (Hunderte von GPU-Stunden).Training a deep learning model from scratch requires setting several parameters, a large amount of labeled training data, and a vast amount of compute resources (hundreds of GPU hours). Die Verwendung eines vorab trainierten Modells zusammen mit dem Transferlernen ermöglicht es Ihnen, den Trainingsprozess zu verkürzen.Using a pretrained model along with transfer learning allows you to shortcut the training process.

TrainingsprozessTraining process

Die Bildklassifizierungs-API startet den Trainingsprozess, indem das vorab trainierte TensorFlow-Modell geladen wird.The Image Classification API starts the training process by loading a pretrained TensorFlow model. Der Trainingsprozess setzt sich aus zwei Schritten zusammen:The training process consists of two steps:

  1. EngpassphaseBottleneck phase
  2. TrainingsphaseTraining phase

Trainingsschritte

EngpassphaseBottleneck phase

Während der Engpassphase werden die Trainingsbilder geladen, wobei die Pixelwerte als Eingabe dienen, oder aber Features für die fixierten Ebenen des vorab trainierten Modells.During the bottleneck phase, the set of training images is loaded and the pixel values are used as input, or features, for the frozen layers of the pretrained model. Die fixierten Ebenen umfassen sämtliche Ebenen im neuronalen Netz bis hin zur vorletzte Ebene, die inoffiziell auch als Engpassebene bezeichnet wird.The frozen layers include all of the layers in the neural network up to the penultimate layer, informally known as the bottleneck layer. Diese Ebenen werden „fixiert“ genannt, da für diese kein Training stattfindet und Vorgänge lediglich weitergegeben werden.These layers are referred to as frozen because no training will occur on these layers and operations are pass-through. In diesen fixierten Ebenen werden die zugrunde liegenden Muster berechnet, anhand derer ein Modell zwischen den verschiedenen Klassen unterscheidet.It's at these frozen layers where the lower-level patterns that help a model differentiate between the different classes are computed. Je mehr Ebenen es gibt, desto rechenintensiver ist dieser Schritt.The larger the number of layers, the more computationally intensive this step is. Da es sich hierbei um eine einmalige Berechnung handelt, können die Ergebnisse zwischengespeichert und in späteren Durchläufen verwendet werden, wenn mit verschiedenen Parametern experimentiert wird.Fortunately, since this is a one-time calculation, the results can be cached and used in later runs when experimenting with different parameters.

TrainingsphaseTraining phase

Sobald die Ausgabewerte aus der Engpassphase berechnet sind, dienen sie als Eingabe für das nochmalige Training der letzten Ebene des Modells.Once the output values from the bottleneck phase are computed, they are used as input to retrain the final layer of the model. Dieser Prozess ist iterativ und wird so oft ausgeführt, wie durch Modellparameter angegeben ist.This process is iterative and runs for the number of times specified by model parameters. Bei jeder Ausführung werden Verlust und Genauigkeit ausgewertet.During each run, the loss and accuracy are evaluated. Anschließend werden die entsprechenden Anpassungen zur Verbesserung des Modells vorgenommen, um so den Verlust zu minimieren und die Genauigkeit zu maximieren.Then, the appropriate adjustments are made to improve the model with the goal of minimizing the loss and maximizing the accuracy. Nach Abschluss des Trainings verfügen Sie über zwei Modellformate.Once training is finished, two model formats are output. Eines wird als .pb-Version des Modells und das andere als für ML.NET serialisierte .zip-Version des Modells bezeichnet.One of them is the .pb version of the model and the other is the .zip ML.NET serialized version of the model. Für die Arbeit in von ML.NET unterstützten Umgebungen wird die .zip-Version des Modells empfohlen.When working in environments supported by ML.NET, it is recommended to use the .zip version of the model. In Umgebungen, in denen ML.NET nicht unterstützt wird, haben Sie jedoch die Möglichkeit, die .pb-Version zu verwenden.However, in environments where ML.NET is not supported, you have the option of using the .pb version.

Grundlegendes zum vorab trainierten ModellUnderstand the pretrained model

Das in diesem Tutorial verwendete vorab trainierte Modell ist die 101-Ebenen-Variante des Modells „Residual Network (ResNet) v2“.The pretrained model used in this tutorial is the 101-layer variant of the Residual Network (ResNet) v2 model. Das Originalmodell ist darauf trainiert, Bilder in tausend Kategorien einzuteilen.The original model is trained to classify images into a thousand categories. Das Modell verwendet ein Bild der Größe 224 × 224 als Eingabe und gibt die Klassenwahrscheinlichkeiten für jede der Klassen aus, für die es trainiert ist.The model takes as input an image of size 224 x 224 and outputs the class probabilities for each of the classes it's trained on. Ein Teil dieses Modells wird verwendet, um ein neues Modell mit benutzerdefinierten Bildern zu trainieren, damit dieses Vorhersagen für zwei Klassen treffen kann.Part of this model is used to train a new model using custom images to make predictions between two classes.

Erstellen einer KonsolenanwendungCreate console application

Nachdem Sie nun grundlegende Kenntnisse über das Transferlernen und die Bildklassifizierungs-API haben, ist es an der Zeit, die Anwendung zu erstellen.Now that you have a general understanding of transfer learning and the Image Classification API, it's time to build the application.

  1. Erstellen Sie eine .NET Core-Konsolenanwendung in C# namens „DeepLearning_ImageClassification_Binary“.Create a C# .NET Core Console Application called "DeepLearning_ImageClassification_Binary".
  2. Installieren Sie das NuGet-Paket Microsoft.ML, Version 1.4.0:Install the Microsoft.ML version 1.4.0 NuGet Package:
    1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie NuGet-Pakete verwalten aus.In Solution Explorer, right-click on your project and select Manage NuGet Packages.
    2. Wählen Sie als Paketquelle „nuget.org“ aus.Choose "nuget.org" as the Package source.
    3. Wählen Sie die Registerkarte Durchsuchen aus.Select the Browse tab.
    4. Aktivieren Sie das Kontrollkästchen Vorabversion einbeziehen.Check the Include prerelease checkbox.
    5. Suchen Sie nach Microsoft.ML.Search for Microsoft.ML.
    6. Wählen Sie die Schaltfläche Installieren aus.Select the Install button.
    7. Wählen Sie die Schaltfläche OK im Dialogfeld Vorschau der Änderungen und dann die Schaltfläche Ich stimme zu im Dialogfeld Zustimmung zur Lizenz aus, wenn Sie den Lizenzbedingungen für die aufgelisteten Pakete zustimmen.Select the OK button on the Preview Changes dialog and then select the I Accept button on the License Acceptance dialog if you agree with the license terms for the packages listed.
    8. Wiederholen Sie diese Schritte für die NuGet-Pakete Microsoft.ML.Vision, Version 1.4.0, SciSharp.TensorFlow.Redist, Version 1.15.0 und Microsoft.ML.ImageAnalytics, Version 1.4.0.Repeat these steps for the Microsoft.ML.Vision version 1.4.0, SciSharp.TensorFlow.Redist version 1.15.0, and Microsoft.ML.ImageAnalytics version 1.4.0 NuGet packages.

Vorbereiten und Verstehen der DatenPrepare and understand the data

Hinweis

Die Datasets für dieses Tutorial stammen von Marc Maguire, Sattar Dorafshan und Robert J. Thomas, „SDNET2018: A concrete crack image dataset for machine learning applications“ (2018).The datasets for this tutorial are from Maguire, Marc; Dorafshan, Sattar; and Thomas, Robert J., "SDNET2018: A concrete crack image dataset for machine learning applications" (2018). Durchsuchen Sie alle Datasets.Browse all Datasets. Dokument 48.Paper 48. https://digitalcommons.usu.edu/all_datasets/48https://digitalcommons.usu.edu/all_datasets/48

SDNET2018 ist ein Bilddataset, das Anmerkungen für gerissene und nicht gerissene Betonstrukturen (Brückenbeläge, Mauern und Gehwege) enthält.SDNET2018 is an image dataset that contains annotations for cracked and non-cracked concrete structures (bridge decks, walls, and pavement).

Beispiele für Brückenbeläge des SDNET2018-Datasets

Die Daten sind in drei Unterverzeichnissen organisiert:The data is organized in three subdirectories:

  • D enthält Bilder von BrückenbelägenD contains bridge deck images
  • P enthält Bilder von GehwegenP contains pavement images
  • W enthält Bilder von MauernW contains wall images

Jedes dieser Unterverzeichnisse enthält zwei zusätzliche Unterverzeichnisse mit Präfixen:Each of these subdirectories contains two additional prefixed subdirectories:

  • C ist das Präfix für gerissene OberflächenC is the prefix used for cracked surfaces
  • U ist das Präfix für nicht gerissene OberflächenU is the prefix used for uncracked surfaces

In diesem Tutorial werden ausschließlich Bilder von Brückenbelägen verwendet.In this tutorial, only bridge deck images are used.

  1. Laden Sie das Dataset herunter, und entpacken Sie es.Download the dataset and unzip.
  2. Erstellen Sie in Ihrem Projekt ein Verzeichnis mit dem Namen „assets“, um darin die Datasetdateien zu speichern.Create a directory named "assets" in your project to save your dataset files.
  3. Kopieren Sie die Unterverzeichnisse CD und UD aus dem zuletzt entpackten Verzeichnis in das Verzeichnis assets.Copy the CD and UD subdirectories from the recently unzipped directory to the assets directory.

Erstellen von Eingabe- und AusgabeklassenCreate input and output classes

  1. Öffnen Sie die Datei Program.cs, und ersetzen Sie die vorhandenen using-Anweisungen am Anfang der Datei durch die folgenden Anweisungen:Open the Program.cs file and replace the existing using statements at the top of the file with the following:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    using Microsoft.ML;
    using static Microsoft.ML.DataOperationsCatalog;
    using Microsoft.ML.Vision;
    
  2. Erstellen Sie in der Datei Program.cs unter der Program-Klasse eine Klasse mit dem Namen ImageData.Below the Program class in Program.cs, create a class called ImageData. Diese Klasse wird verwendet, um die ursprünglich geladenen Daten darzustellen.This class is used to represent the initially loaded data.

    class ImageData
    {
        public string ImagePath { get; set; }
    
        public string Label { get; set; }
    }
    

    ImageData enthält die folgenden Eigenschaften:ImageData contains the following properties:

    • ImagePath ist der vollqualifizierte Pfad, in dem das Bild gespeichert ist.ImagePath is the fully qualified path where the image is stored.
    • Label ist die Kategorie, zu der das Bild gehört.Label is the category the image belongs to. Dies ist der vorherzusagende Wert.This is the value to predict.
  3. Erstellen Sie Klassen für Ihre Eingabe- und Ausgabedaten.Create classes for your input and output data

    1. Definieren Sie unter der ImageData-Klasse das Schema Ihrer Eingabedaten in einer neuen Klasse namens ModelInput.Below the ImageData class, define the schema of your input data in a new class called ModelInput.

      class ModelInput
      {
          public byte[] Image { get; set; }
          
          public UInt32 LabelAsKey { get; set; }
      
          public string ImagePath { get; set; }
      
          public string Label { get; set; }
      }
      

      ModelInput enthält die folgenden Eigenschaften:ModelInput contains the following properties:

      • ImagePath ist der vollqualifizierte Pfad, in dem das Bild gespeichert ist.ImagePath is the fully qualified path where the image is stored.
      • Label ist die Kategorie, zu der das Bild gehört.Label is the category the image belongs to. Dies ist der vorherzusagende Wert.This is the value to predict.
      • Image ist die byte[]-Darstellung des Bilds.Image is the byte[] representation of the image. Bei dem Modell wird erwartet, dass Bilddaten diesen Typ für das Training aufweisen.The model expects image data to be of this type for training.
      • LabelAsKey ist die numerische Darstellung von Label.LabelAsKey is the numerical representation of the Label.

      Nur Image und LabelAsKey werden verwendet, um das Modell zu trainieren und Vorhersagen zu treffen.Only Image and LabelAsKey are used to train the model and make predictions. Die Eigenschaften ImagePath und Label werden beibehalten, damit einfacher auf den Namen und die Kategorie der ursprünglichen Bilddatei zugegriffen werden kann.The ImagePath and Label properties are kept for convenience to access the original image file name and category.

    2. Anschließend definieren Sie unter der ModelInput-Klasse das Schema Ihrer Ausgabedaten in einer neuen Klasse namens ModelOutput.Then, below the ModelInput class, define the schema of your output data in a new class called ModelOutput.

      class ModelOutput
      {
          public string ImagePath { get; set; }
      
          public string Label { get; set; }
      
          public string PredictedLabel { get; set; }
      }
      

      ModelOutput enthält die folgenden Eigenschaften:ModelOutput contains the following properties:

      • ImagePath ist der vollqualifizierte Pfad, in dem das Bild gespeichert ist.ImagePath is the fully qualified path where the image is stored.
      • Label ist die ursprüngliche Kategorie, zu der das Bild gehört.Label is the original category the image belongs to. Dies ist der vorherzusagende Wert.This is the value to predict.
      • PredictedLabel ist der vom Modell vorhergesagte Wert.PredictedLabel is the value predicted by the model.

      Ähnlich wie bei ModelInput ist nur PredictedLabel für Vorhersagen erforderlich, da dies die vom Modell getroffene Vorhersage enthält.Similar to ModelInput, only the PredictedLabel is required to make predictions since it contains the prediction made by the model. Die Eigenschaften ImagePath und Label werden beibehalten, damit einfacher auf den Namen und die Kategorie der ursprünglichen Bilddatei zugegriffen werden kann.The ImagePath and Label properties are retained for convenience to access the original image file name and category.

Erstellen eines ArbeitsbereichsverzeichnissesCreate workspace directory

Wenn sich Trainings-und Validierungsdaten nicht häufig ändern, empfiehlt es sich, die berechneten Engpasswerte für weitere Ausführungen zwischenzuspeichern.When training and validation data do not change often, it is good practice to cache the computed bottleneck values for further runs.

  1. Erstellen Sie in Ihrem Projekt ein neues Verzeichnis namens workspace, um die berechneten Engpasswerte und die .pb-Version des Modells zu speichern.In your project, create a new directory called workspace to store the computed bottleneck values and .pb version of the model.

Definieren von Pfaden und Initialisieren von VariablenDefine paths and initialize variables

  1. Definieren Sie innerhalb der Main-Methode den Speicherort Ihrer Ressourcen, der berechneten Engpasswerte und der .pb-Version des Modells.Inside the Main method, define the location of your assets, computed bottleneck values and .pb version of the model.

    var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
    var workspaceRelativePath = Path.Combine(projectDirectory, "workspace");
    var assetsRelativePath = Path.Combine(projectDirectory, "assets");
    
  2. Initialisieren Sie dann die mlContext-Variable mit einer neuen Instanz von MLContext.Then, initialize the mlContext variable with a new instance of MLContext.

    MLContext mlContext = new MLContext();
    

    Die MLContext-Klasse ist der Startpunkt für alle ML.NET-Vorgänge. Durch das Initialisieren von MLContext wird eine neue ML.NET-Umgebung erstellt, die für mehrere Objekte des Modellerstellungsworkflows verwendet werden kann.The MLContext class is a starting point for all ML.NET operations, and initializing mlContext creates a new ML.NET environment that can be shared across the model creation workflow objects. Die Klasse ähnelt dem Konzept von DBContext in Entity Framework.It's similar, conceptually, to DBContext in Entity Framework.

Laden der DatenLoad the data

Erstellen einer Hilfsmethode zum Laden von DatenCreate data loading utility method

Die Bilder werden in zwei Unterverzeichnissen gespeichert.The images are stored in two subdirectories. Vor dem Laden der Daten müssen diese in eine Liste mit ImageData-Objekten formatiert werden.Before loading the data, it needs to be formatted into a list of ImageData objects. Erstellen Sie hierzu die LoadImagesFromDirectory-Methode unter der Main-Methode.To do so, create the LoadImagesFromDirectory method below the Main method.

public static IEnumerable<ImageData> LoadImagesFromDirectory(string folder, bool useFolderNameAsLabel = true)
{

}
  1. Fügen Sie in LoadImagesDirectory den folgenden Code hinzu, um alle Dateipfade aus den Unterverzeichnissen abzurufen:Inside the LoadImagesDirectory add the following code to get all of the file paths from the subdirectories:

    var files = Directory.GetFiles(folder, "*",
        searchOption: SearchOption.AllDirectories);
    
  2. Durchlaufen Sie dann die einzelnen Dateien mithilfe einer foreach-Anweisung.Then, iterate through each of the files using a foreach statement.

    foreach (var file in files)
    {
    
    }
    
  3. Überprüfen Sie, ob in der foreach-Anweisung die Dateierweiterungen unterstützt werden.Inside the foreach statement, check that the file extensions are supported. Die Bildklassifizierungs-API unterstützt JPEG- und PNG-Formate.The Image Classification API supports JPEG and PNG formats.

    if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png"))
        continue;
    
  4. Rufen Sie anschließend die Bezeichnung für die Datei ab.Then, get the label for the file. Wenn der useFolderNameAsLabel-Parameter auf true festgelegt ist, wird das übergeordnete Verzeichnis, in dem die Datei gespeichert wird, als Bezeichnung verwendet.If the useFolderNameAsLabel parameter is set to true, then the parent directory where the file is saved is used as the label. Andernfalls wird erwartet, dass die Bezeichnung ein Präfix des Dateinamens oder der Dateiname selbst ist.Otherwise, it expects the label to be a prefix of the file name or the file name itself.

    var label = Path.GetFileName(file);
    
    if (useFolderNameAsLabel)
        label = Directory.GetParent(file).Name;
    else
    {
        for (int index = 0; index < label.Length; index++)
        {
            if (!char.IsLetter(label[index]))
            {
                label = label.Substring(0, index);
                break;
            }
        }
    }
    
  5. Abschließend erstellen Sie eine neue Instanz von ModelInput.Finally, create a new instance of ModelInput.

    yield return new ImageData()
    {
        ImagePath = file,
        Label = label
    };
    

Vorbereiten der DatenPrepare the data

  1. Verwenden Sie in der Main-Methode die LoadFromDirectory-Hilfsmethode, um die Liste der Bilder abzurufen, die für das Training verwendet werden.Back in the Main method, use the LoadFromDirectory utility method to get the list of images used for training.

    IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);
    
  2. Laden Sie dann die Bilder mithilfe der LoadFromEnumerable-Methode in eine IDataView-Schnittstelle.Then, load the images into an IDataView using the LoadFromEnumerable method.

    IDataView imageData = mlContext.Data.LoadFromEnumerable(images);
    
  3. Die Daten werden in der Reihenfolge geladen, in der sie aus den Verzeichnissen gelesen wurden.The data is loaded in the order it was read from the directories. Um die Daten auszugleichen, mischen Sie sie zufällig mithilfe der ShuffleRows-Methode.To balance the data, shuffle it using the ShuffleRows method.

    IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);
    
  4. Bei Modellen für maschinelles Lernen wird eine Eingabe im numerischen Format erwartet.Machine learning models expect input to be in numerical format. Daher muss vor dem Training eine Vorverarbeitung der Daten durchgeführt werden.Therefore, some preprocessing needs to be done on the data prior to training. Erstellen Sie eine EstimatorChain, die aus MapValueToKey und LoadRawImageBytes-Transformationen besteht.Create an EstimatorChain made up of the MapValueToKey and LoadRawImageBytes transforms. Die MapValueToKey-Transformation übernimmt den kategorischen Wert aus der Spalte Label, konvertiert diesen in einen numerischen KeyType-Wert und speichert ihn in einer neuen Spalte namens LabelAsKey.The MapValueToKey transform takes the categorical value in the Label column, converts it to a numerical KeyType value and stores it in a new column called LabelAsKey. LoadImages greift auf Werte aus der Spalte ImagePath zusammen mit dem Parameter imageFolder zu, um Bilder für das Training zu laden.The LoadImages takes the values from the ImagePath column along with the imageFolder parameter to load images for training.

    var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
            inputColumnName: "Label",
            outputColumnName: "LabelAsKey")
        .Append(mlContext.Transforms.LoadRawImageBytes(
            outputColumnName: "Image",
            imageFolder: assetsRelativePath,
            inputColumnName: "ImagePath"));
    
  5. Verwenden Sie die Fit-Methode, um die Daten auf die EstimatorChain-Klasse preprocessingPipeline gefolgt von der Transform-Methode anzuwenden, wodurch eine IDataView-Schnittstelle zurückgegeben wird, die die vorverarbeiteten Daten enthält.Use the Fit method to apply the data to the preprocessingPipeline EstimatorChain followed by the Transform method, which returns an IDataView containing the pre-processed data.

    IDataView preProcessedData = preprocessingPipeline
                        .Fit(shuffledData)
                        .Transform(shuffledData);
    
  6. Beim Trainieren eines Modells ist es wichtig, sowohl über ein Trainingsdataset als auch ein Validierungsdataset zu verfügen.To train a model, it's important to have a training dataset as well as a validation dataset. Das Modell wird mit dem Trainingsset trainiert.The model is trained on the training set. Wie gut es Vorhersagen über unbekannte Daten erstellt, wird an der Leistung im Vergleich zum Validierungsset gemessen.How well it makes predictions on unseen data is measured by the performance against the validation set. Basierend auf den Ergebnissen dieser Leistung nimmt das Modell Anpassungen an dem Gelernten vor, um die Ergebnisse zu verbessern.Based on the results of that performance, the model makes adjustments to what it has learned in an effort to improve. Das Validierungsset kann entweder aus der Aufteilung des ursprünglichen Datasets oder aus einer anderen Quelle stammen, die bereits für diesen Zweck vorgesehen ist.The validation set can come from either splitting your original dataset or from another source that has already been set aside for this purpose. In diesem Fall wird das vorverarbeitete Datenset in Trainings-, Validierungs- und Testsets unterteilt.In this case, the pre-processed dataset is split into training, validation and test sets.

    TrainTestData trainSplit = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
    TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);
    

    Im obigen Codebeispiel werden zwei Aufteilungen vorgenommen.The code sample above performs two splits. Zunächst werden die vorverarbeiteten Daten aufgeteilt, wobei 70% für das Training und die restlichen 30% für die Validierung verwendet werden.First, the pre-processed data is split and 70% is used for training while the remaining 30% is used for validation. Anschließend werden die 30% des Validierungssets weiter in Validierungs- und Testsets unterteilt, wobei 90% für die Validierung und 10% für Tests verwendet werden.Then, the 30% validation set is further split into validation and test sets where 90% is used for validation and 10% is used for testing.

    Ein gutes Beispiel, um den Sinn und Zweck dieser Datenaufteilungen zu verstehen, ist eine Prüfungsituation.A way to think about the purpose of these data partitions is taking an exam. Wenn Sie für eine Prüfung lernen, lesen Sie Ihre Notizen, Bücher oder andere Unterlagen, um die in der Prüfung enthaltenen Themen zu lernen und zu vertiefen.When studying for an exam, you review your notes, books, or other resources to get a grasp on the concepts that are on the exam. Dafür ist das Trainingsset da.This is what the train set is for. Dann können Sie eine Probeklausur ablegen, um Ihren Wissensstand zu überprüfen.Then, you might take a mock exam to validate your knowledge. Hier bietet sich das Validierungsset an.This is where the validation set comes in handy. Sie möchten vor der eigentlichen Prüfung feststellen, ob Sie die Inhalte richtig verstanden haben.You want to check whether you have a good grasp of the concepts before taking the actual exam. Ausgehend von den Ergebnissen können Sie herausfinden, was Sie falsch gemacht bzw. nicht richtig verstanden haben, und so die Ergebnisse in den Lernprozess für die eigentliche Prüfung einbeziehen.Based on those results, you take note of what you got wrong or didn't understand well and incorporate your changes as you review for the real exam. Zum Schluss legen Sie die Prüfung ab.Finally, you take the exam. Dafür wird das Testset verwendet.This is what the test set is used for. Sie haben die Fragen in der Prüfung noch nie gesehen und nutzen zur Bearbeitung der vorliegenden Aufgabe nun das, was Sie sich durch den Lernprozess (Training) und die Überprüfung des Gelernten (Validierung) angeeignet haben.You've never seen the questions that are on the exam and now use what you learned from training and validation to apply your knowledge to the task at hand.

  7. Ordnen Sie den Teilbereichen die jeweiligen Werte für die Trainings-, Validierungs- und Testdaten zu.Assign the partitions their respective values for the train, validation and test data.

    IDataView trainSet = trainSplit.TrainSet;
    IDataView validationSet = validationTestSplit.TrainSet;
    IDataView testSet = validationTestSplit.TestSet;
    

Definieren der TrainingspipelineDefine the training pipeline

Das Modelltraining umfasst mehrere Schritte.Model training consists of a couple of steps. Zunächst wird die Bildklassifizierungs-API verwendet, um das Modell zu trainieren.First, Image Classification API is used to train the model. Anschließend werden die verschlüsselten Bezeichnungen in der Spalte PredictedLabel mithilfe der MapKeyToValue-Transformation wieder in ihren ursprünglichen kategorischen Wert konvertiert.Then, the encoded labels in the PredictedLabel column are converted back to their original categorical value using the MapKeyToValue transform.

  1. Erstellen Sie eine neue Variable, um einen Satz erforderlicher und optionaler Parameter für ein ImageClassificationTrainer-Element zu speichern.Create a new variable to store a set of required and optional parameters for an ImageClassificationTrainer.

    var classifierOptions = new ImageClassificationTrainer.Options()
    {
        FeatureColumnName = "Image",
        LabelColumnName = "LabelAsKey",
        ValidationSet = validationSet,
        Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
        MetricsCallback = (metrics) => Console.WriteLine(metrics),
        TestOnTrainSet = false,
        ReuseTrainSetBottleneckCachedValues = true,
        ReuseValidationSetBottleneckCachedValues = true,
        WorkspacePath=workspaceRelativePath
    };
    

    Ein ImageClassificationTrainer-Element nimmt mehrere optionale Parameter an:An ImageClassificationTrainer takes several optional parameters:

    • FeatureColumnName ist die Spalte, die als Eingabe für das Modell verwendet wird.FeatureColumnName is the column that is used as input for the model.
    • LabelColumnName ist die Spalte für den vorherzusagenden Wert.LabelColumnName is the column for the value to predict.
    • ValidationSet ist die IDataView-Schnittstelle, die die Validierungsdaten enthält.ValidationSet is the IDataView containing the validation data.
    • Arch definiert, welche der vorab trainierten Modellarchitekturen verwendet werden soll.Arch defines which of the pretrained model architectures to use. In diesem Tutorial wird die 101-Ebenen-Variante des Modells „ResNetv2“ verwendet.This tutorial uses the 101-layer variant of the ResNetv2 model.
    • MetricsCallback verknüpft eine Funktion, um den Fortschritt während des Trainings zu verfolgen.MetricsCallback binds a function to track the progress during training.
    • TestOnTrainSet weist das Modell an, die Leistung anhand des Trainingssets zu messen, wenn kein Validierungsset vorhanden ist.TestOnTrainSet tells the model to measure performance against the training set when no validation set is present.
    • ReuseTrainSetBottleneckCachedValues informiert das Modell, ob die zwischengespeicherten Werte aus der Engpassphase in nachfolgenden Durchläufen verwendet werden sollen.ReuseTrainSetBottleneckCachedValues tells the model whether to use the cached values from the bottleneck phase in subsequent runs. Die Engpassphase ist eine einmalige Pass-Through-Berechnung, die bei der ersten Durchführung sehr rechenintensiv ist.The bottleneck phase is a one-time pass-through computation that is computationally intensive the first time it is performed. Wenn sich die Trainingsdaten nicht ändern, und Sie mit einer anderen Anzahl von Epochen oder anderen Batchgrößen experimentieren möchten, können Sie mit den zwischengespeicherten Werten den Zeitaufwand für das Training eines Modells erheblich verringern.If the training data does not change and you want to experiment using a different number of epochs or batch size, using the cached values significantly reduces the amount of time required to train a model.
    • ReuseValidationSetBottleneckCachedValues ist vergleichbar mit ReuseTrainSetBottleneckCachedValues, allerdings handelt es sich in diesem Fall um das Validierungsdataset.ReuseValidationSetBottleneckCachedValues is similar to ReuseTrainSetBottleneckCachedValues only that in this case it's for the validation dataset.
    • WorkspacePath definiert das Verzeichnis, in dem die berechneten Engpasswerte und die .pb-Version des Modells gespeichert werden sollen.WorkspacePath defines the directory where to store the computed bottleneck values and .pb version of the model.
  2. Definieren Sie die EstimatorChain-Trainingspipeline, die aus mapLabelEstimator und ImageClassificationTrainer besteht.Define the EstimatorChain training pipeline that consists of both the mapLabelEstimator and the ImageClassificationTrainer.

    var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
        .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
    
  3. Verwenden Sie die Methode Fit, um Ihr Modell zu trainieren.Use the Fit method to train your model.

    ITransformer trainedModel = trainingPipeline.Fit(trainSet);
    

Verwenden des ModellsUse the model

Nachdem Sie Ihr Modell trainiert haben, ist es an der Zeit, es zur Klassifizierung von Bildern zu verwenden.Now that you have trained your model, it's time to use it to classify images.

Erstellen Sie unter der Main-Methode eine neue Hilfsmethode namens OutputPrediction, um Vorhersageinformationen in der Konsole anzuzeigen.Below the Main method, create a new utility method called OutputPrediction to display prediction information in the console.

private static void OutputPrediction(ModelOutput prediction)
{
    string imageName = Path.GetFileName(prediction.ImagePath);
    Console.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}");
}

Klassifizieren eines einzelnen BildsClassify a single image

  1. Fügen Sie eine neue Methode namens ClassifySingleImage unter der Main-Methode hinzu, um eine Einzelbildvorhersage zu erstellen und auszugeben.Add a new method called ClassifySingleImage below the Main method to make and output a single image prediction.

    public static void ClassifySingleImage(MLContext mlContext, IDataView data, ITransformer trainedModel)
    {
    
    }
    
  2. Erstellen Sie eine PredictionEngine-Klasse innerhalb der ClassifySingleImage-Methode.Create a PredictionEngine inside the ClassifySingleImage method. Die PredictionEngine-Klasse ist eine praktische API, mit der Sie eine Vorhersage für eine einzelne Dateninstanz übergeben und dann ausführen können.The PredictionEngine is a convenience API, which allows you to pass in and then perform a prediction on a single instance of data.

    PredictionEngine<ModelInput, ModelOutput> predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(trainedModel);
    
  3. Um auf eine einzelne ModelInput-Instanz zuzugreifen, konvertieren Sie die IDataView-Schnittstelle data in eine IEnumerable-Schnittstelle mit der CreateEnumerable-Methode und erhalten Sie dann das erste Ergebnis.To access a single ModelInput instance, convert the data IDataView into an IEnumerable using the CreateEnumerable method and then get the first observation.

    ModelInput image = mlContext.Data.CreateEnumerable<ModelInput>(data,reuseRowObject:true).First();
    
  4. Verwenden Sie die Predict-Methode, um das Bild zu klassifizieren.Use the Predict method to classify the image.

    ModelOutput prediction = predictionEngine.Predict(image);
    
  5. Geben Sie die Vorhersage mit der OutputPrediction-Methode in der Konsole aus.Output the prediction to the console with the OutputPrediction method.

    Console.WriteLine("Classifying single image");
    OutputPrediction(prediction);
    
  6. Rufen Sie innerhalb der Main-Methode ClassifySingleImage mit dem Testset der Bilder auf.Inside the Main method, call ClassifySingleImage using the test set of images.

    ClassifySingleImage(mlContext, testSet, trainedModel);
    

Klassifizieren mehrerer BilderClassify multiple images

  1. Fügen Sie eine neue Methode namens ClassifyImages unter der ClassifySingleImage-Methode hinzu, um mehrere Bildvorhersagen zu erstellen und auszugeben.Add a new method called ClassifyImages below the ClassifySingleImage method to make and output multiple image predictions.

    public static void ClassifyImages(MLContext mlContext, IDataView data, ITransformer trainedModel)
    {
    
    }
    
  2. Erstellen Sie mithilfe der Transform-Methode eine IDataView-Schnittstelle, die die Vorhersagen enthält.Create an IDataView containing the predictions by using the Transform method. Fügen Sie der ClassifyImages-Methode den folgenden Code hinzu.Add the following code inside the ClassifyImages method.

    IDataView predictionData = trainedModel.Transform(data);
    
  3. Zur Iteration über die Vorhersagen konvertieren Sie die IDataView-Schnittstelle predictionData in eine IEnumerable-Schnittstelle mithilfe der CreateEnumerable-Methode und erhalten Sie dann die ersten zehn Ergebnisse.In order to iterate over the predictions, convert the predictionData IDataView into an IEnumerable using the CreateEnumerable method and then get the first 10 observations.

    IEnumerable<ModelOutput> predictions = mlContext.Data.CreateEnumerable<ModelOutput>(predictionData, reuseRowObject: true).Take(10);
    
  4. Iterieren Sie die ursprünglichen und vorhergesagten Bezeichnungen für die Vorhersagen, und geben Sie sie aus.Iterate and output the original and predicted labels for the predictions.

    Console.WriteLine("Classifying multiple images");
    foreach (var prediction in predictions)
    {
        OutputPrediction(prediction);
    }
    
  5. Abschließend rufen Sie innerhalb der Main-Methode ClassifyImages mit dem Testset der Bilder auf.Finally, inside the Main method, call ClassifyImages using the test set of images.

    ClassifyImages(mlContext, testSet, trainedModel);
    

Ausführen der AnwendungRun the application

Führen Sie die Konsolenanwendung aus.Run your console app. Die Ausgabe sollte in etwa wie folgt aussehen.The output should be similar to that below. Möglicherweise werden Warnungen oder Verarbeitungsnachrichten angezeigt. Diese wurden jedoch aus Gründen der Übersichtlichkeit aus den folgenden Ergebnissen entfernt.You may see warnings or processing messages, but these messages have been removed from the following results for clarity. Aus Gründen der Kürze wurde die Ausgabe komprimiert.For brevity, the output has been condensed.

EngpassphaseBottleneck phase

Für den Bildnamen wird kein Wert ausgegeben, da die Bilder als byte[] geladen werden, sodass kein Bildname angezeigt werden kann.No value is printed for the image name because the images are loaded as a byte[] therefore there is no image name to display.

Phase: Bottleneck Computation, Dataset used:      Train, Image Index: 279
Phase: Bottleneck Computation, Dataset used:      Train, Image Index: 280
Phase: Bottleneck Computation, Dataset used: Validation, Image Index:   1
Phase: Bottleneck Computation, Dataset used: Validation, Image Index:   2

TrainingsphaseTraining phase

Phase: Training, Dataset used: Validation, Batch Processed Count:   6, Epoch:  21, Accuracy:  0.6797619
Phase: Training, Dataset used: Validation, Batch Processed Count:   6, Epoch:  22, Accuracy:  0.7642857
Phase: Training, Dataset used: Validation, Batch Processed Count:   6, Epoch:  23, Accuracy:  0.7916667

Klassifizieren der Ausgabe von BildernClassify images output

Classifying single image
Image: 7001-220.jpg | Actual Value: UD | Predicted Value: UD

Classifying multiple images
Image: 7001-220.jpg | Actual Value: UD | Predicted Value: UD
Image: 7001-163.jpg | Actual Value: UD | Predicted Value: UD
Image: 7001-210.jpg | Actual Value: UD | Predicted Value: UD

Bei der Überprüfung des Bilds 7001-220.jpg können Sie feststellen, dass tatsächlich kein Riss zu sehen ist.Upon inspection of the 7001-220.jpg image, you can see that it in fact is not cracked.

Für die Vorhersage verwendetes SDNET2018-Datasetbild

Herzlichen Glückwunsch!Congratulations! Sie haben ein Deep-Learning-Modell zur Klassifizierung von Bildern erstellt.You've now successfully built a deep learning model for classifying images.

Verbessern des ModellsImprove the model

Wenn Sie mit den Ergebnissen des Modells nicht zufrieden sind, können Sie versuchen, seine Leistung zu verbessern, indem Sie einige der folgenden Ansätze ausprobieren:If you're not satisfied with the results of your model, you can try to improve its performance by trying some of the following approaches:

  • Mehr Daten: Je mehr Beispiele vorhanden sind, von denen ein Modell lernt, desto besser ist dessen Leistung.More Data: The more examples a model learns from, the better it performs. Laden Sie das vollständige SDNET2018-Dataset herunter, und verwenden Sie es für das Training.Download the full SDNET2018 dataset and use it to train.
  • Erweitern der Daten: Eine gängige Technik, um eine größere Datenvielfalt zu erreichen, ist die Erweiterung der Daten durch Aufnahme eines Bilds und Anwendung verschiedener Transformationen (Drehen, Spiegeln, Verschieben, Zuschneiden).Augment the data: A common technique to add variety to the data is to augment the data by taking an image and applying different transforms (rotate, flip, shift, crop). Auf diese Weise erhalten Sie verschiedene Beispiele, von denen das Modell lernen kann.This adds more varied examples for the model to learn from.
  • Längere Trainingsdauer: Umso länger die Trainingsdauer, desto genauer werden die Ergebnisse des Modells sein.Train for a longer time: The longer you train, the more tuned the model will be. Durch die Erhöhung der Anzahl von Epochen kann sich die Leistung des Modell erheblich verbessern.Increasing the number of epochs may improve the performance of your model.
  • Experimentieren mit Hyperparametern: Zusätzlich zu den in diesem Tutorial verwendeten Parametern können weitere Parameter angepasst werden, um die Leistung zu steigern.Experiment with the hyper-parameters: In addition to the parameters used in this tutorial, other parameters can be tuned to potentially improve performance. Die Änderung des Lerntempos, das den Umfang der Aktualisierungen am Modell nach jeder Epoche bestimmt, kann zu einer höheren Leistung führen.Changing the learning rate, which determines the magnitude of updates made to the model after each epoch may improve performance.
  • Verwenden einer anderen Modellarchitektur: Abhängig von der Beschaffenheit Ihrer Daten kann sich das Modell, das am besten deren Merkmale erlernen kann, unterscheiden.Use a different model architecture: Depending on what your data looks like, the model that can best learn its features may differ. Wenn Sie mit der Leistung Ihres Modells unzufrieden sind, sollten Sie versuchen, die Architektur zu ändern.If you're not satisfied with the performance of your model, try changing the architecture.

Zusätzliche RessourcenAdditional Resources

Nächste SchritteNext steps

In diesem Tutorial haben Sie erfahren, wie Sie ein benutzerdefiniertes Deep-Learning-Modell mithilfe von Transferlernen, einem vorab trainierten TensorFlow-Modell und der ML.NET-Bildklassifizierungs-API erstellen, um Bilder von Betonoberflächen als gerissen oder nicht gerissen zu klassifizieren.In this tutorial, you learned how to build a custom deep learning model using transfer learning, a pretrained image classification TensorFlow model and the ML.NET Image Classification API to classify images of concrete surfaces as cracked or uncracked.

Fahren Sie mit dem nächsten Tutorial fort, um mehr zu erfahren.Advance to the next tutorial to learn more.