Samouczek: automatyczna inspekcja wizualna przy użyciu uczenia transferowego za pomocą interfejsu API klasyfikacji obrazów ML.NET

Dowiedz się, jak wytrenować niestandardowy model uczenia głębokiego przy użyciu uczenia transferowego, wstępnie wytrenowanego modelu TensorFlow i interfejsu API klasyfikacji obrazów ML.NET w celu klasyfikowania obrazów konkretnych powierzchni jako pękniętych lub niezakłanych.

Ten samouczek zawiera informacje na temat wykonywania następujących czynności:

  • Omówienie problemu
  • Dowiedz się więcej o interfejsie API klasyfikacji obrazów ML.NET
  • Omówienie wstępnie wytrenowanego modelu
  • Trenowanie niestandardowego modelu klasyfikacji obrazów TensorFlow przy użyciu uczenia transferowego
  • Klasyfikowanie obrazów przy użyciu modelu niestandardowego

Wymagania wstępne

Omówienie przykładu uczenia transferowego klasyfikacji obrazów

Ten przykład to aplikacja konsolowa platformy .NET Core w języku C#, która klasyfikuje obrazy przy użyciu wstępnie wytrenowanego modelu TensorFlow uczenia głębokiego. Kod dla tego przykładu można znaleźć w przeglądarce przykładów.

Omówienie problemu

Klasyfikacja obrazów to problem z przetwarzaniem obrazów. Klasyfikacja obrazów przyjmuje obraz jako dane wejściowe i kategoryzuje go w określonej klasie. Modele klasyfikacji obrazów są często trenowane przy użyciu uczenia głębokiego i sieci neuronowych. Aby uzyskać więcej informacji, zobacz Uczenie głębokie a uczenie maszynowe .

Oto niektóre scenariusze, w których klasyfikacja obrazów jest przydatna:

  • Rozpoznawanie twarzy
  • Wykrywanie emocji
  • Diagnostyka medyczna
  • Wykrywanie punktów orientacyjnych

Ten samouczek szkoli niestandardowy model klasyfikacji obrazów w celu przeprowadzenia automatycznej inspekcji wizualnej pokładów mostów w celu zidentyfikowania struktur uszkodzonych przez pęknięcia.

interfejs API klasyfikacji obrazów ML.NET

ML.NET zapewnia różne sposoby przeprowadzania klasyfikacji obrazów. Ten samouczek dotyczy uczenia transferowego przy użyciu interfejsu API klasyfikacji obrazów. Interfejs API klasyfikacji obrazów korzysta z TensorFlow.NET, biblioteki niskiego poziomu, która udostępnia powiązania języka C# dla interfejsu API języka C++ w języku TensorFlow.

Co to jest uczenie transferowe?

Uczenie transferowe stosuje wiedzę zdobytą na podstawie rozwiązywania jednego problemu do innego powiązanego problemu.

Trenowanie modelu uczenia głębokiego od podstaw wymaga ustawienia kilku parametrów, dużej ilości oznaczonych danych treningowych i ogromnej ilości zasobów obliczeniowych (setki godzin procesora GPU). Korzystanie ze wstępnie wytrenowanego modelu wraz z uczeniem transferowym umożliwia skrót do procesu trenowania.

Proces trenowania

Interfejs API klasyfikacji obrazów uruchamia proces trenowania przez załadowanie wstępnie wytrenowanego modelu TensorFlow. Proces trenowania składa się z dwóch kroków:

  1. Faza wąskiego gardła
  2. Faza trenowania

Kroki trenowania

Faza wąskiego gardła

W fazie wąskich gardeł jest ładowany zestaw obrazów treningowych, a wartości pikseli są używane jako dane wejściowe lub funkcje dla zamrożonych warstw wstępnie wytrenowanego modelu. Warstwy zamrożone obejmują wszystkie warstwy w sieci neuronowej aż do przedostatniej warstwy, nieformalnie znanej jako warstwa wąskiego gardła. Te warstwy są określane jako zamrożone, ponieważ na tych warstwach nie będzie wykonywane trenowanie, a operacje są przekazywane. W tych zamrożonych warstwach są obliczane wzorce niższego poziomu, które pomagają modelowi rozróżniać różne klasy. Większa liczba warstw, tym większa jest większa liczba warstw intensywnie korzystających z obliczeń. Na szczęście, ponieważ jest to jednorazowe obliczenie, wyniki mogą być buforowane i używane w kolejnych uruchomieniach podczas eksperymentowania z różnymi parametrami.

Faza trenowania

Po obliczeniu wartości wyjściowych z fazy wąskiego gardła są one używane jako dane wejściowe do ponownego trenowania końcowej warstwy modelu. Ten proces jest iteracyjny i jest uruchamiany dla liczby razy określonych przez parametry modelu. Podczas każdego przebiegu są oceniane straty i dokładność. Następnie należy wprowadzić odpowiednie korekty w celu ulepszenia modelu w celu zminimalizowania utraty i maksymalizacji dokładności. Po zakończeniu trenowania dane wyjściowe są dwoma formatami modelu. Jedna z nich to .pb wersja modelu, a druga to .zip ML.NET serializowana wersja modelu. Podczas pracy w środowiskach obsługiwanych przez ML.NET zaleca się użycie .zip wersji modelu. Jednak w środowiskach, w których ML.NET nie jest obsługiwana, możesz użyć .pb wersji.

Omówienie wstępnie wytrenowanego modelu

Wstępnie wytrenowany model używany w tym samouczku jest wariantem 101-warstwowym modelu Residual Network (ResNet) w wersji 2. Oryginalny model jest trenowany do klasyfikowania obrazów w tysiącach kategorii. Model przyjmuje jako dane wejściowe obraz o rozmiarze 224 x 224 i generuje prawdopodobieństwa klasy dla każdej z klas, na których jest trenowany. Część tego modelu służy do trenowania nowego modelu przy użyciu obrazów niestandardowych w celu przewidywania między dwiema klasami.

Tworzenie aplikacji konsolowej

Teraz, gdy masz ogólną wiedzę na temat uczenia transferowego i interfejsu API klasyfikacji obrazów, nadszedł czas na skompilowanie aplikacji.

  1. Utwórz aplikację konsolową języka C# o nazwie "DeepLearning_ImageClassification_Binary". Kliknij przycisk Dalej.

  2. Wybierz platformę .NET 6 jako strukturę do użycia. Kliknij przycisk Utwórz.

  3. Zainstaluj pakiet NuGet Microsoft.ML :

    Uwaga

    W tym przykładzie użyto najnowszej stabilnej wersji pakietów NuGet wymienionych, chyba że określono inaczej.

    1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Zarządzaj pakietami NuGet.
    2. Wybierz pozycję "nuget.org" jako źródło pakietu.
    3. Wybierz kartę Przeglądaj.
    4. Zaznacz pole wyboru Uwzględnij wersję wstępną .
    5. Wyszukaj Microsoft.ML.
    6. Wybierz przycisk Zainstaluj .
    7. Wybierz przycisk OK w oknie dialogowym Podgląd zmian , a następnie wybierz przycisk Akceptuję w oknie dialogowym Akceptacja licencji , jeśli zgadzasz się z postanowieniami licencyjnymi dla pakietów wymienionych.
    8. Powtórz te kroki dla pakietów NuGet Microsoft.ML.Vision, SciSharp.TensorFlow.Redistw wersji 2.3.1 i Microsoft.ML.ImageAnalytics .

Przygotowywanie i interpretacja danych

Uwaga

Zestawy danych na potrzeby tego samouczka pochodzą z firmy Maguire, Marc; Dorafshan, Sattar; i Thomas, Robert J., "SDNET2018: konkretny zestaw danych obrazu crack dla aplikacji uczenia maszynowego" (2018). Przeglądaj wszystkie zestawy danych. Papier 48. https://digitalcommons.usu.edu/all_datasets/48

SDNET2018 to zestaw danych obrazów, który zawiera adnotacje do pękniętych i nie pękniętych konstrukcji betonowych (pomosty, ściany i chodniki).

Przykłady zestawów danych SDNET2018

Dane są zorganizowane w trzech podkatalogach:

  • D zawiera obrazy pomostu
  • P zawiera obrazy chodników
  • W zawiera obrazy ściany

Każdy z tych podkatalogów zawiera dwa dodatkowe prefiksy podkatalogów:

  • C jest prefiksem używanym do pękniętych powierzchni
  • U jest prefiksem używanym do powierzchni bez szczeliny

W tym samouczku są używane tylko obrazy pomostu.

  1. Pobierz zestaw danych i rozpakuj.
  2. Utwórz katalog o nazwie "assets" w projekcie, aby zapisać pliki zestawu danych.
  3. Skopiuj podkatalogi cd i UD z ostatnio rozpakowanego katalogu do katalogu assets .

Tworzenie klas wejściowych i wyjściowych

  1. Otwórz plik Program.cs i zastąp istniejące using instrukcje w górnej części pliku następującym kodem:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.IO;
    using Microsoft.ML;
    using static Microsoft.ML.DataOperationsCatalog;
    using Microsoft.ML.Vision;
    
  2. Program Poniżej klasy w pliku Program.cs utwórz klasę o nazwie ImageData. Ta klasa służy do reprezentowania początkowo załadowanych danych.

    class ImageData
    {
        public string ImagePath { get; set; }
    
        public string Label { get; set; }
    }
    

    ImageData zawiera następujące właściwości:

    • ImagePath to w pełni kwalifikowana ścieżka, w której jest przechowywany obraz.
    • Label to kategoria, do którego należy obraz. Jest to wartość do przewidzenia.
  3. Tworzenie klas dla danych wejściowych i wyjściowych

    1. Poniżej klasy zdefiniuj ImageData schemat danych wejściowych w nowej klasie o nazwie ModelInput.

      class ModelInput
      {
          public byte[] Image { get; set; }
          
          public UInt32 LabelAsKey { get; set; }
      
          public string ImagePath { get; set; }
      
          public string Label { get; set; }
      }
      

      ModelInput zawiera następujące właściwości:

      • Image jest reprezentacją byte[] obrazu. Model oczekuje, że dane obrazu będą tego typu na potrzeby trenowania.
      • LabelAsKey to liczbowa reprezentacja elementu Label.
      • ImagePath to w pełni kwalifikowana ścieżka, w której jest przechowywany obraz.
      • Label to kategoria, do którego należy obraz. Jest to wartość do przewidzenia.

      Tylko Image i LabelAsKey są używane do trenowania modelu i tworzenia przewidywań. Właściwości ImagePath i Label są przechowywane dla wygody w celu uzyskania dostępu do oryginalnej nazwy i kategorii pliku obrazu.

    2. Następnie poniżej klasy zdefiniuj ModelInput schemat danych wyjściowych w nowej klasie o nazwie ModelOutput.

      class ModelOutput
      {
          public string ImagePath { get; set; }
      
          public string Label { get; set; }
      
          public string PredictedLabel { get; set; }
      }
      

      ModelOutput zawiera następujące właściwości:

      • ImagePath to w pełni kwalifikowana ścieżka, w której jest przechowywany obraz.
      • Label to oryginalna kategoria, do którego należy obraz. Jest to wartość do przewidzenia.
      • PredictedLabel jest wartością przewidywaną przez model.

      Podobnie jak w PredictedLabel przypadku ModelInputmetody , tylko element jest wymagany do przewidywania, ponieważ zawiera przewidywanie dokonane przez model. Właściwości ImagePath i Label są zachowywane dla wygody w celu uzyskania dostępu do oryginalnej nazwy i kategorii pliku obrazu.

Tworzenie katalogu obszaru roboczego

Jeśli dane trenowania i walidacji nie zmieniają się często, dobrym rozwiązaniem jest buforowanie obliczonych wartości wąskich gardeł dla dalszych przebiegów.

  1. W projekcie utwórz nowy katalog o nazwie workspace , aby przechowywać obliczone wartości wąskich gardeł i .pb wersję modelu.

Definiowanie ścieżek i inicjowanie zmiennych

  1. W obszarze instrukcji using zdefiniuj lokalizację zasobów, obliczone wartości wąskich gardeł i .pb wersję modelu.

    var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
    var workspaceRelativePath = Path.Combine(projectDirectory, "workspace");
    var assetsRelativePath = Path.Combine(projectDirectory, "assets");
    
  2. Zainicjuj zmienną mlContext przy użyciu nowego wystąpienia obiektu MLContext.

    MLContext mlContext = new MLContext();
    

    Klasa MLContext jest punktem wyjścia dla wszystkich operacji ML.NET, a inicjowanie metody mlContext tworzy nowe środowisko ML.NET, które można udostępnić w obiektach przepływu pracy tworzenia modelu. Jest ona podobna, koncepcyjnie, do DbContext w programie Entity Framework.

Ładowanie danych

Tworzenie metody narzędzia ładowania danych

Obrazy są przechowywane w dwóch podkatalogach. Przed załadowaniem danych należy sformatować je na listę ImageData obiektów. W tym celu utwórz metodę LoadImagesFromDirectory .

IEnumerable<ImageData> LoadImagesFromDirectory(string folder, bool useFolderNameAsLabel = true)
{

}
  1. W pliku LoadImagesFromDirectorydodaj następujący kod, aby pobrać wszystkie ścieżki plików z podkatalogów:

    var files = Directory.GetFiles(folder, "*",
        searchOption: SearchOption.AllDirectories);
    
  2. Następnie iteracja poszczególnych plików przy użyciu foreach instrukcji .

    foreach (var file in files)
    {
    
    }
    
  3. W instrukcji foreach sprawdź, czy rozszerzenia plików są obsługiwane. Interfejs API klasyfikacji obrazów obsługuje formaty JPEG i PNG.

    if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png"))
        continue;
    
    
  4. Następnie pobierz etykietę dla pliku. useFolderNameAsLabel Jeśli parametr jest ustawiony na truewartość , katalog nadrzędny, w którym jest zapisywany plik, jest używany jako etykieta. W przeciwnym razie oczekuje, że etykieta będzie prefiksem nazwy pliku lub samej nazwy pliku.

    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;
            }
        }
    }
    
  5. Na koniec utwórz nowe wystąpienie klasy ModelInput.

    yield return new ImageData()
    {
        ImagePath = file,
        Label = label
    };
    

Przygotowywanie danych

  1. Wywołaj metodę narzędzia, LoadImagesFromDirectory aby uzyskać listę obrazów używanych do trenowania po zainicjowaniu zmiennej mlContext .

    IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);
    
  2. Następnie załaduj obrazy do IDataView metody za pomocą LoadFromEnumerable metody .

    IDataView imageData = mlContext.Data.LoadFromEnumerable(images);
    
  3. Dane są ładowane w kolejności odczytu z katalogów. Aby zrównoważyć dane, przetasuj je przy użyciu ShuffleRows metody .

    IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);
    
  4. Modele uczenia maszynowego oczekują, że dane wejściowe będą w formacie liczbowym. W związku z tym przed rozpoczęciem trenowania należy wykonać pewne wstępne przetwarzanie danych. Utwórz element EstimatorChain składający się z MapValueToKey przekształceń i LoadRawImageBytes . Przekształcenie MapValueToKey przyjmuje wartość kategorii w kolumnie Label , konwertuje ją na wartość liczbową KeyType i przechowuje ją w nowej kolumnie o nazwie LabelAsKey. Parametr LoadImages pobiera wartości z ImagePath kolumny wraz z parametrem imageFolder w celu załadowania obrazów na potrzeby trenowania.

    var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
            inputColumnName: "Label",
            outputColumnName: "LabelAsKey")
        .Append(mlContext.Transforms.LoadRawImageBytes(
            outputColumnName: "Image",
            imageFolder: assetsRelativePath,
            inputColumnName: "ImagePath"));
    
  5. Użyj metody , Fit aby zastosować dane do następującej TransformpreprocessingPipelineEstimatorChain metody, która zwraca IDataView dane zawierające wstępnie przetworzone dane.

    IDataView preProcessedData = preprocessingPipeline
                        .Fit(shuffledData)
                        .Transform(shuffledData);
    
  6. Aby wytrenować model, ważne jest, aby mieć zestaw danych trenowania, a także zestaw danych weryfikacji. Model jest trenowany na zestawie treningowym. Jak dobrze tworzy prognozy dotyczące niezamierzonych danych, są mierzone przez wydajność zestawu walidacji. Na podstawie wyników tej wydajności model wprowadza korekty tego, czego nauczył się w celu poprawy. Zestaw weryfikacji może pochodzić z podziału oryginalnego zestawu danych lub z innego źródła, które zostało już odłożone do tego celu. W takim przypadku wstępnie przetworzony zestaw danych jest podzielony na zestawy trenowania, walidacji i testowania.

    TrainTestData trainSplit = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
    TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);
    

    Powyższy przykład kodu wykonuje dwa podziały. Najpierw dane wstępnie przetworzone są podzielone, a 70% jest używane do trenowania, podczas gdy pozostałe 30% jest używane do walidacji. Następnie zestaw weryfikacji 30% jest dalej podzielony na zestawy weryfikacji i testów, w których do walidacji jest używane 90%, a do testowania jest używane 10%.

    Sposób myślenia o celu tych partycji danych odbywa egzamin. Podczas studiów na egzaminie zapoznasz się z notatkami, książkami lub innymi zasobami, aby zrozumieć pojęcia, które są na egzaminie. Jest to zestaw pociągu dla. Następnie możesz wziąć egzamin pozorny, aby zweryfikować swoją wiedzę. Jest to miejsce, w którym zestaw weryfikacji jest przydatny. Chcesz sprawdzić, czy masz dobre zrozumienie pojęć przed rozpoczęciem rzeczywistego egzaminu. Na podstawie tych wyników zanotujesz to, co się nie stało lub nie rozumiesz dobrze i uwzględnisz zmiany podczas przeglądania rzeczywistego egzaminu. Na koniec przejmiesz egzamin. Jest to zestaw testów używany dla programu . Nigdy nie widziałeś pytań, które znajdują się na egzaminie, a teraz użyjesz tego, czego nauczyłeś się od szkolenia i walidacji, aby zastosować swoją wiedzę do zadania pod ręką.

  7. Przypisz partycje odpowiednie wartości dla danych trenowania, walidacji i testowania.

    IDataView trainSet = trainSplit.TrainSet;
    IDataView validationSet = validationTestSplit.TrainSet;
    IDataView testSet = validationTestSplit.TestSet;
    

Definiowanie potoku trenowania

Trenowanie modelu składa się z kilku kroków. Najpierw interfejs API klasyfikacji obrazów służy do trenowania modelu. Następnie zakodowane etykiety w PredictedLabel kolumnie są konwertowane z powrotem na oryginalną wartość kategorii przy użyciu MapKeyToValue przekształcenia.

  1. Utwórz nową zmienną do przechowywania zestawu wymaganych i opcjonalnych parametrów dla elementu ImageClassificationTrainer.

    var classifierOptions = new ImageClassificationTrainer.Options()
    {
        FeatureColumnName = "Image",
        LabelColumnName = "LabelAsKey",
        ValidationSet = validationSet,
        Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
        MetricsCallback = (metrics) => Console.WriteLine(metrics),
        TestOnTrainSet = false,
        ReuseTrainSetBottleneckCachedValues = true,
        ReuseValidationSetBottleneckCachedValues = true
    };
    

    Element ImageClassificationTrainer przyjmuje kilka parametrów opcjonalnych:

    • FeatureColumnName to kolumna używana jako dane wejściowe dla modelu.
    • LabelColumnName to kolumna dla wartości do przewidzenia.
    • ValidationSet jest elementem IDataView zawierającym dane weryfikacji.
    • Arch definiuje, które z wstępnie wytrenowanych architektur modelu mają być używane. W tym samouczku użyto wariantu 101-warstwowego modelu ResNetv2.
    • MetricsCallback wiąże funkcję w celu śledzenia postępu podczas trenowania.
    • TestOnTrainSet informuje model o mierzenie wydajności względem zestawu treningowego, gdy nie ma zestawu walidacji.
    • ReuseTrainSetBottleneckCachedValues informuje model, czy należy używać buforowanych wartości z fazy wąskiego gardła w kolejnych uruchomieniach. Faza wąskiego gardła jest jednorazowym obliczeniam przekazywanym, które jest intensywnie obciążające obliczenia po raz pierwszy. Jeśli dane szkoleniowe nie zmieniają się i chcesz eksperymentować przy użyciu innej liczby epok lub rozmiaru partii, użycie buforowanych wartości znacznie skraca czas wymagany do trenowania modelu.
    • ReuseValidationSetBottleneckCachedValues jest podobny tylko do ReuseTrainSetBottleneckCachedValues tego, że w tym przypadku jest przeznaczony dla zestawu danych weryfikacji.
    • WorkspacePath definiuje katalog, w którym mają być przechowywane obliczone wąskie gardła i .pb wersja modelu.
  2. Zdefiniuj EstimatorChain potok trenowania, który składa się zarówno z obiektu , jak mapLabelEstimator i .ImageClassificationTrainer

    var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
        .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
    
  3. Fit Użyj metody , aby wytrenować model.

    ITransformer trainedModel = trainingPipeline.Fit(trainSet);
    

Korzystanie z modelu

Teraz, gdy model został wytrenowany, nadszedł czas, aby go używać do klasyfikowania obrazów.

Utwórz nową metodę narzędzia o nazwie OutputPrediction , aby wyświetlić informacje o przewidywaniach w konsoli programu .

private static void OutputPrediction(ModelOutput prediction)
{
    string imageName = Path.GetFileName(prediction.ImagePath);
    Console.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}");
}

Klasyfikowanie pojedynczego obrazu

  1. Utwórz nową metodę o nazwie ClassifySingleImage , aby utworzyć i wygenerować pojedyncze przewidywanie obrazu.

    void ClassifySingleImage(MLContext mlContext, IDataView data, ITransformer trainedModel)
    {
    
    }
    
  2. Utwórz wewnątrz PredictionEngineClassifySingleImage metody . Jest PredictionEngine to wygodny interfejs API, który umożliwia przekazanie, a następnie wykonanie przewidywania dla pojedynczego wystąpienia danych.

    PredictionEngine<ModelInput, ModelOutput> predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(trainedModel);
    
  3. Aby uzyskać dostęp do pojedynczego ModelInput wystąpienia, przekonwertuj element dataIDataView na IEnumerable przy użyciu CreateEnumerable metody , a następnie uzyskaj pierwszą obserwację.

    ModelInput image = mlContext.Data.CreateEnumerable<ModelInput>(data,reuseRowObject:true).First();
    
  4. Predict Użyj metody , aby sklasyfikować obraz.

    ModelOutput prediction = predictionEngine.Predict(image);
    
  5. Wygeneruj przewidywanie do konsoli za pomocą OutputPrediction metody .

    Console.WriteLine("Classifying single image");
    OutputPrediction(prediction);
    
  6. Wywołaj poniższe wywołanie ClassifySingleImageFit metody przy użyciu zestawu testów obrazów.

    ClassifySingleImage(mlContext, testSet, trainedModel);
    

Klasyfikowanie wielu obrazów

  1. Dodaj nową metodę o nazwie ClassifyImages poniżej metody , ClassifySingleImage aby utworzyć i wygenerować wiele przewidywań obrazów.

    void ClassifyImages(MLContext mlContext, IDataView data, ITransformer trainedModel)
    {
    
    }
    
  2. Utwórz element IDataView zawierający przewidywania przy użyciu Transform metody . Dodaj następujący kod wewnątrz ClassifyImages metody .

    IDataView predictionData = trainedModel.Transform(data);
    
  3. Aby iterować przewidywania, przekonwertuj wartość predictionDataIDataView na IEnumerable przy użyciu CreateEnumerable metody , a następnie uzyskaj pierwsze 10 obserwacji.

    IEnumerable<ModelOutput> predictions = mlContext.Data.CreateEnumerable<ModelOutput>(predictionData, reuseRowObject: true).Take(10);
    
  4. Iterowanie i generowanie oryginalnych i przewidywanych etykiet przewidywania.

    Console.WriteLine("Classifying multiple images");
    foreach (var prediction in predictions)
    {
        OutputPrediction(prediction);
    }
    
  5. Na koniec wywołaj ClassifyImages poniżej ClassifySingleImage() metody przy użyciu zestawu testowego obrazów.

    ClassifyImages(mlContext, testSet, trainedModel);
    

Uruchamianie aplikacji

Uruchom aplikację konsolową. Dane wyjściowe powinny być podobne do poniższych. Mogą pojawić się ostrzeżenia lub przetwarzanie komunikatów, ale te komunikaty zostały usunięte z poniższych wyników w celu uzyskania jasności. W przypadku zwięzłości dane wyjściowe zostały skondensowane.

Faza wąskiego gardła

Żadna wartość nie jest drukowana dla nazwy obrazu, ponieważ obrazy są ładowane jako byte[] nazwa obrazu, dlatego nie ma nazwy obrazu do wyświetlenia.

Phase: Bottleneck Computation, Dataset used:      Train, Image Index: 279
Phase: Bottleneck Computation, Dataset used:      Train, Image Index: 280
Phase: Bottleneck Computation, Dataset used: Validation, Image Index:   1
Phase: Bottleneck Computation, Dataset used: Validation, Image Index:   2

Faza trenowania

Phase: Training, Dataset used: Validation, Batch Processed Count:   6, Epoch:  21, Accuracy:  0.6797619
Phase: Training, Dataset used: Validation, Batch Processed Count:   6, Epoch:  22, Accuracy:  0.7642857
Phase: Training, Dataset used: Validation, Batch Processed Count:   6, Epoch:  23, Accuracy:  0.7916667

Klasyfikowanie danych wyjściowych obrazów

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

Po inspekcji obrazu7001-220.jpg widać, że w rzeczywistości nie jest pęknięty.

Obraz zestawu danych SDNET2018 używany do przewidywania

Gratulacje! Udało Ci się utworzyć model uczenia głębokiego do klasyfikowania obrazów.

Ulepszanie modelu

Jeśli wyniki modelu nie są zadowalające, możesz spróbować poprawić jego wydajność, próbując wypróbować niektóre z następujących metod:

  • Więcej danych: Tym więcej przykładów model uczy się od, tym lepiej działa. Pobierz pełny zestaw danych SDNET2018 i użyj go do trenowania.
  • Rozszerzanie danych: typową techniką dodawania różnych danych jest rozszerzenie danych przez utworzenie obrazu i zastosowanie różnych przekształceń (obracanie, przerzucanie, przesunięcie, przycinanie). Dodaje to bardziej zróżnicowane przykłady dla modelu, z których można się uczyć.
  • Trenowanie przez dłuższy czas: tym dłużej trenujesz, tym bardziej dostrojony będzie model. Zwiększenie liczby epok może zwiększyć wydajność modelu.
  • Eksperymentuj z hiperparami: oprócz parametrów używanych w tym samouczku można dostroić inne parametry, aby potencjalnie poprawić wydajność. Zmiana szybkości nauki, która określa wielkość aktualizacji w modelu po każdej epoki może poprawić wydajność.
  • Użyj innej architektury modelu: w zależności od wyglądu danych model, który może najlepiej poznać jego funkcje, może się różnić. Jeśli nie jesteś zadowolony z wydajności modelu, spróbuj zmienić architekturę.

Następne kroki

W tym samouczku przedstawiono sposób tworzenia niestandardowego modelu uczenia głębokiego przy użyciu uczenia transferowego, wstępnie wytrenowanego modelu klasyfikacji obrazów TensorFlow i interfejsu API klasyfikacji obrazów ML.NET w celu klasyfikowania obrazów betonowych powierzchni jako pękniętych lub niezakłęconych.

Przejdź do następnego samouczka, aby dowiedzieć się więcej.