Kurz: Trénování klasifikačního modelu ML.NET pro kategorizaci obrázků
Naučte se trénovat klasifikační model pro kategorizaci obrázků pomocí předem vytrénovaného modelu TensorFlow pro zpracování obrázků.
Model TensorFlow byl natrénován tak, aby klasifikoval obrázky do tisíců kategorií. Vzhledem k tomu, že model TensorFlow ví, jak rozpoznávat vzory v obrázcích, může model ML.NET využít část svého kanálu k převodu obrázků RAW na funkce nebo vstupy pro trénování klasifikačního modelu.
V tomto kurzu se naučíte:
- Pochopení problému
- Začlenění předem natrénovaného modelu TensorFlow do kanálu ML.NET
- Trénování a vyhodnocení modelu ML.NET
- Klasifikace testovacího obrázku
Zdrojový kód pro tento kurz najdete v úložišti dotnet/samples . Ve výchozím nastavení konfigurace projektu .NET pro tento kurz cílí na .NET Core 2.2.
Požadavky
Výběr správné úlohy strojového učení
Hloubkové učení
Hluboké učení je podmnožinou strojového učení, které mění oblasti, jako je počítačové zpracování obrazu a rozpoznávání řeči.
Modely hlubokého učení se trénují pomocí velkých sad označených dat a neurálních sítí , které obsahují více vrstev učení. Hluboké učení:
- U některých úloh, jako je počítačové zpracování obrazu, funguje lépe.
- Vyžaduje obrovské množství trénovacích dat.
Klasifikace obrázků je specifická klasifikační úloha, která nám umožňuje automaticky klasifikovat obrázky do kategorií, jako jsou:
- Rozpoznání lidské tváře na obrázku nebo ne
- Detekce koček vs. psů.
Nebo jako na následujících obrázcích můžete určit, jestli je obrázek potravinou, tou nebo spotřebičem:
Poznámka
Předchozí obrázky patří do Wikimedia Commons a mají následující atributy:
- "220px-Pepperoni_pizza.jpg" Public Domain, https://commons.wikimedia.org/w/index.php?curid=79505,
- "119px-Nalle_-_a_small_brown_teddy_bear.jpg" Autor Jonik - self-photographed, CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=48166.
- "193px-Broodrooster.jpg" M.Minderhoud - Vlastní práce, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=27403
Trénování modelu klasifikace obrázků od začátku vyžaduje nastavení milionů parametrů, tuny označených trénovacích dat a obrovské množství výpočetních prostředků (stovky hodin GPU). I když to není tak efektivní jako trénování vlastního modelu od nuly, pomocí předem natrénovaného modelu můžete tento proces zkrátit tím, že budete pracovat s tisíci obrázků oproti milionům označených obrázků a poměrně rychle vytvořit přizpůsobený model (během hodiny na počítači bez GPU). V tomto kurzu se proces ještě více zužuje a využívá jen tucet trénovacích obrázků.
Je Inception model
natrénovaný tak, aby klasifikoval obrázky do tisíců kategorií, ale pro účely tohoto kurzu potřebujete klasifikovat obrázky v menší sadě kategorií a jenom v těchto kategoriích. Schopnost rozpoznávat a klasifikovat obrázky můžete využít Inception model
v nových omezených kategoriích vlastního klasifikátoru obrázků.
- Potravin
- Hračka
- Zařízení
V tomto kurzu se používá model hlubokého učení TensorFlow Inception , oblíbený model rozpoznávání obrázků trénovaný na ImageNet
datové sadě. Model TensorFlow klasifikuje celé obrázky do tisíců tříd, například "Umbrella", "Jersey" a "Myčka nádobí".
Inception model
Vzhledem k tomu, že už byl předem vytrénován na tisících různých obrázků, obsahuje interně funkce obrázku potřebné k identifikaci obrázku. Tyto funkce interních obrázků v modelu můžeme využít k trénování nového modelu s mnohem menším počtem tříd.
Jak je znázorněno v následujícím diagramu, přidáte odkaz na ML.NET balíčky NuGet v aplikacích .NET Core nebo .NET Framework. Na pozadí ML.NET zahrnuje a odkazuje na nativní TensorFlow
knihovnu, která umožňuje napsat kód, který načte existující soubor trénovaného TensorFlow
modelu.
Klasifikace s více třídami
Po použití modelu vzniku TensorFlow k extrakci funkcí vhodných jako vstup pro algoritmus klasického strojového učení přidáme ML.NET klasifikátor s více třídami.
Konkrétním školitelem použitým v tomto případě je multinomický algoritmus logistické regrese.
Algoritmus implementovaný tímto školitelem funguje dobře při problémech s velkým počtem funkcí, což je případ modelu hlubokého učení pracujícího s obrazovými daty.
Další informace najdete v tématu Hloubkové učení vs. strojové učení .
Data
Existují dva zdroje dat: .tsv
soubor a soubory obrázků. Soubor tags.tsv
obsahuje dva sloupce: první je definovaný jako ImagePath
a druhý sloupec odpovídá Label
obrázku. Následující ukázkový soubor nemá řádek záhlaví a vypadá takto:
broccoli.jpg food
pizza.jpg food
pizza2.jpg food
teddy2.jpg toy
teddy3.jpg toy
teddy4.jpg toy
toaster.jpg appliance
toaster2.png appliance
Trénovací a testovací obrázky se nacházejí ve složkách prostředků, které si stáhnete v souboru ZIP. Tyto obrázky patří do Wikimedia Commons.
Bezplatné úložiště médií Ve Wikimedia Commons. Citováno 10:48, 17. října 2018 z: https://commons.wikimedia.org/wiki/Pizzahttps://commons.wikimedia.org/wiki/Toasterhttps://commons.wikimedia.org/wiki/Teddy_bear
Nastavení
Vytvoření projektu
Vytvořte konzolovou aplikaci jazyka C# s názvem TransferLearningTF. Klikněte na tlačítko Další .
Jako architekturu, kterou chcete použít, zvolte .NET 6. Klikněte na tlačítko Vytvořit.
Nainstalujte balíček NuGet Microsoft.ML:
Poznámka
Tato ukázka používá nejnovější stabilní verzi uvedených balíčků NuGet, pokud není uvedeno jinak.
- V Průzkumník řešení klikněte pravým tlačítkem na projekt a vyberte Spravovat balíčky NuGet.
- Jako zdroj balíčku zvolte "nuget.org", vyberte kartu Procházet a vyhledejte Microsoft.ML.
- Vyberte tlačítko Nainstalovat .
- V dialogovém okně Náhled změn vyberte tlačítko OK.
- Pokud souhlasíte s licenčními podmínkami pro uvedené balíčky, vyberte v dialogovém okně Souhlas s licencemi tlačítko Souhlasím.
- Opakujte tento postup pro Microsoft.ML.ImageAnalytics, SciSharp.TensorFlow.Redist a Microsoft.ML.TensorFlow.
Stažení prostředků
Stáhněte soubor ZIP adresáře assetů projektu a rozbalte ho.
assets
Zkopírujte adresář do adresáře projektu TransferLearningTF. Tento adresář a jeho podadresáře obsahují data a podpůrné soubory (s výjimkou modelu Inception, který si stáhnete a přidáte v dalším kroku) potřebné pro účely tohoto kurzu.Stáhněte si model inception a rozbalte ho.
Zkopírujte obsah adresáře, který
inception5h
jste právě rozbalili, do adresáře projektuassets/inception
TransferLearningTF. Tento adresář obsahuje model a další podpůrné soubory potřebné pro tento kurz, jak je znázorněno na následujícím obrázku:V Průzkumník řešení klikněte pravým tlačítkem na jednotlivé soubory v adresáři a podadresáři prostředků a vyberte Vlastnosti. V části Upřesnit změňte hodnotu Kopírovat do výstupního adresáře na Kopírovat, pokud je novější.
Vytvoření tříd a definování cest
Na začátek souboru Program.cs přidejte následující další
using
příkazy:using Microsoft.ML; using Microsoft.ML.Data;
Přidejte následující kód na řádek přímo pod příkazy using a určete cesty k prostředkům:
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");
Vytvořte třídy pro vstupní data a předpovědi.
public class ImageData { [LoadColumn(0)] public string? ImagePath; [LoadColumn(1)] public string? Label; }
ImageData
je datová třída vstupního obrázku a obsahuje následující String pole:ImagePath
obsahuje název souboru obrázku.Label
obsahuje hodnotu popisku obrázku.
Přidejte do projektu novou třídu pro
ImagePrediction
:public class ImagePrediction : ImageData { public float[]? Score; public string? PredictedLabelValue; }
ImagePrediction
je třída předpovědi obrázku a obsahuje následující pole:Score
obsahuje procento spolehlivosti pro danou klasifikaci obrázků.PredictedLabelValue
obsahuje hodnotu pro predikovaný popisek klasifikace obrázků.
ImagePrediction
je třída používaná pro predikci po vytrénování modelu.string
Má (ImagePath
) pro cestu k imagi. SloužíLabel
k opakovanému použití a trénování modelu. Hodnota sePredictedLabelValue
používá při predikci a vyhodnocení. Pro vyhodnocení se používá vstup s trénovacími daty, predikovanými hodnotami a modelem.
Inicializace proměnných
Inicializace
mlContext
proměnné pomocí nové instance .MLContext
Console.WriteLine("Hello World!")
Nahraďte řádek následujícím kódem:MLContext mlContext = new MLContext();
Třída MLContext je výchozím bodem pro všechny operace ML.NET a inicializace
mlContext
vytvoří nové ML.NET prostředí, které lze sdílet mezi objekty pracovního postupu vytváření modelu. KoncepčněDBContext
je podobný jako v Entity Frameworku.
Vytvoření struktury pro parametry modelu inception
Model inception má několik parametrů, které musíte předat. Vytvořte strukturu pro mapování hodnot parametrů na popisné názvy pomocí následujícího kódu hned po inicializaci
mlContext
proměnné: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; }
Vytvoření metody zobrazovacího nástroje
Vzhledem k tomu, že data obrázku a související předpovědi zobrazíte více než jednou, vytvořte metodu zobrazovacího nástroje, která bude zpracovávat zobrazení obrázků a výsledků predikcí.
Vytvořte metodu
DisplayResults()
hned za strukturouInceptionSettings
pomocí následujícího kódu:void DisplayResults(IEnumerable<ImagePrediction> imagePredictionData) { }
Vyplňte text
DisplayResults
metody:foreach (ImagePrediction prediction in imagePredictionData) { Console.WriteLine($"Image: {Path.GetFileName(prediction.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} "); }
Vytvoření metody pro vytvoření předpovědi
Pomocí následujícího kódu vytvořte metodu
ClassifySingleImage()
těsně před metodouDisplayResults()
:void ClassifySingleImage(MLContext mlContext, ITransformer model) { }
ImageData
Vytvořte objekt, který obsahuje plně kvalifikovanou cestu a název souboru obrázku pro jeden .ImagePath
Jako další řádky metodyClassifySingleImage()
přidejte následující kód:var imageData = new ImageData() { ImagePath = _predictSingleImage };
Vytvořte jednu predikci přidáním následujícího kódu jako dalšího řádku metody
ClassifySingleImage
:// Make prediction function (input = ImageData, output = ImagePrediction) var predictor = mlContext.Model.CreatePredictionEngine<ImageData, ImagePrediction>(model); var prediction = predictor.Predict(imageData);
K získání předpovědi použijte metodu Predict(). PredictionEngine je rozhraní API pro pohodlí, které umožňuje provádět předpovědi pro jednu instanci dat.
PredictionEngine
není bezpečná pro přístup z více vláken. Je přijatelné používat v jednovláknovém nebo prototypovém prostředí. Pokud chcete zvýšit výkon a bezpečnost vláken v produkčních prostředích, použijtePredictionEnginePool
službu , která vytvoříPredictionEngine
ObjectPool
objekt objektů pro použití v celé aplikaci. Projděte si tohoto průvodce používánímPredictionEnginePool
ve webovém rozhraní API ASP.NET Core.Poznámka
PredictionEnginePool
rozšíření služby je aktuálně ve verzi Preview.Zobrazte výsledek předpovědi jako další řádek kódu v
ClassifySingleImage()
metodě :Console.WriteLine($"Image: {Path.GetFileName(imageData.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} ");
Vytvoření kanálu modelu ML.NET
Kanál ML.NET modelu je řetězec odhadců. Během výstavby potrubí nedochází k žádnému spuštění. Objekty estimátoru se vytvoří, ale nespustí.
Přidání metody pro vygenerování modelu
Tato metoda je jádrem kurzu. Vytvoří kanál pro model a vytrénuje kanál tak, aby vytvořil model ML.NET. Model se také vyhodnocuje oproti některým dříve neviditelným testovacím datům.
Vytvořte metodu
GenerateModel()
hned za strukturouInceptionSettings
a těsně před metodouDisplayResults()
pomocí následujícího kódu:ITransformer GenerateModel(MLContext mlContext) { }
Přidejte odhadce pro načtení, změnu velikosti a extrahování pixelů z obrazových dat:
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))
Obrazová data je potřeba zpracovat do formátu, který model TensorFlow očekává. V tomto případě se obrázky načtou do paměti, změní se na konzistentní velikost a pixely se extrahují do číselného vektoru.
Přidejte estimátor pro načtení modelu TensorFlow a jeho skóre:
.Append(mlContext.Model.LoadTensorFlowModel(_inceptionTensorFlowModel). ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))
Tato fáze v kanálu načte model TensorFlow do paměti a pak zpracuje vektor hodnot pixelů prostřednictvím sítě modelu TensorFlow. Použití vstupů na model hlubokého učení a generování výstupu pomocí modelu se označuje jako bodování. Při použití celého modelu se při vyhodnocování vytvoří odvození neboli predikce.
V tomto případě použijete celý model TensorFlow s výjimkou poslední vrstvy, což je vrstva, která provádí odvozování. Výstup předposlední vrstvy je označený
softmax_2_preactivation
jako . Výstupem této vrstvy je vlastně vektor vlastností, které charakterizují původní vstupní obrázky.Tento vektor funkcí vygenerovaný modelem TensorFlow se použije jako vstup pro trénovací algoritmus ML.NET.
Přidejte estimátor pro mapování popisků řetězců v trénovacích datech na hodnoty celočíselného klíče:
.Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelKey", inputColumnName: "Label"))
Trenér ML.NET, který je připojen dále, vyžaduje, aby jeho popisky byly ve
key
formátu, a ne ve libovolných řetězcích. Klíč je číslo, které má 1:1 mapování na řetězcovou hodnotu.Přidejte algoritmus trénování ML.NET:
.Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelKey", featureColumnName: "softmax2_pre_activation"))
Přidejte estimátor, který namapuje předpovězenou hodnotu klíče zpět do řetězce:
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabelValue", "PredictedLabel")) .AppendCacheCheckpoint(mlContext);
Trénování modelu
Načtěte trénovací data pomocí obálky LoadFromTextFile . Jako další řádek metody
GenerateModel()
přidejte následující kód:IDataView trainingData = mlContext.Data.LoadFromTextFile<ImageData>(path: _trainTagsTsv, hasHeader: false);
Data v ML.NET jsou reprezentována jako rozhraní IDataView.
IDataView
je flexibilní a efektivní způsob popisu tabulkových dat (číselných a textových). Data je možné načíst z textového souboru nebo v reálném čase (například databáze SQL nebo soubory protokolu) do objektuIDataView
.Trénování modelu pomocí dat načtených výše:
ITransformer model = pipeline.Fit(trainingData);
Metoda
Fit()
trénuje model použitím trénovací datové sady na kanál.
Vyhodnocení přesnosti modelu
Načtěte a transformujte testovací data přidáním následujícího kódu na další řádek
GenerateModel
metody: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);
K vyhodnocení modelu můžete použít několik ukázkových obrázků. Podobně jako trénovací data je potřeba je načíst do objektu
IDataView
, aby je model mohl transformovat.Do metody přidejte
GenerateModel()
následující kód pro vyhodnocení modelu:MulticlassClassificationMetrics metrics = mlContext.MulticlassClassification.Evaluate(predictions, labelColumnName: "LabelKey", predictedLabelColumnName: "PredictedLabel");
Jakmile máte nastavenou předpověď, metoda Evaluate():
- Vyhodnotí model (porovná předpovězené hodnoty s testovací datovou sadou
labels
). - Vrátí metriky výkonu modelu.
- Vyhodnotí model (porovná předpovězené hodnoty s testovací datovou sadou
Zobrazení metrik přesnosti modelu
Pomocí následujícího kódu můžete zobrazit metriky, sdílet výsledky a pak s nimi pracovat:
Console.WriteLine($"LogLoss is: {metrics.LogLoss}"); Console.WriteLine($"PerClassLogLoss is: {String.Join(" , ", metrics.PerClassLogLoss.Select(c => c.ToString()))}");
Pro klasifikaci obrázků se vyhodnocují následující metriky:
Log-loss
– viz Protokol Loss. Chcete, aby se ztráta protokolů co nejvíce blížil nule.Per class Log-loss
. Chcete, aby ztráta protokolů pro jednotlivé třídy byla co nejblíže nule.
Přidejte následující kód, který vrátí natrénovaný model jako další řádek:
return model;
Spusťte aplikaci.
Po vytvoření MLContext třídy přidejte
GenerateModel
volání metody :ITransformer model = GenerateModel(mlContext);
Za volání
GenerateModel()
metody přidejte voláníClassifySingleImage()
metody :ClassifySingleImage(mlContext, model);
Spusťte konzolovou aplikaci (Ctrl + F5). Výsledky by se měly podobat následujícímu výstupu. (Může se zobrazit upozornění nebo zpracování zpráv, ale tyto zprávy byly z důvodu přehlednosti odebrány z následujících výsledků.)
=============== 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
Gratulujeme! Teď jste úspěšně vytvořili klasifikační model v ML.NET pro kategorizaci obrázků pomocí předem vytrénovaného TensorFlowu pro zpracování obrázků.
Zdrojový kód pro tento kurz najdete v úložišti dotnet/samples .
V tomto kurzu jste se naučili:
- Pochopení problému
- Začlenění předem natrénovaného modelu TensorFlow do kanálu ML.NET
- Trénování a vyhodnocení modelu ML.NET
- Klasifikace testovacího obrázku
Podívejte se na úložiště ukázek machine learningu na GitHubu a prozkoumejte rozbalenou ukázku klasifikace obrázků.