Sdílet prostřednictvím


Kurz: Trénování klasifikačního modelu ML.NET za účelem kategorizace obrázků

Naučte se trénovat klasifikační model pro kategorizaci obrázků pomocí předem natré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 rozpoznat vzory v obrázcích, může model ML.NET využít jeho část v kanálu k převodu nezpracovaných obrázků na funkce nebo vstupy k trénování klasifikačního modelu.

V tomto návodu se naučíte, jak:

  • Pochopení problému
  • Začlenění předtrénovaného modelu TensorFlow do ML.NET pipeline
  • 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í cílí konfigurace projektu .NET pro tento kurz na .NET Core 2.2.

Požadavky

Výběr správné úlohy strojového učení

Hluboké učení

Hluboké učení je podmnožinou strojového učení, což je revoluční oblast, 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í:

  • Funguje lépe na některých úkolech, jako je počítačové zpracování obrazu.
  • Vyžaduje obrovské množství trénovacích dat.

Klasifikace obrázků je konkrétní úloha klasifikace, která nám umožňuje automaticky klasifikovat obrázky do kategorií, jako jsou:

  • Rozpoznání lidské tváře na obrázku nebo ne.
  • Zjišťování koček vs. psů.

Na následujících obrázcích se určuje, jestli se jedná o jídlo, hračku nebo zařízení.

obrázek pizzy obrázek medvídka obrázek toustovače

Poznámka:

Předchozí obrázky patří do Wikimedia Commons a přiřazují se následujícím způsobem:

Trénování modelu klasifikace obrázků od začátku vyžaduje nastavení milionů parametrů, tunu označených trénovacích dat a obrovské množství výpočetních prostředků (stovky hodin GPU). I když není tak účinné jako trénování vlastního modelu od nuly, použití předem natrénovaného modelu umožňuje tento proces obejít tím, že pracujete s tisíci obrázky oproti milionům označených obrázků a sestavit přizpůsobený model poměrně rychle (během hodiny, na počítači bez GPU). Tento kurz škáluje proces ještě dál a používá jen tucet trénovacích obrázků.

Inception model je vytrénován tak, aby klasifikoval obrázky do tisíce kategorií, ale v tomto kurzu potřebujete klasifikovat obrázky v menší sadě kategorií a pouze v těch. Pomocí Inception modelmožnosti rozpoznávat a klasifikovat obrázky do nových omezených kategorií vlastního klasifikátoru obrázků.

  • Jídlo
  • Hračka
  • Zařízení

V tomto kurzu se používá model hlubokého učení TensorFlow, což je oblíbený model rozpoznávání obrázků natrénovaný v ImageNet datové sadě. Model TensorFlow klasifikuje celé obrázky do tisíc tříd, například "Umbrella", "Jersey" a "Myčka".

Vzhledem k tomu, že už Inception model je předem natrénovaný na tisících různých imagí, interně obsahuje funkce obrázku potřebné k identifikaci obrázku. Tyto funkce interních imagí 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 balíčky NuGet ML.NET v aplikacích .NET nebo .NET Framework. Pod povrchem ML.NET zahrnuje a odkazuje na nativní TensorFlow knihovnu, která umožňuje napsání kódu pro načtení existujícího natrénovaného TensorFlow souboru modelu.

Architektonický diagram transformace TensorFlow v ML.NET

Klasifikace s více třídami

Po použití modelu inception TensorFlow k extrakci funkcí vhodných jako vstup pro klasický algoritmus strojového učení přidáte ML.NET klasifikátor více tříd.

Konkrétním trenérem používaným v tomto případě je multinomický logistický regresní algoritmus.

Algoritmus implementovaný tímto trenérem funguje dobře na problémech s velkým počtem funkcí, což je případ modelu hlubokého učení, který pracuje s daty obrazu.

Další informace najdete v tématu Hluboké učení vs. strojové učení.

Data

Existují dva zdroje dat: .tsv soubor a soubory obrázků. Soubor tags.tsv obsahuje dva sloupce: první sloupec je definován jako ImagePath, a druhý sloupec je Label odpovídající obrázku. Následující ukázkový soubor neobsahuje řá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.

Wikimedia Commons, bezplatné úložiště médií. 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 Next.

  2. Jako architekturu, která se má použít, zvolte .NET 8. 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íku ř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 Instalovat.
    • 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ě Přijetí licence tlačítko Přijmout.
    • Opakujte tyto kroky pro Microsoft.ML.ImageAnalytics, SciSharp.TensorFlow.Redist a Microsoft.ML.TensorFlow.

Stažení prostředků

  1. Stáhněte soubor ZIP adresáře zdrojů 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ých pro tento kurz.

  3. Stáhněte model Inception a rozbalte jej.

  4. Zkopírujte obsah adresáře inception5h, který jste právě rozbalili, do adresáře TransferLearningTF vašeho projektu assets/inception. 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 Inception

  5. V Průzkumníku řešení klikněte pravým tlačítkem na všechny soubory v adresáři prostředků a podadresářích 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ší“.

Vytváření tříd a definování cest

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

    using Microsoft.ML;
    using Microsoft.ML.Data;
    
  2. Přidejte následující kód na řádek přímo pod using direktivy pro určení cest assetu:

    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 vstupní třída dat obrázku a má 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 predikce obrázku a má následující pole:

    • Score obsahuje procento spolehlivosti pro danou klasifikaci obrázků.
    • PredictedLabelValue obsahuje hodnotu pro předpovězený štítek klasifikace obrázků.

    ImagePrediction je třída použitá pro predikci po vytrénování modelu. Má string (ImagePath) pro cestu k obrázku. Slouží Label k opakovanému použití a trénování modelu. Používá se PredictedLabelValue při predikci a vyhodnocení. Pro vyhodnocení se použije vstup s trénovacími daty, predikovanými hodnotami a modelem.

Inicializujte proměnné

  1. Inicializace mlContext proměnné s novou instancí MLContext. Console.WriteLine("Hello World!") Řádek nahraďte 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 napříč objekty pracovního postupu vytváření modelu. Je to podobné, koncepčně, jako DBContext v Entity Frameworku.

Vytvoření struktury pro parametry modelu inception

  1. Model inception má několik parametrů, které je potřeba předat. Vytvořte strukturu, která mapuje hodnoty parametrů na uživatelsky přívětivé názvy s následujícím kódem 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 nástroje pro zobrazení

Jelikož budete data obrázku a příslušné předpovědi zobrazovat vícekrát, vytvořte pomocnou metodu pro zajištění zobrazení obrázku a výsledků predikcí.

  1. Vytvořte metodu DisplayResults()InceptionSettings hned za strukturou 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. Vytvořte ImageData objekt, který obsahuje plně kvalifikovanou cestu a název souboru obrázku pro jeden ImagePath. Přidejte následující kód jako další řádky v ClassifySingleImage() metodě:

    var imageData = new ImageData()
    {
        ImagePath = _predictSingleImage
    };
    
  3. Vytvořte jednu předpověď tak, že do metody přidáte následující kód jako další řádek 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 pohodlné rozhraní API, které umožňuje provádět predikce pro jednu instanci dat. PredictionEngine není bezpečný pro přístup z více vláken. Je přijatelné použít 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ří ObjectPoolPredictionEngine objekty pro použití v celé aplikaci. V tomto průvodci se dozvíte, jak používat PredictionEnginePool webové rozhraní API ASP.NET Core.

    Poznámka:

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

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

Potrubí modelu ML.NET je řetězec odhadců. Během sestavování potrubí nedojde 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. Vyhodnocuje také model oproti některým dříve nezoznaným testovacím datům.

    Pomocí následujícího kódu vytvořte metodu GenerateModel()InceptionSettings hned za strukturou a těsně před DisplayResults() metodou:

    ITransformer GenerateModel(MLContext mlContext)
    {
    
    }
    
  2. Přidejte odhadátory pro načtení, změnu velikosti a extrahování pixelů z dat obrázku:

    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))
    

    Data obrázku je potřeba zpracovat ve 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 odhadce pro načtení modelu TensorFlow a pro jeho vyhodnocení.

    .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í modelu v celém rozsahu provede bodování odvozování nebo predikci.

    V tomto případě použijete veškerý model TensorFlow s výjimkou poslední vrstvy, což je vrstva, která odvozuje. Výstup předposlední vrstvy je označen softmax_2_preactivation. Výstup této vrstvy je v podstatě vektorem vlastností, které charakterizují původní vstupní obrázky.

    Tento vektor funkce generovaný modelem TensorFlow se použije jako vstup do trénovacího algoritmu ML.NET.

  4. Přidejte odhadovač pro mapování popisků řetězců ve výukových datech na celočíselné klíčové hodnoty:

    .Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelKey", inputColumnName: "Label"))
    

    Trénovací algoritmus ML.NET, který je připojen následovně, vyžaduje, aby jeho popisky byly ve formátu key, nikoli jako libovolné řetězce. Klíč je číslo, které má jednoznačné přiřazení k řetězcové hodnotě.

  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 pro namapování predikované hodnoty 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í, efektivní způsob popisu tabulkových dat (číselných a textových). Data lze načíst z textového souboru nebo v reálném čase (například z databáze SQL nebo souborů protokolu) do objektu IDataView .

  2. Trénování modelu s daty načtenými 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 následující kód GenerateModel() pro vyhodnocení modelu:

    MulticlassClassificationMetrics metrics =
        mlContext.MulticlassClassification.Evaluate(predictions,
            labelColumnName: "LabelKey",
            predictedLabelColumnName: "PredictedLabel");
    

    Jakmile máte nastavenou predikci, metoda Evaluate():

    • Vyhodnotí model (porovná predikované 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 zobrazte metriky, sdílejte výsledky a pak s nimi zareagujte:

    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 Ztráta protokolu. Chcete, aby ztráta protokolu byla co nejblíže nule.
    • Per class Log-loss. Pro každou třídu chcete, aby ztráta protokolu byla co nejblíže nule.
  4. Přidejte následující kód, který vrátí natrénovaný model jako další řádek:

    return model;
    

Spuštění aplikace

  1. Přidejte volání na GenerateModel po vytvoření třídy MLContext.

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

    ClassifySingleImage(mlContext, model);
    
  3. Spusťte konzolovou aplikaci (Ctrl + F5). Výsledky by měly být podobné následujícímu výstupu. (Může se zobrazit upozornění nebo zprávy o zpracování, ale tyto zprávy byly z následujících výsledků odstraněny pro větší přehlednost.)

    =============== 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 natré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ředtrénovaného modelu TensorFlow do ML.NET pipeline
  • Trénování a vyhodnocení modelu ML.NET
  • Klasifikace testovacího obrázku

Podívejte se na úložiště GitHub s ukázkami služby Machine Learning a prozkoumejte rozbalenou ukázku klasifikace obrázků.