Tutorial: inspeção visual automatizada usando o aprendizado de transferência com a API de classificação de imagem ML.NETTutorial: Automated visual inspection using transfer learning with the ML.NET Image Classification API

Saiba como treinar um modelo de aprendizado profundo personalizado usando o aprendizado de transferência, um modelo TensorFlow pretreinado e a API de classificação de imagem ML.NET para classificar imagens de superfícies concretas como rachadas ou sem cracking.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.

Neste tutorial, você aprenderá como:In this tutorial, you learn how to:

  • Compreender o problemaUnderstand the problem
  • Saiba mais sobre a API de classificação de imagem ML.NETLearn about ML.NET Image Classification API
  • Entender o modelo pretreinadoUnderstand the pretrained model
  • Usar o aprendizado de transferência para treinar um modelo de classificação de imagem TensorFlow personalizadoUse transfer learning to train a custom TensorFlow image classification model
  • Classificar imagens com o modelo personalizadoClassify images with the custom model

Pré-requisitosPrerequisites

  • Visual studio 2019 ou posterior ou visual Studio 2017 versão 15,6 ou posterior com a carga de trabalho "desenvolvimento de plataforma cruzada do .NET Core" instalada.Visual Studio 2019 or later or Visual Studio 2017 version 15.6 or later with the ".NET Core cross-platform development" workload installed.

Visão geral do exemplo de aprendizado de transferência de classificação de imagemImage classification transfer learning sample overview

Este exemplo é um aplicativo de console C# .NET Core que classifica imagens usando um modelo de TensorFlow de aprendizado profundo pretreinado.This sample is a C# .NET Core console application that classifies images using a pretrained deep learning TensorFlow model. O código para este exemplo pode ser encontrado no navegador de exemplos.The code for this sample can be found on the samples browser.

Compreender o problemaUnderstand the problem

A classificação de imagem é um problema de pesquisa Visual computacional.Image classification is a computer vision problem. A classificação de imagem usa uma imagem como entrada e a categoriza em uma classe prescrita.Image classification takes an image as input and categorizes it into a prescribed class. Alguns cenários em que a classificação de imagem é útil incluem:Some scenarios where image classification is useful include:

  • Reconhecimento de rostoFacial recognition
  • Detecção de EmoçõesEmotion detection
  • Diagnóstico médicoMedical diagnosis
  • Detecção de monumentosLandmark detection

Este tutorial treina um modelo de classificação de imagem personalizada para executar a inspeção visual automatizada de decks de ponte para identificar estruturas que estão danificadas por rachaduras.This tutorial trains a custom image classification model to perform automated visual inspection of bridge decks to identify structures that are damaged by cracks.

API de classificação de imagem ML.NETML.NET Image Classification API

O ML.NET fornece várias maneiras de executar a classificação de imagem.ML.NET provides various ways of performing image classification. Este tutorial aplica-se ao aprendizado de transferência usando a API de classificação de imagem.This tutorial applies transfer learning using the Image Classification API. A API de classificação de imagem usa TensorFlow.net, uma biblioteca de nível baixo que fornece associações em C# para a API do TensorFlow C++.The Image Classification API makes use of TensorFlow.NET, a low-level library that provides C# bindings for the TensorFlow C++ API.

O que é a transferência de aprendizado?What is transfer learning?

O aprendizado de transferência aplica o conhecimento obtido da solução de um problema para outro problema relacionado.Transfer learning applies knowledge gained from solving one problem to another related problem.

Treinar um modelo de aprendizado profundo do zero exige a definição de vários parâmetros, uma grande quantidade de dados de treinamento rotulados e uma grande quantidade de recursos de computação (centenas de horas de GPU).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). Usar um modelo pretreinado junto com o aprendizado de transferência permite que você Modele o processo de treinamento.Using a pretrained model along with transfer learning allows you to shortcut the training process.

Processo de treinamentoTraining process

A API de classificação de imagem inicia o processo de treinamento carregando um modelo de TensorFlow pré-treinado.The Image Classification API starts the training process by loading a pretrained TensorFlow model. O processo de treinamento consiste em duas etapas:The training process consists of two steps:

  1. Fase de afunilamentoBottleneck phase
  2. Fase de treinamentoTraining phase

Etapas de treinamento

Fase de afunilamentoBottleneck phase

Durante a fase de afunilamento, o conjunto de imagens de treinamento é carregado e os valores de pixel são usados como entrada, ou recursos, para as camadas congeladas do modelo pretreinado.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. As camadas congeladas incluem todas as camadas na rede neural até a camada penúltima, informalmente conhecida como a camada de afunilamento.The frozen layers include all of the layers in the neural network up to the penultimate layer, informally known as the bottleneck layer. Essas camadas são referidas como congeladas porque nenhum treinamento ocorrerá nessas camadas e as operações são passagem.These layers are referred to as frozen because no training will occur on these layers and operations are pass-through. Elas estão nessas camadas congeladas onde os padrões de nível inferior que ajudam um modelo diferenciar entre as diferentes classes são computadas.It's at these frozen layers where the lower-level patterns that help a model differentiate between the different classes are computed. Quanto maior o número de camadas, mais intensivamente essa etapa é computada.The larger the number of layers, the more computationally intensive this step is. Felizmente, como esse é um cálculo único, os resultados podem ser armazenados em cache e usados em execuções posteriores ao experimentar parâmetros diferentes.Fortunately, since this is a one-time calculation, the results can be cached and used in later runs when experimenting with different parameters.

Fase de treinamentoTraining phase

Depois que os valores de saída da fase de afunilamento são computados, eles são usados como entrada para treinar novamente a camada final do modelo.Once the output values from the bottleneck phase are computed, they are used as input to retrain the final layer of the model. Esse processo é iterativo e é executado para o número de vezes especificado por parâmetros de modelo.This process is iterative and runs for the number of times specified by model parameters. Durante cada execução, a perda e a precisão são avaliadas.During each run, the loss and accuracy are evaluated. Em seguida, os ajustes apropriados são feitos para melhorar o modelo com o objetivo de minimizar a perda e maximizar a precisão.Then, the appropriate adjustments are made to improve the model with the goal of minimizing the loss and maximizing the accuracy. Quando o treinamento for concluído, dois formatos de modelo serão gerados.Once training is finished, two model formats are output. Uma delas é a .pb versão do modelo e a outra é a .zip versão serializada ml.net do modelo.One of them is the .pb version of the model and the other is the .zip ML.NET serialized version of the model. Ao trabalhar em ambientes com suporte do ML.NET, é recomendável usar a .zip versão do modelo.When working in environments supported by ML.NET, it is recommended to use the .zip version of the model. No entanto, em ambientes em que não há suporte para ML.NET, você tem a opção de usar a .pb versão.However, in environments where ML.NET is not supported, you have the option of using the .pb version.

Entender o modelo pretreinadoUnderstand the pretrained model

O modelo pretreinado usado neste tutorial é a variante de camada 101 do modelo de rede residual (ResNet) v2.The pretrained model used in this tutorial is the 101-layer variant of the Residual Network (ResNet) v2 model. O modelo original é treinado para classificar imagens em milhares de categorias.The original model is trained to classify images into a thousand categories. O modelo usa como entrada uma imagem de tamanho 224 x 224 e gera as probabilidades de classe para cada uma das classes em que é treinado.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. Parte desse modelo é usada para treinar um novo modelo usando imagens personalizadas para fazer previsões entre duas classes.Part of this model is used to train a new model using custom images to make predictions between two classes.

Criar um aplicativo de consoleCreate console application

Agora que você tem uma compreensão geral do aprendizado de transferência e da API de classificação de imagem, é hora de criar o aplicativo.Now that you have a general understanding of transfer learning and the Image Classification API, it's time to build the application.

  1. Crie um aplicativo de console do .NET Core em C# chamado "DeepLearning_ImageClassification_Binary".Create a C# .NET Core Console Application called "DeepLearning_ImageClassification_Binary".

  2. Instale o pacote NuGet do Microsoft.ml :Install the Microsoft.ML NuGet Package:

    Observação

    Este exemplo usa a versão estável mais recente dos pacotes NuGet mencionados, a menos que indicado de outra forma.This sample uses the latest stable version of the NuGet packages mentioned unless otherwise stated.

    1. No Gerenciador de Soluções, clique com o botão direito do mouse no seu projeto e selecione Gerenciar Pacotes NuGet.In Solution Explorer, right-click on your project and select Manage NuGet Packages.
    2. Escolha "nuget.org" como a origem do pacote.Choose "nuget.org" as the Package source.
    3. Selecione a guia Procurar.Select the Browse tab.
    4. Marque a caixa de seleção incluir pré-lançamento .Check the Include prerelease checkbox.
    5. Procure Microsoft.ml.Search for Microsoft.ML.
    6. Selecione o botão Instalar.Select the Install button.
    7. Selecione o botão OK na caixa de diálogo Visualizar Alterações e selecione o botão Aceito na caixa de diálogo Aceitação da Licença, se concordar com o termos de licença para os pacotes listados.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. Repita essas etapas para os pacotes Microsoft. ml. Vision, SciSharp. TensorFlow. Redist e Microsoft. ml. ImageAnalytics NuGet.Repeat these steps for the Microsoft.ML.Vision, SciSharp.TensorFlow.Redist, and Microsoft.ML.ImageAnalytics NuGet packages.

Preparar e compreender os dadosPrepare and understand the data

Observação

Os conjuntos de valores para este tutorial são de Maguire, Marc; Dorafshan, Sattar; e Thomas, Robert J., "SDNET2018: um conjunto de imagem de quebra concreta para aplicativos de Machine Learning" (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). Procurar todos os conjuntos de valores.Browse all Datasets. Papel 48.Paper 48. https://digitalcommons.usu.edu/all_datasets/48

SDNET2018 é um conjunto de uma imagem que contém anotações para estruturas concretas rachadas e não rachadas (baralhos de ponte, paredes e Pavement).SDNET2018 is an image dataset that contains annotations for cracked and non-cracked concrete structures (bridge decks, walls, and pavement).

Amostras de baralho da ponte do conjunto de SDNET2018

Os dados são organizados em três subdiretórios:The data is organized in three subdirectories:

  • D contém imagens do deck de ponteD contains bridge deck images
  • P contém imagens PavementP contains pavement images
  • W contém imagens de paredeW contains wall images

Cada um desses subdiretórios contém dois subdiretórios prefixais adicionais:Each of these subdirectories contains two additional prefixed subdirectories:

  • C é o prefixo usado para superfícies rachadasC is the prefix used for cracked surfaces
  • U é o prefixo usado para superfícies não decifradasU is the prefix used for uncracked surfaces

Neste tutorial, somente imagens de baralho de ponte são usadas.In this tutorial, only bridge deck images are used.

  1. Baixe o conjunto de e descompacte.Download the dataset and unzip.
  2. Crie um diretório chamado "ativos" em seu projeto para salvar os arquivos do conjunto de recursos.Create a directory named "assets" in your project to save your dataset files.
  3. Copie os subdiretórios CD e UD do diretório recentemente descompactado para o diretório de ativos .Copy the CD and UD subdirectories from the recently unzipped directory to the assets directory.

Criar classes de entrada e saídaCreate input and output classes

  1. Abra o arquivo Program.cs e substitua as using instruções existentes na parte superior do arquivo pelo seguinte: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. Abaixo da Program classe em Program.cs, crie uma classe chamada ImageData .Below the Program class in Program.cs, create a class called ImageData. Essa classe é usada para representar os dados carregados inicialmente.This class is used to represent the initially loaded data.

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

    ImageData contém as seguintes propriedades:ImageData contains the following properties:

    • ImagePath é o caminho totalmente qualificado em que a imagem é armazenada.ImagePath is the fully qualified path where the image is stored.
    • Label é a categoria à qual a imagem pertence.Label is the category the image belongs to. Esse é o valor a prever.This is the value to predict.
  3. Criar classes para os dados de entrada e saídaCreate classes for your input and output data

    1. Abaixo da ImageData classe, defina o esquema dos dados de entrada em uma nova classe chamada 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 contém as seguintes propriedades:ModelInput contains the following properties:

      • Image é a byte[] representação da imagem.Image is the byte[] representation of the image. O modelo espera que os dados de imagem sejam desse tipo para treinamento.The model expects image data to be of this type for training.
      • LabelAsKey é a representação numérica do Label .LabelAsKey is the numerical representation of the Label.
      • ImagePath é o caminho totalmente qualificado em que a imagem é armazenada.ImagePath is the fully qualified path where the image is stored.
      • Label é a categoria à qual a imagem pertence.Label is the category the image belongs to. Esse é o valor a prever.This is the value to predict.

      Somente Image e LabelAsKey são usados para treinar o modelo e fazer previsões.Only Image and LabelAsKey are used to train the model and make predictions. As ImagePath Label Propriedades e são mantidas por conveniência para acessar o nome e a categoria do arquivo de imagem original.The ImagePath and Label properties are kept for convenience to access the original image file name and category.

    2. Em seguida, abaixo da ModelInput classe, defina o esquema dos dados de saída em uma nova classe chamada 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 contém as seguintes propriedades:ModelOutput contains the following properties:

      • ImagePath é o caminho totalmente qualificado em que a imagem é armazenada.ImagePath is the fully qualified path where the image is stored.
      • Label é a categoria original à qual a imagem pertence.Label is the original category the image belongs to. Esse é o valor a prever.This is the value to predict.
      • PredictedLabel é o valor previsto pelo modelo.PredictedLabel is the value predicted by the model.

      Semelhante a ModelInput , somente o PredictedLabel é necessário para fazer previsões, pois ela contém a previsão feita pelo modelo.Similar to ModelInput, only the PredictedLabel is required to make predictions since it contains the prediction made by the model. As ImagePath Label Propriedades e são retidas para facilitar o acesso ao nome e à categoria do arquivo de imagem original.The ImagePath and Label properties are retained for convenience to access the original image file name and category.

Criar diretório de espaço de trabalhoCreate workspace directory

Quando os dados de treinamento e validação não são alterados com frequência, é uma boa prática armazenar em cache os valores de afunilamento computados para execuções posteriores.When training and validation data do not change often, it is good practice to cache the computed bottleneck values for further runs.

  1. Em seu projeto, crie um novo diretório chamado espaço de trabalho para armazenar os valores de afunilamento computados e .pb a versão do modelo.In your project, create a new directory called workspace to store the computed bottleneck values and .pb version of the model.

Definir caminhos e inicializar variáveisDefine paths and initialize variables

  1. Dentro do Main método, defina o local de seus ativos, os valores de afunilamento computados e .pb a versão do modelo.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. Inicialize a mlContext variável com uma nova instância de MLContext.Initialize the mlContext variable with a new instance of MLContext.

    MLContext mlContext = new MLContext();
    

    A classe MLContext é um ponto de partida para todas as operações de ml.net, e a inicialização de MLContext cria um novo ambiente ml.NET que pode ser compartilhado entre os objetos de fluxo de trabalho de criação de modelo.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. Ele é semelhante, conceitualmente, a DbContext no Entity Framework.It's similar, conceptually, to DbContext in Entity Framework.

Carregar os dadosLoad the data

Criar método de utilitário de carregamento de dadosCreate data loading utility method

As imagens são armazenadas em dois subdiretórios.The images are stored in two subdirectories. Antes de carregar os dados, eles precisam ser formatados em uma lista de ImageData objetos.Before loading the data, it needs to be formatted into a list of ImageData objects. Para fazer isso, crie o LoadImagesFromDirectory método abaixo do Main método.To do so, create the LoadImagesFromDirectory method below the Main method.

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

}
  1. Dentro do LoadImagesFromDirectory , adicione o seguinte código para obter todos os caminhos de arquivo dos subdiretórios:Inside the LoadImagesFromDirectory, add the following code to get all of the file paths from the subdirectories:

    var files = Directory.GetFiles(folder, "*",
        searchOption: SearchOption.AllDirectories);
    
  2. Em seguida, Itere em cada um dos arquivos usando uma foreach instrução.Then, iterate through each of the files using a foreach statement.

    foreach (var file in files)
    {
    
    }
    
  3. Dentro da foreach instrução, verifique se as extensões de arquivo têm suporte.Inside the foreach statement, check that the file extensions are supported. A API de classificação de imagem dá suporte aos formatos JPEG e PNG.The Image Classification API supports JPEG and PNG formats.

    if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png"))
        continue;
    
    
  4. Em seguida, obtenha o rótulo para o arquivo.Then, get the label for the file. Se o useFolderNameAsLabel parâmetro for definido como true , o diretório pai onde o arquivo é salvo será usado como o rótulo.If the useFolderNameAsLabel parameter is set to true, then the parent directory where the file is saved is used as the label. Caso contrário, ele espera que o rótulo seja um prefixo do nome do arquivo ou o próprio nome do arquivo.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. Por fim, crie uma nova instância do ModelInput .Finally, create a new instance of ModelInput.

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

Preparar os dadosPrepare the data

  1. De volta ao Main método, use o LoadImagesFromDirectory método utilitário para obter a lista de imagens usadas para treinamento.Back in the Main method, use the LoadImagesFromDirectory utility method to get the list of images used for training.

    IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);
    
  2. Em seguida, carregue as imagens em um IDataView usando o LoadFromEnumerable método.Then, load the images into an IDataView using the LoadFromEnumerable method.

    IDataView imageData = mlContext.Data.LoadFromEnumerable(images);
    
  3. Os dados são carregados na ordem em que foram lidos dos diretórios.The data is loaded in the order it was read from the directories. Para balancear os dados, use a ordem aleatória usando o ShuffleRows método.To balance the data, shuffle it using the ShuffleRows method.

    IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);
    
  4. Os modelos de aprendizado de máquina esperam que a entrada esteja em formato numérico.Machine learning models expect input to be in numerical format. Portanto, algum pré-processamento precisa ser feito nos dados antes do treinamento.Therefore, some preprocessing needs to be done on the data prior to training. Crie um EstimatorChain composto das MapValueToKey LoadRawImageBytes transformações e.Create an EstimatorChain made up of the MapValueToKey and LoadRawImageBytes transforms. A MapValueToKey transformação usa o valor categórico na Label coluna, converte-o em um valor numérico KeyType e o armazena em uma nova coluna chamada 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. O LoadImages pega os valores da ImagePath coluna junto com o imageFolder parâmetro para carregar imagens para treinamento.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. Use o Fit método para aplicar os dados ao preprocessingPipeline EstimatorChain seguido pelo Transform método, que retorna um IDataView que contém os dados pré-processados.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. Para treinar um modelo, é importante ter um conjunto de um de treinamento, bem como um conjunto de uma validação.To train a model, it's important to have a training dataset as well as a validation dataset. O modelo é treinado no conjunto de treinamento.The model is trained on the training set. O quão bem ele faz previsões sobre dados não vistos é medido pelo desempenho em relação ao conjunto de validação.How well it makes predictions on unseen data is measured by the performance against the validation set. Com base nos resultados desse desempenho, o modelo faz ajustes no que ele aprendeu em um esforço para melhorar.Based on the results of that performance, the model makes adjustments to what it has learned in an effort to improve. O conjunto de validação pode vir de uma divisão do conjunto de seus conjuntos de seus originais ou de outra fonte que já tenha sido reservada para essa finalidade.The validation set can come from either splitting your original dataset or from another source that has already been set aside for this purpose. Nesse caso, o conjunto de valores previamente processados é dividido em conjuntos de treinamento, validação e teste.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);
    

    O exemplo de código acima executa duas divisões.The code sample above performs two splits. Primeiro, os dados previamente processados são divididos e 70% é usado para treinamento enquanto os 30% restantes são usados para validação.First, the pre-processed data is split and 70% is used for training while the remaining 30% is used for validation. Em seguida, o conjunto de validação de 30% é mais dividido em conjuntos de validação e de teste em que 90% é usado para validação e 10% é usado para teste.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.

    Uma maneira de pensar sobre a finalidade dessas partições de dados é fazer um exame.A way to think about the purpose of these data partitions is taking an exam. Ao estudar um exame, você examina suas notas, livros ou outros recursos para entender os conceitos que estão no exame.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. É para isso que se trata o conjunto de treinamento.This is what the train set is for. Em seguida, você pode fazer um exame fictício para validar seu conhecimento.Then, you might take a mock exam to validate your knowledge. É aí que o conjunto de validação é útil.This is where the validation set comes in handy. Você quer verificar se tem uma boa noção dos conceitos antes de pegar o exame real.You want to check whether you have a good grasp of the concepts before taking the actual exam. Com base nesses resultados, anote o que você obteve errado ou não entendeu bem e incorpore suas alterações ao examinar o exame real.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. Por fim, você assume o exame.Finally, you take the exam. É para isso que o conjunto de testes é usado.This is what the test set is used for. Você nunca viu as perguntas que estão no exame e agora usa o que aprendeu do treinamento e da validação para aplicar seu conhecimento à tarefa em questão.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. Atribua as partições seus respectivos valores para os dados de treinamento, validação e teste.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;
    

Definir o pipeline de treinamentoDefine the training pipeline

O treinamento de modelo consiste em algumas etapas.Model training consists of a couple of steps. Primeiro, a API de classificação de imagem é usada para treinar o modelo.First, Image Classification API is used to train the model. Em seguida, os rótulos codificados na PredictedLabel coluna são convertidos de volta para seu valor categórico original usando a MapKeyToValue transformação.Then, the encoded labels in the PredictedLabel column are converted back to their original categorical value using the MapKeyToValue transform.

  1. Crie uma nova variável para armazenar um conjunto de parâmetros obrigatórios e opcionais para um ImageClassificationTrainer .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
    };
    

    Um ImageClassificationTrainer aceita vários parâmetros opcionais:An ImageClassificationTrainer takes several optional parameters:

    • FeatureColumnName é a coluna usada como entrada para o modelo.FeatureColumnName is the column that is used as input for the model.
    • LabelColumnName é a coluna para o valor a prever.LabelColumnName is the column for the value to predict.
    • ValidationSet é o IDataView que contém os dados de validação.ValidationSet is the IDataView containing the validation data.
    • Arch define qual das arquiteturas de modelo pretreinados usar.Arch defines which of the pretrained model architectures to use. Este tutorial usa a variante de camada 101 do modelo ResNetv2.This tutorial uses the 101-layer variant of the ResNetv2 model.
    • MetricsCallback associa uma função para acompanhar o progresso durante o treinamento.MetricsCallback binds a function to track the progress during training.
    • TestOnTrainSet informa o modelo para medir o desempenho em relação ao conjunto de treinamento quando nenhum conjunto de validação estiver presente.TestOnTrainSet tells the model to measure performance against the training set when no validation set is present.
    • ReuseTrainSetBottleneckCachedValues informa ao modelo se os valores armazenados em cache devem ser usados da fase de afunilamento nas execuções subsequentes.ReuseTrainSetBottleneckCachedValues tells the model whether to use the cached values from the bottleneck phase in subsequent runs. A fase de afunilamento é uma computação de passagem única que é computacionalmente intensiva na primeira vez em que é executada.The bottleneck phase is a one-time pass-through computation that is computationally intensive the first time it is performed. Se os dados de treinamento não forem alterados e você quiser experimentar o uso de um número diferente de épocas ou do tamanho do lote, usar os valores armazenados em cache reduz significativamente o tempo necessário para treinar um modelo.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 é semelhante ReuseTrainSetBottleneckCachedValues apenas ao que, nesse caso, é para o conjunto de conjuntos de validação.ReuseValidationSetBottleneckCachedValues is similar to ReuseTrainSetBottleneckCachedValues only that in this case it's for the validation dataset.
    • WorkspacePath define o diretório onde armazenar os valores de afunilamento computados e .pb a versão do modelo.WorkspacePath defines the directory where to store the computed bottleneck values and .pb version of the model.
  2. Defina o EstimatorChain pipeline de treinamento que consiste no mapLabelEstimator e no ImageClassificationTrainer .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. Use o Fit método para treinar seu modelo.Use the Fit method to train your model.

    ITransformer trainedModel = trainingPipeline.Fit(trainSet);
    

Usar o modeloUse the model

Agora que você treinou seu modelo, é hora de usá-lo para classificar imagens.Now that you have trained your model, it's time to use it to classify images.

Abaixo do Main método, crie um novo método de utilitário chamado OutputPrediction para exibir informações de previsão no console do.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}");
}

Classificar uma única imagemClassify a single image

  1. Adicione um novo método chamado ClassifySingleImage abaixo do Main método para fazer e gerar uma previsão de imagem única.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. Crie um PredictionEngine dentro do ClassifySingleImage método.Create a PredictionEngine inside the ClassifySingleImage method. O PredictionEngine é uma API de conveniência, que permite que você passe e execute uma previsão em uma única instância de dados.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. Para acessar uma única ModelInput instância, converta-a data IDataView em um IEnumerable usando o CreateEnumerable método e obtenha a primeira observação.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. Use o Predict método para classificar a imagem.Use the Predict method to classify the image.

    ModelOutput prediction = predictionEngine.Predict(image);
    
  5. Gere a previsão para o console com o OutputPrediction método.Output the prediction to the console with the OutputPrediction method.

    Console.WriteLine("Classifying single image");
    OutputPrediction(prediction);
    
  6. Dentro do Main método, chame ClassifySingleImage usando o conjunto de teste de imagens.Inside the Main method, call ClassifySingleImage using the test set of images.

    ClassifySingleImage(mlContext, testSet, trainedModel);
    

Classificar várias imagensClassify multiple images

  1. Adicione um novo método chamado ClassifyImages abaixo do ClassifySingleImage método para fazer e gerar várias previsões de imagem.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. Crie um IDataView contendo as previsões usando o Transform método.Create an IDataView containing the predictions by using the Transform method. Adicione o seguinte código dentro do método ClassifyImages.Add the following code inside the ClassifyImages method.

    IDataView predictionData = trainedModel.Transform(data);
    
  3. Para iterar as previsões, converta-o predictionData IDataView em um IEnumerable usando o CreateEnumerable método e, em seguida, obtenha as 10 primeiras observações.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. Itere e gere os rótulos original e previsto para as previsões.Iterate and output the original and predicted labels for the predictions.

    Console.WriteLine("Classifying multiple images");
    foreach (var prediction in predictions)
    {
        OutputPrediction(prediction);
    }
    
  5. Por fim, dentro do Main método, chame ClassifyImages usando o conjunto de teste de imagens.Finally, inside the Main method, call ClassifyImages using the test set of images.

    ClassifyImages(mlContext, testSet, trainedModel);
    

Executar o aplicativoRun the application

Execute o aplicativo de console.Run your console app. A saída deve ser semelhante à mostrada abaixo.The output should be similar to that below. Você poderá ver avisos ou mensagens de processamento, mas essas mensagens foram removidas dos resultados a seguir para maior clareza.You may see warnings or processing messages, but these messages have been removed from the following results for clarity. Para resumir, a saída foi condensada.For brevity, the output has been condensed.

Fase de afunilamentoBottleneck phase

Nenhum valor é impresso para o nome da imagem porque as imagens são carregadas como um byte[] , portanto, não há nenhum nome de imagem a ser exibido.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

Fase de treinamentoTraining 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

Classificar saída de imagensClassify 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

Após a inspeção da imagem de 7001-220.jpg , você pode ver que, na verdade, ela não está quebrada.Upon inspection of the 7001-220.jpg image, you can see that it in fact is not cracked.

Imagem do conjunto de SDNET2018 usado para previsão

Parabéns!Congratulations! Agora você criou com êxito um modelo de aprendizado profundo para classificar imagens.You've now successfully built a deep learning model for classifying images.

Melhorar o modeloImprove the model

Se você não estiver satisfeito com os resultados do modelo, poderá tentar melhorar seu desempenho experimentando algumas das seguintes abordagens: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:

  • Mais dados: quanto mais exemplos um modelo aprende, melhor é o desempenho.More Data: The more examples a model learns from, the better it performs. Baixe o conjunto de SDNET2018 completo e use-o para treinar.Download the full SDNET2018 dataset and use it to train.
  • Aumentar os dados: uma técnica comum para adicionar uma variedade aos dados é aumentar os dados, tirando uma imagem e aplicando transformações diferentes (girar, virar, deslocar, cortar).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). Isso adiciona exemplos mais variados para o modelo a ser aprendedo.This adds more varied examples for the model to learn from.
  • Treine por mais tempo: quanto mais longo for o treinamento, mais ajustado será o modelo.Train for a longer time: The longer you train, the more tuned the model will be. Aumentar o número de épocas pode melhorar o desempenho do seu modelo.Increasing the number of epochs may improve the performance of your model.
  • Experimente os hiperparâmetros: além dos parâmetros usados neste tutorial, outros parâmetros podem ser ajustados para melhorar potencialmente o desempenho.Experiment with the hyper-parameters: In addition to the parameters used in this tutorial, other parameters can be tuned to potentially improve performance. Alterar a taxa de aprendizado, que determina a magnitude das atualizações feitas ao modelo depois que cada época pode melhorar o desempenho.Changing the learning rate, which determines the magnitude of updates made to the model after each epoch may improve performance.
  • Use uma arquitetura de modelo diferente: dependendo de como seus dados se parecem, o modelo que pode aprender melhor seus recursos pode ser diferente.Use a different model architecture: Depending on what your data looks like, the model that can best learn its features may differ. Se você não estiver satisfeito com o desempenho do seu modelo, tente alterar a arquitetura.If you're not satisfied with the performance of your model, try changing the architecture.

Recursos adicionaisAdditional Resources

Próximas etapasNext steps

Neste tutorial, você aprendeu a criar um modelo de aprendizado profundo personalizado usando o aprendizado de transferência, um modelo TensorFlow de classificação de imagem previamente treinado e a API de classificação de imagem ML.NET para classificar imagens de superfícies concretas como rachadas ou sem cracking.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.

Avance para o próximo tutorial para saber mais.Advance to the next tutorial to learn more.