Esercitazione: Ispezione visiva automatizzata tramite l'apprendimento di trasferimento con l'API di classificazione delle immagini ML.NET
Articolo
Informazioni su come eseguire il training di un modello di deep learning personalizzato usando l'apprendimento di trasferimento, un modello TensorFlow con training preliminare e l'API di classificazione delle immagini ML.NET per classificare le immagini di superfici concrete come crepate o non crittografate.
In questa esercitazione verranno illustrate le procedure per:
Informazioni sul problema
Informazioni sull'API di classificazione delle immagini ML.NET
Comprendere il modello con training preliminare
Usare l'apprendimento di trasferimento per eseguire il training di un modello di classificazione delle immagini TensorFlow personalizzato
Classificare le immagini con il modello personalizzato
Panoramica dell'esempio di apprendimento per il trasferimento delle immagini
Questo esempio è un'applicazione console C# .NET Core che classifica le immagini usando un modello TensorFlow con training preliminare. Il codice per questo esempio è disponibile nel browser di esempi.
Informazioni sul problema
La classificazione delle immagini è un problema di visione artificiale. La classificazione delle immagini accetta un'immagine come input e la classifica in una classe specificata. I modelli di classificazione delle immagini vengono comunemente sottoposti a training usando deep learning e reti neurali. Per altre informazioni, vedere Deep Learning e Machine Learning .
Alcuni scenari in cui la classificazione delle immagini è utile includono:
Riconoscimento facciale
Rilevamento delle emozioni
Diagnosi medica
Rilevamento dei punti di riferimento
Questa esercitazione esegue il training di un modello di classificazione delle immagini personalizzato per eseguire l'ispezione visiva automatica dei ponti per identificare le strutture danneggiate da crepe.
API di classificazione delle immagini ML.NET
ML.NET offre diversi modi per eseguire la classificazione delle immagini. Questa esercitazione applica l'apprendimento di trasferimento usando l'API Classificazione immagini. L'API Classificazione immagini usa TensorFlow.NET, una libreria a basso livello che fornisce associazioni C# per l'API C++ TensorFlow.
Che cos'è l'apprendimento induttivo?
L'apprendimento di trasferimento applica le conoscenze acquisite dalla risoluzione di un problema a un altro problema correlato.
Il training di un modello di deep learning da zero richiede l'impostazione di diversi parametri, una grande quantità di dati di training etichettati e una vasta quantità di risorse di calcolo (centinaia di ore di GPU). L'uso di un modello con training preliminare insieme all'apprendimento di trasferimento consente di completare il processo di training.
Processo di training
L'API Classificazione immagini avvia il processo di training caricando un modello TensorFlow con training preliminare. Il processo di training è costituito da due passaggi:
Fase collo di bottiglia
Fase di training
Fase collo di bottiglia
Durante la fase del collo di bottiglia, il set di immagini di training viene caricato e i valori pixel vengono usati come input o funzionalità, per i livelli congelati del modello pre-sottoposto a training. I livelli congelati includono tutti i livelli della rete neurale fino al penultimo livello, noto in modo informale come livello collo di bottiglia. Questi livelli vengono definiti bloccati perché nessun training si verificherà su questi livelli e le operazioni sono pass-through. Si tratta di questi livelli bloccati in cui vengono calcolati i modelli di livello inferiore che consentono a un modello di distinguere tra le diverse classi. Maggiore è il numero di livelli, più intensivo a livello di calcolo è questo passaggio. Fortunatamente, poiché si tratta di un calcolo one-time, i risultati possono essere memorizzati nella cache e usati in esecuzioni successive durante l'esperimento con parametri diversi.
Fase di training
Dopo aver calcolato i valori di output della fase del collo di bottiglia, vengono usati come input per ripetere il training del livello finale del modello. Questo processo è iterativo e viene eseguito per il numero di volte specificato dai parametri del modello. Durante ogni esecuzione vengono valutate la perdita e l'accuratezza. Le modifiche appropriate vengono quindi apportate per migliorare il modello con l'obiettivo di ridurre al minimo la perdita e massimizzare l'accuratezza. Al termine del training, vengono restituiti due formati di modello. Una di esse è la versione del modello e l'altra è la .pb.zip ML.NET versione serializzata del modello. Quando si lavora in ambienti supportati da ML.NET, è consigliabile usare la .zip versione del modello. Tuttavia, negli ambienti in cui ML.NET non è supportato, è possibile usare la .pb versione.
Comprendere il modello con training preliminare
Il modello con training preliminare usato in questa esercitazione è la variante a 101 livelli del modello Residual Network (ResNet) v2. Il modello originale viene sottoposto a training per classificare le immagini in migliaia di categorie. Il modello accetta come input un'immagine di dimensioni 224 x 224 e restituisce le probabilità di classe per ognuna delle classi su cui viene eseguito il training. Parte di questo modello viene usata per eseguire il training di un nuovo modello usando immagini personalizzate per eseguire stime tra due classi.
Creare un'applicazione console
Ora che si ha una conoscenza generale dell'apprendimento di trasferimento e dell'API Classificazione immagini, è possibile compilare l'applicazione.
Creare un'applicazione console C# denominata "DeepLearning_ImageClassification_Binary". Fare clic sul pulsante Next (Avanti).
Scegliere .NET 6 come framework da usare. Fare clic sul pulsante Crea.
Installare il pacchetto NuGet Microsoft.ML:
Nota
Questo esempio usa la versione stabile più recente dei pacchetti NuGet menzionati a meno che non sia specificato in altro modo.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Gestisci pacchetti NuGet.
Scegliere "nuget.org" come origine pacchetto.
Selezionare la scheda Sfoglia.
Selezionare la casella di controllo Includi versione preliminare .
Cercare Microsoft.ML.
Selezionare il pulsante Installa.
Selezionare il pulsante OK nella finestra di dialogo Anteprima modifiche e quindi selezionare il pulsante Accetto nella finestra di dialogo Accettazione della licenza se si accettano le condizioni di licenza per i pacchetti elencati.
Ripetere questi passaggi per i pacchetti NuGet Microsoft.ML.Vision, SciSharp.TensorFlow.Redist versione 2.3.1 e Microsoft.ML.ImageAnalytics .
Preparare e identificare i dati
Nota
I set di dati per questa esercitazione sono di Maguire, Marc; Dorafshan, Sattar; e Thomas, Robert J., "SDNET2018: set di dati di immagini di crack concrete per le applicazioni di Machine Learning" (2018). Esplorare tutti i set di dati. Carta 48. https://digitalcommons.usu.edu/all_datasets/48
SDNET2018 è un set di dati di immagini che contiene annotazioni per strutture di cemento crepate e non cracked (ponte, pareti e pavimentazioni).
I dati sono organizzati in tre sottodirectory:
D contiene immagini bridge deck
P contiene immagini di pavimentazione
W contiene immagini di parete
Ognuna di queste sottodirectory contiene due sottodirectory con prefisso aggiuntivo:
C è il prefisso usato per le superfici crepate
U è il prefisso usato per le superfici non crittografate
In questa esercitazione vengono usate solo immagini bridge deck.
Creare una directory denominata "asset" nel progetto per salvare i file del set di dati.
Copiare le sottodirectory CD e UD dalla directory non aggiornata di recente alla directory asset .
Creare classi di input e output
Aprire il file Program.cs e sostituire le istruzioni esistenti using nella parte superiore del file con quanto segue:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.ML;
using static Microsoft.ML.DataOperationsCatalog;
using Microsoft.ML.Vision;
Sotto la Program classe in Program.cs creare una classe denominata ImageData. Questa classe viene usata per rappresentare i dati inizialmente caricati.
class ImageData
{
public string ImagePath { get; set; }
public string Label { get; set; }
}
ImageData contiene le proprietà seguenti:
ImagePath è il percorso completo in cui viene archiviata l'immagine.
Label è la categoria a cui appartiene l'immagine. Questo è il valore da prevedere.
Creare classi per i dati di input e output
Sotto la ImageData classe definire lo schema dei dati di input in una nuova classe denominata ModelInput.
class ModelInput
{
public byte[] Image { get; set; }
public UInt32 LabelAsKey { get; set; }
public string ImagePath { get; set; }
public string Label { get; set; }
}
ModelInput contiene le proprietà seguenti:
Image è la byte[] rappresentazione dell'immagine. Il modello prevede che i dati dell'immagine siano di questo tipo per il training.
LabelAsKey è la rappresentazione numerica dell'oggetto Label.
ImagePath è il percorso completo in cui viene archiviata l'immagine.
Label è la categoria a cui appartiene l'immagine. Questo è il valore da prevedere.
Solo Image e LabelAsKey vengono usati per eseguire il training del modello e effettuare stime. Le ImagePath proprietà e Label vengono mantenute per praticità per accedere al nome e alla categoria del file di immagine originale.
Quindi, sotto la ModelInput classe, definire lo schema dei dati di output in una nuova classe denominata ModelOutput.
class ModelOutput
{
public string ImagePath { get; set; }
public string Label { get; set; }
public string PredictedLabel { get; set; }
}
ModelOutput contiene le proprietà seguenti:
ImagePath è il percorso completo in cui viene archiviata l'immagine.
Label è la categoria originale a cui appartiene l'immagine. Questo è il valore da prevedere.
PredictedLabel è il valore stimato dal modello.
Analogamente a ModelInput, è necessario eseguire stime solo PredictedLabel perché contiene la stima effettuata dal modello. Le ImagePath proprietà e Label vengono mantenute per praticità per accedere al nome e alla categoria del file di immagine originale.
Creare la directory dell'area di lavoro
Quando i dati di training e convalida non cambiano spesso, è consigliabile memorizzare nella cache i valori del collo di bottiglia calcolati per ulteriori esecuzioni.
Nel progetto creare una nuova directory denominata area di lavoro per archiviare i valori del collo di bottiglia calcolati e .pb la versione del modello.
Definire i percorsi e inizializzare le variabili
Nelle istruzioni using definire la posizione degli asset, calcolare i valori del collo di bottiglia e .pb la versione del modello.
var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
var workspaceRelativePath = Path.Combine(projectDirectory, "workspace");
var assetsRelativePath = Path.Combine(projectDirectory, "assets");
Inizializzare la mlContext variabile con una nuova istanza di MLContext.
MLContext mlContext = new MLContext();
La classe MLContext è un punto di partenza per tutte le operazioni di ML.NET e l'inizializzazione di mlContext crea un nuovo ambiente ML.NET che può essere condiviso tra gli oggetti del flusso di lavoro di creazione del modello. Dal punto di vista concettuale è simile a DbContext in Entity Framework.
Caricare i dati
Creare un metodo di utilità di caricamento dei dati
Le immagini vengono archiviate in due sottodirectory. Prima di caricare i dati, è necessario formattare in un elenco di ImageData oggetti. A tale scopo, creare il LoadImagesFromDirectory metodo.
LoadImagesFromDirectoryAll'interno di , aggiungere il codice seguente per ottenere tutti i percorsi di file dalle sottodirectory:
var files = Directory.GetFiles(folder, "*",
searchOption: SearchOption.AllDirectories);
Eseguire quindi l'iterazione di ognuno dei file usando un'istruzione foreach .
foreach (var file in files)
{
}
All'interno dell'istruzione foreach verificare che le estensioni di file siano supportate. L'API Classificazione immagini supporta formati JPEG e PNG.
if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png"))
continue;
Ottenere quindi l'etichetta per il file. Se il useFolderNameAsLabel parametro è impostato su true, la directory padre in cui viene salvato il file viene usato come etichetta. In caso contrario, si prevede che l'etichetta sia un prefisso del nome del file o del nome del file stesso.
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;
}
}
}
Chiamare il LoadImagesFromDirectory metodo di utilità per ottenere l'elenco di immagini usate per il training dopo l'inizializzazione della mlContext variabile.
I modelli di Machine Learning prevedono che l'input sia in formato numerico. Pertanto, è necessario eseguire alcune operazioni di pre-elaborazione sui dati prima del training. Creare un EstimatorChain oggetto costituito da MapValueToKey e LoadRawImageBytes trasformazioni. La MapValueToKey trasformazione accetta il valore categorico nella Label colonna, lo converte in un valore numerico KeyType e lo archivia in una nuova colonna denominata LabelAsKey. Accetta LoadImages i valori dalla ImagePath colonna insieme al parametro per caricare immagini per il imageFolder training.
Utilizzare il Fit metodo per applicare i dati al preprocessingPipelineEstimatorChain seguito dal Transform metodo, che restituisce un IDataView oggetto contenente i dati pre-elaborati.
Per eseguire il training di un modello, è importante avere un set di dati di training e un set di dati di convalida. Il modello viene sottoposto a training nel set di training. Il modo in cui esegue stime sui dati non visualizzati viene misurata dalle prestazioni rispetto al set di convalida. In base ai risultati di tale prestazione, il modello apporta modifiche a ciò che ha appreso in modo da migliorare. Il set di convalida può derivare dalla suddivisione del set di dati originale o da un'altra origine già messa a parte per questo scopo. In questo caso, il set di dati pre-elaborato viene suddiviso in set di training, convalida e test.
L'esempio di codice precedente esegue due suddivisioni. Prima di tutto, i dati pre-elaborati vengono suddivisi e il 70% viene usato per il training mentre il rimanente 30% viene usato per la convalida. Quindi, il set di convalida del 30% è ulteriormente suddiviso in set di convalida e test in cui viene usato il 90% per la convalida e il 10% viene usato per i test.
Un modo per pensare allo scopo di queste partizioni di dati sta prendendo un esame. Quando si studia per un esame, si esaminano le note, i libri o altre risorse per ottenere una comprensione sui concetti che si trovano nell'esame. Questo è quello che il set di training è per. È quindi possibile eseguire un esame fittizio per convalidare la conoscenza. Questo è il luogo in cui il set di convalida è utile. Si vuole verificare se si ha una buona comprensione dei concetti prima di eseguire l'esame effettivo. In base a questi risultati, prendere nota di ciò che si è sbagliato o non ha capito bene e incorporare le modifiche come si esamina per l'esame reale. Infine, si prende l'esame. Si tratta di ciò che viene usato per il set di test. Non sono mai state viste le domande che si trovano nell'esame e ora si usano le informazioni apprese dal training e dalla convalida per applicare le proprie conoscenze all'attività a mano.
Assegnare le partizioni dei rispettivi valori per i dati di training, convalida e test.
Il training del modello è costituito da un paio di passaggi. In primo luogo, l'API classificazione delle immagini viene usata per eseguire il training del modello. Le etichette codificate nella PredictedLabel colonna vengono quindi convertite nuovamente nel valore categorico originale usando la MapKeyToValue trasformazione.
Creare una nuova variabile per archiviare un set di parametri obbligatori e facoltativi per un ImageClassificationTraineroggetto .
FeatureColumnName è la colonna utilizzata come input per il modello.
LabelColumnName è la colonna per il valore da prevedere.
ValidationSet è l'oggetto contenente i dati di IDataView convalida.
Arch definisce quale delle architetture del modello pre-sottoposto a training da usare. Questa esercitazione usa la variante a livello 101 del modello ResNetv2.
MetricsCallback associa una funzione per tenere traccia dello stato di avanzamento durante il training.
TestOnTrainSet indica al modello di misurare le prestazioni rispetto al set di training quando non è presente alcun set di convalida.
ReuseTrainSetBottleneckCachedValues indica al modello se usare i valori memorizzati nella cache dalla fase del collo di bottiglia nelle esecuzioni successive. La fase del collo di bottiglia è un calcolo pass-through una volta che viene intensivo a livello di calcolo la prima volta che viene eseguita. Se i dati di training non cambiano e si vuole sperimentare usando un numero diverso di epoche o dimensioni batch, l'uso dei valori memorizzati nella cache riduce significativamente il tempo necessario per eseguire il training di un modello.
ReuseValidationSetBottleneckCachedValues è simile solo ReuseTrainSetBottleneckCachedValues a quello in questo caso per il set di dati di convalida.
WorkspacePath definisce la directory in cui archiviare i valori del collo di bottiglia calcolati e .pb la versione del modello.
var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
Usare il metodo per eseguire il training del Fit modello.
Creare un PredictionEngine oggetto all'interno del ClassifySingleImage metodo . PredictionEngine è un'API utile, che consente di passare e quindi eseguire una stima su una singola istanza di dati.
Per accedere a una singola ModelInput istanza, convertire in dataIDataView un IEnumerable oggetto usando il CreateEnumerable metodo e quindi ottenere la prima osservazione.
Per scorrere le stime, convertire in predictionDataIDataView un oggetto IEnumerable usando il CreateEnumerable metodo e quindi ottenere le prime 10 osservazioni.
Chiamare ClassifyImages infine sotto il ClassifySingleImage() metodo usando il set di test di immagini.
ClassifyImages(mlContext, testSet, trainedModel);
Eseguire l'applicazione
Eseguire l'app console. L'output dovrebbe essere simile a quello riportato di seguito. È possibile che vengano visualizzati avvisi o messaggi di elaborazione che tuttavia, per chiarezza, sono stati rimossi dai risultati riportati di seguito. Per brevità, l'output è stato condensato.
Fase collo di bottiglia
Non viene stampato alcun valore per il nome dell'immagine perché le immagini vengono caricate come nome byte[] di immagine da visualizzare.
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
Dopo l'ispezione dell'immagine 7001-220.jpg , si può vedere che in realtà non è rotto.
Congratulazioni! È stato creato un modello di Deep Learning per la classificazione delle immagini.
Migliorare il modello
Se non si è soddisfatti dei risultati del modello, è possibile provare a migliorarne le prestazioni provando alcuni degli approcci seguenti:
Altri dati: più esempi un modello apprende, con prestazioni migliori. Scaricare il set di dati SDNET2018 completo e usarlo per il training.
Aumentare i dati: una tecnica comune per aggiungere varietà ai dati consiste nell'aumentare i dati prendendo un'immagine e applicando trasformazioni diverse (ruotare, capovolgere, spostare, ritagliare). In questo modo vengono aggiunti esempi più vari per il modello da cui apprendere.
Eseguire il training per un periodo di tempo più lungo: più lungo sarà il training, più sarà ottimizzato il modello. L'aumento del numero di periodi può migliorare le prestazioni del modello.
Sperimentare gli iper parametri: oltre ai parametri usati in questa esercitazione, è possibile ottimizzare altri parametri per migliorare potenzialmente le prestazioni. Modifica della frequenza di apprendimento, che determina la grandezza degli aggiornamenti apportati al modello dopo ogni periodo può migliorare le prestazioni.
Usare un'architettura del modello diversa: a seconda dell'aspetto dei dati, il modello in grado di apprendere meglio le relative funzionalità può differire. Se non si è soddisfatti delle prestazioni del modello, provare a modificare l'architettura.
Passaggi successivi
In questa esercitazione si è appreso come creare un modello di Deep Learning personalizzato usando l'apprendimento per il trasferimento, un modello TensorFlow di classificazione delle immagini con training preliminare e l'API di classificazione delle immagini ML.NET per classificare le immagini di superfici concrete come incrisse o non crittografate.
Passare all'esercitazione successiva per altre informazioni.
L'origine di questo contenuto è disponibile in GitHub, in cui è anche possibile creare ed esaminare i problemi e le richieste pull. Per ulteriori informazioni, vedere la guida per i collaboratori.
Feedback su .NET
.NET è un progetto di open source. Selezionare un collegamento per fornire feedback:
Questo percorso di apprendimento ha lo scopo di spiegare agli studenti come distribuire intelligenza artificiale nei dispositivi perimetrali usando servizi di Azure.
Gestire l'inserimento e la preparazione dei dati, il training e la distribuzione di modelli e il monitoraggio delle soluzioni di apprendimento automatico con Python, Azure Machine Learning e MLflow.