Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aprenda a treinar um modelo de classificação para categorizar imagens usando um modelo TensorFlow pré-treinado para processamento de imagens.
O modelo TensorFlow foi treinado para classificar imagens em mil categorias. Como o modelo TensorFlow sabe reconhecer padrões em imagens, o modelo ML.NET pode utilizar parte dele no seu pipeline para converter imagens raw em características ou entradas para treinar um modelo de classificação.
Neste tutorial, aprenderás como:
- Entenda o problema
- Incorpore o modelo pré-treinado TensorFlow na pipeline do ML.NET
- Treine e avalie o modelo ML.NET
- Classificar uma imagem de teste
Podes encontrar o código-fonte deste tutorial no repositório dotnet/samples . Por padrão, a configuração do projeto .NET para este tutorial tem como alvo o .NET Core 2.2.
Pré-requisitos
- Visual Studio 2022 ou posterior
- O ficheiro .ZIP do diretório de ativos do tutorial
- O modelo de aprendizagem automática InceptionV1
Selecione a tarefa de aprendizagem automática certa
Aprendizagem profunda
A aprendizagem profunda é um subconjunto da Aprendizagem Automática, que está a revolucionar áreas como a visão computacional e o reconhecimento de voz.
Os modelos de aprendizagem profunda são treinados utilizando grandes conjuntos de dados rotulados e redes neuronais que contêm múltiplas camadas de aprendizagem. Aprendizagem profunda:
- Tem melhor desempenho em algumas tarefas como visão computacional.
- Requer enormes quantidades de dados de treino.
A classificação de imagens é uma tarefa específica de classificação que nos permite classificar automaticamente imagens em categorias tais como:
- Detetar um rosto humano numa imagem ou não.
- Detetar gatos vs. cães.
Ou, como nas imagens seguintes, determinar se uma imagem é um alimento, brinquedo ou eletrodoméstico:
Observação
As imagens anteriores pertencem à Wikimedia Commons e são atribuídas da seguinte forma:
- "220px-Pepperoni_pizza.jpg" Domínio Público, https://commons.wikimedia.org/w/index.php?curid=79505,
- "119px-Nalle_-_a_small_brown_teddy_bear.jpg" Por Jonik - Autofotografado, CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=48166.
- "193px-Broodrooster.jpg" Por M. Minderhoud - Trabalho próprio, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=27403
Treinar um modelo de classificação de imagem do zero requer definir milhões de parâmetros, uma tonelada de dados de treino rotulados e uma enorme quantidade de recursos de computação (centenas de horas de GPU). Embora não seja tão eficaz como treinar um modelo personalizado do zero, usar um modelo pré-treinado permite-lhe encurtar este processo trabalhando com milhares de imagens em vez de milhões de imagens rotuladas e construir um modelo personalizado relativamente rapidamente (dentro de uma hora numa máquina sem GPU). Este tutorial reduz ainda mais esse processo, usando apenas uma dúzia de imagens de treino.
O Inception model é treinado para classificar imagens em mil categorias, mas para este tutorial, deve classificar imagens num conjunto de categorias mais reduzido, e apenas nessas categorias. Pode usar a Inception modelcapacidade de reconhecer e classificar imagens para as novas categorias limitadas do seu classificador de imagens personalizado.
- Alimentação
- Brinquedo
- Aparelho
Este tutorial utiliza o modelo de aprendizagem profunda TensorFlow Inception , um modelo popular de reconhecimento de imagens treinado com o conjunto de ImageNet dados. O modelo TensorFlow classifica imagens inteiras em mil classes, como "Umbrella", "Jersey" e "Dishwasher".
Como o Inception model já foi pré-treinado em milhares de imagens diferentes, internamente contém as características de imagem necessárias para a identificação de imagens. Podemos utilizar estas características internas da imagem no modelo para treinar um novo modelo com muito menos classes.
Como mostrado no diagrama seguinte, adicionar uma referência aos pacotes NuGet do ML.NET na sua aplicação .NET ou .NET Framework. Nos bastidores, o ML.NET inclui e faz referência à biblioteca nativa TensorFlow que permite escrever código que carrega um ficheiro de modelo treinado TensorFlow existente.
Classificação multiclasse
Depois de usar o modelo de início TensorFlow para extrair características adequadas como entrada para um algoritmo clássico de aprendizagem automática, adiciona-se um classificador multiclasse ML.NET.
O treinador específico utilizado neste caso é o algoritmo de regressão logística multinomial.
O algoritmo implementado por este formador tem um bom desempenho em problemas com um grande número de funcionalidades, como é o caso de um modelo de aprendizagem profunda que opera com dados de imagem.
Para mais informações, veja Deep learning vs. machine learning.
Data
Existem duas fontes de dados: o .tsv ficheiro e os ficheiros de imagem. O tags.tsv ficheiro contém duas colunas: a primeira é definida como ImagePath e a segunda é a Label correspondente à imagem. O seguinte ficheiro de exemplo não tem linha de cabeçalho e tem este aspeto:
broccoli.jpg food
pizza.jpg food
pizza2.jpg food
teddy2.jpg toy
teddy3.jpg toy
teddy4.jpg toy
toaster.jpg appliance
toaster2.png appliance
As imagens de treino e testes estão localizadas nas pastas de assets que irá descarregar num ficheiro zip. Estas imagens pertencem à Wikimedia Commons.
Wikimedia Commons, o repositório gratuito de media. Consultado às 10:48, 17 de outubro de 2018 de: https://commons.wikimedia.org/wiki/Pizzahttps://commons.wikimedia.org/wiki/Toasterhttps://commons.wikimedia.org/wiki/Teddy_bear
Configuração
Criar um projeto
Crie uma aplicação de consola C# chamada "TransferLearningTF". Clique no botão Seguinte.
Escolhe o .NET 8 como framework a usar. Clique no botão Criar .
Instale o Pacote Microsoft.ML NuGet:
Observação
Este exemplo utiliza a versão estável mais recente dos pacotes NuGet mencionados, salvo indicação em contrário.
- No Explorador de Soluções, clique com o botão direito no seu projeto e selecione Gerir Pacotes NuGet.
- Escolha "nuget.org" como a fonte do Pacote, selecione o separador Navegar, procure por Microsoft.ML.
- Selecione o botão Instalar.
- Selecione o botão OK na janela de Pré-visualização de Alterações .
- Selecione o botão Aceitar no diálogo de Aceitação de Licença se concordar com os termos da licença dos pacotes listados.
- Repita estes passos para Microsoft.ML.ImageAnalytics, SciSharp.TensorFlow.Redist e Microsoft.ML.TensorFlow.
Descarregar recursos
Descarregue o ficheiro zip do diretório de ativos do projeto e descompacte.
Copie o
assetsdiretório para o diretório do seu projeto TransferLearningTF . Este diretório e os seus subdiretórios contêm os dados e ficheiros de suporte (exceto o modelo Inception, que irá descarregar e adicionar no próximo passo) necessários para este tutorial.Descarrega o modelo Inception e descomprime.
Copie o conteúdo do diretório
inception5hque acabou de descompactar para o diretório do seu projeto TransferLearningTF. Este diretório contém o modelo e ficheiros de suporte adicionais necessários para este tutorial, como mostrado na imagem seguinte:
No Explorador de Soluções, clique com o botão direito em cada um dos ficheiros no diretório e subdiretórios do ativo e selecione Propriedades. Em Avançado, altere o valor de Copiar para Diretório de Saída para Cópia, se for mais recente.
Criar classes e definir caminhos
Adicione as seguintes diretivas adicionais
usingno topo do ficheiro Program.cs :using Microsoft.ML; using Microsoft.ML.Data;Adicione o seguinte código à linha logo abaixo das
usingdiretivas para especificar os caminhos dos ativos: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");Cria classes para os teus dados de entrada e previsões.
public class ImageData { [LoadColumn(0)] public string? ImagePath; [LoadColumn(1)] public string? Label; }ImageDataé a classe de dados da imagem de entrada e tem os seguintes String campos:-
ImagePathcontém o nome do ficheiro imagem. -
Labelcontém um valor para a etiqueta da imagem.
-
Adicione uma nova turma ao seu projeto para
ImagePrediction:public class ImagePrediction : ImageData { public float[]? Score; public string? PredictedLabelValue; }ImagePredictioné a classe de previsão da imagem e tem os seguintes campos:-
Scorecontém a percentagem de confiança para uma dada classificação de imagem. -
PredictedLabelValuecontém um valor para a etiqueta de classificação de imagem prevista.
ImagePredictioné a classe usada para a previsão após o modelo ter sido treinado. Tem umstring(ImagePath) para o percurso da imagem. ÉLabelusado para reutilizar e treinar o modelo. ÉPredictedLabelValueutilizado durante a previsão e avaliação. Para avaliação, utiliza-se uma entrada com dados de treino, os valores previstos e o modelo.-
Inicializar variáveis
Inicialize a
mlContextvariável com uma nova instância deMLContext. Substitua aConsole.WriteLine("Hello World!")linha pelo seguinte código:MLContext mlContext = new MLContext();A MLContext classe é um ponto de partida para todas as operações ML.NET, e a inicialização
mlContextcria um novo ambiente ML.NET que pode ser partilhado entre os objetos de fluxo de trabalho de criação de modelos. É semelhante, do ponto de vista conceptual, aoDBContextno Entity Framework.
Criar uma estrutura para os parâmetros do modelo Inception
O modelo Inception tem vários parâmetros que tens de cumprir. Crie um struct para mapear os valores dos parâmetros para nomes amigáveis com o seguinte código, logo após inicializar a variável
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; }
Criar um método de utilidade de visualização
Como irá mostrar os dados da imagem e as previsões relacionadas mais do que uma vez, crie um método utilitário de visualização para gerir a visualização da imagem e dos resultados da previsão.
Crie o
DisplayResults()método, logo após aInceptionSettingsstruct, usando o seguinte código:void DisplayResults(IEnumerable<ImagePrediction> imagePredictionData) { }Preencha o corpo do
DisplayResultsmétodo:foreach (ImagePrediction prediction in imagePredictionData) { Console.WriteLine($"Image: {Path.GetFileName(prediction.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} "); }
Crie um método para fazer uma previsão
Crie o
ClassifySingleImage()método, mesmo antes doDisplayResults()método, usando o seguinte código:void ClassifySingleImage(MLContext mlContext, ITransformer model) { }Crie um
ImageDataobjeto que contenha o caminho totalmente qualificado e o nome do ficheiro de imagem para o únicoImagePath. Adicione o seguinte código como as linhas seguintes noClassifySingleImage()método:var imageData = new ImageData() { ImagePath = _predictSingleImage };Faça uma única previsão, adicionando o seguinte código como a linha seguinte do
ClassifySingleImagemétodo:// Make prediction function (input = ImageData, output = ImagePrediction) var predictor = mlContext.Model.CreatePredictionEngine<ImageData, ImagePrediction>(model); var prediction = predictor.Predict(imageData);Para obter a previsão, use o método Predict(). O PredictionEngine é uma API de conveniência, que permite realizar uma previsão sobre uma única instância de dados.
PredictionEnginenão é seguro para rosca. É aceitável usar em ambientes monofio ou ambientes de protótipo. Para melhorar o desempenho e a segurança das threads em ambientes de produção, use oPredictionEnginePoolserviço, que cria umObjectPoolconjunto dePredictionEngineobjetos para usar em toda a sua aplicação. Consulte este guia sobre como usarPredictionEnginePoolnuma API Web Core ASP.NET.Observação
PredictionEnginePoolA extensão do serviço está atualmente em pré-visualização.Mostrar o resultado da previsão como a próxima linha de código no
ClassifySingleImage()método:Console.WriteLine($"Image: {Path.GetFileName(imageData.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} ");
Construir o pipeline do modelo ML.NET
Um fluxo de trabalho de modelos ML.NET é uma cadeia de estimadores. Não ocorre nenhuma execução durante a construção do oleoduto. Os objetos estimadores são criados mas não executados.
Adicionar um método para gerar o modelo
Este método é o cerne do tutorial. Cria um pipeline para o modelo e treina esse pipeline para produzir o modelo ML.NET. Também avalia o modelo com base em alguns dados de teste anteriormente inéditos.
Crie o
GenerateModel()método, logo após aInceptionSettingsestrutura e logo antes doDisplayResults()método, usando o seguinte código:ITransformer GenerateModel(MLContext mlContext) { }Adicione os estimadores para carregar, redimensionar e extrair os píxeis dos dados da imagem:
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))Os dados da imagem precisam de ser processados no formato que o modelo TensorFlow espera. Neste caso, as imagens são carregadas na memória, redimensionadas para um tamanho consistente, e os píxeis são extraídos num vetor numérico.
Adicione o estimador para carregar o modelo TensorFlow, e pontue-o:
.Append(mlContext.Model.LoadTensorFlowModel(_inceptionTensorFlowModel). ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))Esta etapa do pipeline carrega o modelo TensorFlow na memória e depois processa o vetor dos valores dos píxeis através da rede de modelos TensorFlow. Aplicar entradas a um modelo de aprendizagem profunda e gerar uma saída usando o modelo é denominado Scoring. Ao usar o modelo na sua totalidade, a pontuação faz uma inferência, ou previsão.
Neste caso, usas todo o modelo TensorFlow exceto a última camada, que é a camada que faz a inferência. A saída da penúltima camada é rotulada como
softmax_2_preactivation. A saída desta camada é efetivamente um vetor de características que caracterizam as imagens de entrada originais.Este vetor de características gerado pelo modelo TensorFlow será usado como entrada para um algoritmo de treino ML.NET.
Adicione o estimador para mapear as etiquetas das cadeias nos dados de treino para valores inteiros de chave:
.Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelKey", inputColumnName: "Label"))O treinador do ML.NET que é adicionado a seguir exige que as suas etiquetas estejam no formato
keyem vez de strings arbitrárias. Uma chave é um número que tem um mapeamento um para um para um valor de cadeia.Adicione o algoritmo de treino ML.NET:
.Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelKey", featureColumnName: "softmax2_pre_activation"))Adicione o estimador para mapear o valor-chave previsto de volta numa cadeia:
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabelValue", "PredictedLabel")) .AppendCacheCheckpoint(mlContext);
Treinar o modelo
Carregue os dados de treino usando o wrapper LoadFromTextFile. Adicione o seguinte código como a linha seguinte no
GenerateModel()método:IDataView trainingData = mlContext.Data.LoadFromTextFile<ImageData>(path: _trainTagsTsv, hasHeader: false);Os dados em ML.NET são representados como uma interface IDataView.
IDataViewé uma forma flexível e eficiente de descrever dados tabulares (numéricos e textuais). Os dados podem ser carregados a partir de um ficheiro de texto ou em tempo real (por exemplo, base de dados SQL ou ficheiros de log) para umIDataViewobjeto.Treine o modelo com os dados carregados acima:
ITransformer model = pipeline.Fit(trainingData);O
Fit()método treina o seu modelo aplicando o conjunto de dados de treino ao pipeline.
Avaliar a precisão do modelo
Carregue e transforme os dados de teste, adicionando o seguinte código à linha seguinte do
GenerateModelmétodo: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);Existem algumas imagens de exemplo que pode usar para avaliar o modelo. Tal como os dados de treino, estes precisam de ser carregados num
IDataView, para que possam ser transformados pelo modelo.Adicione o seguinte código ao
GenerateModel()método para avaliar o modelo:MulticlassClassificationMetrics metrics = mlContext.MulticlassClassification.Evaluate(predictions, labelColumnName: "LabelKey", predictedLabelColumnName: "PredictedLabel");Depois de definir a previsão, o método Evaluate():
- Avalia o modelo (compara os valores previstos com o conjunto de dados
labelsde teste ). - Devolve as métricas de desempenho do modelo.
- Avalia o modelo (compara os valores previstos com o conjunto de dados
Mostrar as métricas de precisão do modelo
Use o seguinte código para mostrar as métricas, partilhar os resultados e depois agir com base neles:
Console.WriteLine($"LogLoss is: {metrics.LogLoss}"); Console.WriteLine($"PerClassLogLoss is: {String.Join(" , ", metrics.PerClassLogLoss.Select(c => c.ToString()))}");As seguintes métricas são avaliadas para classificação de imagens:
-
Log-loss- ver Perda de Log. Queres que a perda logarítmica seja o mais próxima possível de zero. -
Per class Log-loss. Queres que a perda logarítima por classe seja o mais próxima possível de zero.
-
Adicione o seguinte código para devolver o modelo treinado na linha seguinte:
return model;
Execute o aplicativo
Adicione a chamada após
GenerateModela criação da MLContext turma:ITransformer model = GenerateModel(mlContext);Adicione a chamada ao
ClassifySingleImage()método após a chamada aoGenerateModel()método:ClassifySingleImage(mlContext, model);Executa a tua aplicação de consola (Ctrl + F5). Os seus resultados devem ser semelhantes aos resultados seguintes. (Pode ver avisos ou mensagens de processamento, mas estas mensagens foram removidas dos resultados seguintes para maior clareza.)
=============== 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
Parabéns! Agora construiu com sucesso um modelo de classificação em ML.NET para categorizar imagens, utilizando um TensorFlow pré-treinado para processamento de imagens.
Podes encontrar o código-fonte deste tutorial no repositório dotnet/samples .
Neste tutorial, você aprendeu como:
- Entenda o problema
- Incorpore o modelo pré-treinado TensorFlow na pipeline do ML.NET
- Treine e avalie o modelo ML.NET
- Classificar uma imagem de teste
Consulte o repositório de exemplos de Machine Learning no GitHub para explorar uma amostra expandida de classificação de imagens.