Sdílet prostřednictvím


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:

pizza obrázekteddy medvěd imagetoustovač obrázek

Poznámka

Předchozí obrázky patří do Wikimedia Commons a mají následující atributy:

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 modelv 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.

Diagram transformace tensorFlow ML.NET oblouku

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

  1. Vytvořte konzolovou aplikaci jazyka C# s názvem TransferLearningTF. Klikněte na tlačítko Další .

  2. Jako architekturu, kterou chcete použít, zvolte .NET 6. Klikněte na tlačítko Vytvořit.

  3. 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ů

  1. Stáhněte soubor ZIP adresáře assetů projektu a rozbalte ho.

  2. 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.

  3. Stáhněte si model inception a rozbalte ho.

  4. Zkopírujte obsah adresáře, který inception5h jste právě rozbalili, do adresáře projektu assets/inceptionTransferLearningTF. 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:

    Obsah adresáře pro inception

  5. 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

  1. Na začátek souboru Program.cs přidejte následující další using příkazy:

    using Microsoft.ML;
    using Microsoft.ML.Data;
    
  2. 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");
    
  3. 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.
  4. 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 se PredictedLabelValue 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

  1. 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

  1. 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í.

  1. Vytvořte metodu DisplayResults() hned za strukturou InceptionSettings pomocí následujícího kódu:

    void DisplayResults(IEnumerable<ImagePrediction> imagePredictionData)
    {
    
    }
    
  2. 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

  1. Pomocí následujícího kódu vytvořte metodu ClassifySingleImage() těsně před metodou DisplayResults() :

    void ClassifySingleImage(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. ImageData Vytvořte objekt, který obsahuje plně kvalifikovanou cestu a název souboru obrázku pro jeden .ImagePath Jako další řádky metody ClassifySingleImage() přidejte následující kód:

    var imageData = new ImageData()
    {
        ImagePath = _predictSingleImage
    };
    
  3. 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žijte PredictionEnginePool službu , která vytvoří PredictionEngineObjectPool objekt objektů pro použití v celé aplikaci. Projděte si tohoto průvodce používáním PredictionEnginePool ve webovém rozhraní API ASP.NET Core.

    Poznámka

    PredictionEnginePool rozšíření služby je aktuálně ve verzi Preview.

  4. 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í.

  1. 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 strukturou InceptionSettings a těsně před metodou DisplayResults() pomocí následujícího kódu:

    ITransformer GenerateModel(MLContext mlContext)
    {
    
    }
    
  2. 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.

  3. 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_preactivationjako . 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.

  4. 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.

  5. Přidejte algoritmus trénování ML.NET:

    .Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelKey", featureColumnName: "softmax2_pre_activation"))
    
  6. 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

  1. 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 objektu IDataView .

  2. 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

  1. 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.

  2. 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.
  3. 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.
  4. Přidejte následující kód, který vrátí natrénovaný model jako další řádek:

    return model;
    

Spusťte aplikaci.

  1. Po vytvoření MLContext třídy přidejte GenerateModel volání metody :

    ITransformer model = GenerateModel(mlContext);
    
  2. Za volání GenerateModel() metody přidejte volání ClassifySingleImage() metody :

    ClassifySingleImage(mlContext, model);
    
  3. 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ů.