Samouczek: analizowanie tonacji recenzji filmów przy użyciu wstępnie wytrenowanego modelu TensorFlow w ML.NET
W tym samouczku pokazano, jak używać wstępnie wytrenowanego modelu TensorFlow do klasyfikowania tonacji w komentarzach witryny internetowej. Klasyfikator tonacji binarnej to aplikacja konsolowa języka C# opracowana przy użyciu programu Visual Studio.
Model TensorFlow używany w tym samouczku został wytrenowany przy użyciu recenzji filmów z bazy danych IMDB. Po zakończeniu tworzenia aplikacji będzie można podać tekst recenzji filmu, a aplikacja poinformuje Cię, czy recenzja ma pozytywną, czy negatywną tonację.
Ten samouczek zawiera informacje na temat wykonywania następujących czynności:
- Ładowanie wstępnie wytrenowanego modelu TensorFlow
- Przekształcanie tekstu komentarza witryny internetowej w funkcje odpowiednie dla modelu
- Używanie modelu do przewidywania
Kod źródłowy tego samouczka można znaleźć w repozytorium dotnet/samples .
Wymagania wstępne
- Program Visual Studio 2022 z zainstalowanym obciążeniem ".NET Desktop Development".
Konfigurowanie
Tworzenie aplikacji
Utwórz aplikację konsolową języka C# o nazwie "TextClassificationTF". Kliknij przycisk Dalej.
Wybierz platformę .NET 6 jako platformę do użycia. Kliknij przycisk Utwórz.
Utwórz katalog o nazwie Dane w projekcie, aby zapisać pliki zestawu danych.
Zainstaluj pakiet NuGet Microsoft.ML:
Uwaga
W tym przykładzie użyto najnowszej stabilnej wersji pakietów NuGet wymienionych, chyba że określono inaczej.
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Zarządzaj pakietami NuGet. Wybierz pozycję "nuget.org" jako źródło pakietu, a następnie wybierz kartę Przeglądaj . Wyszukaj Microsoft.ML, wybierz odpowiedni pakiet, a następnie wybierz przycisk Zainstaluj . Kontynuuj instalację, zgadzając się na postanowienia licencyjne dotyczące wybranego pakietu. Powtórz te kroki dla bibliotek Microsoft.ML.TensorFlow, Microsoft.ML.SampleUtils i SciSharp.TensorFlow.Redist.
Dodawanie modelu TensorFlow do projektu
Uwaga
Model tego samouczka pochodzi z repozytorium GitHub dotnet/machinelearning-testdata . Model jest w formacie TensorFlow SavedModel.
Pobierz plik zip sentiment_model i rozpakuj.
Plik zip zawiera:
saved_model.pb
: sam model TensorFlow. Model przyjmuje tablicę całkowitą o stałej długości (rozmiar 600) funkcji reprezentujących tekst w ciągu przeglądu imDB i generuje dwa prawdopodobieństwa, które sumują się do 1: prawdopodobieństwo, że przegląd danych wejściowych ma pozytywną tonację i prawdopodobieństwo, że przegląd wejściowy ma negatywną tonację.imdb_word_index.csv
: mapowanie z poszczególnych wyrazów na wartość całkowitą. Mapowanie służy do generowania funkcji wejściowych dla modelu TensorFlow.
Skopiuj zawartość najbardziej
sentiment_model
wewnętrznego katalogu do katalogu projektusentiment_model
TextClassificationTF. Ten katalog zawiera model i dodatkowe pliki pomocy technicznej potrzebne do tego samouczka, jak pokazano na poniższej ilustracji:W Eksplorator rozwiązań kliknij prawym przyciskiem myszy każdy z plików w katalogu i podkatalogu
sentiment_model
, a następnie wybierz polecenie Właściwości. W obszarze Zaawansowane zmień wartość opcji Kopiuj do katalogu wyjściowego , aby skopiować, jeśli jest nowsza.
Dodawanie instrukcji using i zmiennych globalnych
Dodaj następujące dodatkowe
using
instrukcje na początku pliku Program.cs :using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms;
Utwórz zmienną globalną bezpośrednio po instrukcjach using do przechowywania zapisanej ścieżki pliku modelu.
string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
_modelPath
to ścieżka pliku wytrenowanego modelu.
Modelowanie danych
Recenzje filmów są wolnym tekstem formularza. Aplikacja konwertuje tekst na format wejściowy oczekiwany przez model w wielu dyskretnych etapach.
Pierwszą z nich jest podzielenie tekstu na oddzielne wyrazy i użycie dostarczonego pliku mapowania w celu zamapowania każdego wyrazu na kodowanie całkowite. Wynikiem tej transformacji jest zmienna długość tablicy całkowitej o długości odpowiadającej liczbie wyrazów w zdaniu.
Właściwość | Wartość | Typ |
---|---|---|
Przeglądanie tekstu | ten film jest naprawdę dobry | ciąg |
VariableLengthFeatures | 14,22,9,66,78,... | int[] |
Tablica funkcji o zmiennej długości jest następnie zmieniana na stałą długość 600. Jest to długość oczekiwana przez model TensorFlow.
Właściwość | Wartość | Typ |
---|---|---|
Przeglądanie tekstu | ten film jest naprawdę dobry | ciąg |
VariableLengthFeatures | 14,22,9,66,78,... | int[] |
Funkcje | 14,22,9,66,78,... | int[600] |
Utwórz klasę danych wejściowych w dolnej części pliku Program.cs :
/// <summary> /// Class to hold original sentiment data. /// </summary> public class MovieReview { public string? ReviewText { get; set; } }
Klasa danych wejściowych,
MovieReview
, ma wartośćstring
dla komentarzy użytkownika (ReviewText
).Utwórz klasę dla funkcji o zmiennej
MovieReview
długości po klasie:/// <summary> /// Class to hold the variable length feature vector. Used to define the /// column names used as input to the custom mapping action. /// </summary> public class VariableLength { /// <summary> /// This is a variable length vector designated by VectorType attribute. /// Variable length vectors are produced by applying operations such as 'TokenizeWords' on strings /// resulting in vectors of tokens of variable lengths. /// </summary> [VectorType] public int[]? VariableLengthFeatures { get; set; } }
Właściwość
VariableLengthFeatures
ma atrybut VectorType , aby wyznaczyć go jako wektor. Wszystkie elementy wektorów muszą być tego samego typu. W zestawach danych z dużą liczbą kolumn ładowanie wielu kolumn jako pojedynczego wektora zmniejsza liczbę przepływów danych podczas stosowania przekształceń danych.Ta klasa jest używana w
ResizeFeatures
akcji. Nazwy jego właściwości (w tym przypadku tylko jeden) są używane do wskazywania, które kolumny w widoku DataView mogą być używane jako dane wejściowe do niestandardowej akcji mapowania.Utwórz klasę dla funkcji o stałej długości po
VariableLength
klasie:/// <summary> /// Class to hold the fixed length feature vector. Used to define the /// column names used as output from the custom mapping action, /// </summary> public class FixedLength { /// <summary> /// This is a fixed length vector designated by VectorType attribute. /// </summary> [VectorType(Config.FeatureLength)] public int[]? Features { get; set; } }
Ta klasa jest używana w
ResizeFeatures
akcji. Nazwy jego właściwości (w tym przypadku tylko jeden) są używane do wskazywania, które kolumny w widoku DataView mogą być używane jako dane wyjściowe akcji mapowania niestandardowego.Należy pamiętać, że nazwa właściwości
Features
jest określana przez model TensorFlow. Nie można zmienić tej nazwy właściwości.Utwórz klasę przewidywania po
FixedLength
klasie:/// <summary> /// Class to contain the output values from the transformation. /// </summary> public class MovieReviewSentimentPrediction { [VectorType(2)] public float[]? Prediction { get; set; } }
MovieReviewSentimentPrediction
jest klasą przewidywania używaną po trenowaniu modelu.MovieReviewSentimentPrediction
ma pojedyncząfloat
tablicęVectorType
(Prediction
) i atrybut.Utwórz inną klasę do przechowywania wartości konfiguracji, takich jak długość wektora funkcji:
static class Config { public const int FeatureLength = 600; }
Tworzenie tekstu MLContext, słownika odnośników i akcji w celu zmiany rozmiaru funkcji
Klasa MLContext jest punktem wyjścia dla wszystkich operacji ML.NET. Inicjowanie 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.
Console.WriteLine("Hello World!")
Zastąp wiersz następującym kodem, aby zadeklarować i zainicjować zmienną mlContext:MLContext mlContext = new MLContext();
Utwórz słownik, aby kodować wyrazy jako liczby całkowite przy użyciu
LoadFromTextFile
metody w celu załadowania danych mapowania z pliku, jak pokazano w poniższej tabeli:Word Indeks Dzieci 362 chcę 181 Nieodpowiednim 355 effects 302 Uczucie 547 Dodaj poniższy kod, aby utworzyć mapę odnośników:
var lookupMap = mlContext.Data.LoadFromTextFile(Path.Combine(_modelPath, "imdb_word_index.csv"), columns: new[] { new TextLoader.Column("Words", DataKind.String, 0), new TextLoader.Column("Ids", DataKind.Int32, 1), }, separatorChar: ',' );
Dodaj element ,
Action
aby zmienić rozmiar tablicy liczb całkowitych słowa o zmiennej długości do tablicy całkowitej o stałym rozmiarze z następnymi wierszami kodu:Action<VariableLength, FixedLength> ResizeFeaturesAction = (s, f) => { var features = s.VariableLengthFeatures; Array.Resize(ref features, Config.FeatureLength); f.Features = features; };
Ładowanie wstępnie wytrenowanego modelu TensorFlow
Dodaj kod, aby załadować model TensorFlow:
TensorFlowModel tensorFlowModel = mlContext.Model.LoadTensorFlowModel(_modelPath);
Po załadowaniu modelu można wyodrębnić jego schemat wejściowy i wyjściowy. Schematy są wyświetlane tylko dla zainteresowań i nauki. Nie potrzebujesz tego kodu, aby aplikacja końcowa działała:
DataViewSchema schema = tensorFlowModel.GetModelSchema(); Console.WriteLine(" =============== TensorFlow Model Schema =============== "); var featuresType = (VectorDataViewType)schema["Features"].Type; Console.WriteLine($"Name: Features, Type: {featuresType.ItemType.RawType}, Size: ({featuresType.Dimensions[0]})"); var predictionType = (VectorDataViewType)schema["Prediction/Softmax"].Type; Console.WriteLine($"Name: Prediction/Softmax, Type: {predictionType.ItemType.RawType}, Size: ({predictionType.Dimensions[0]})");
Schemat wejściowy to tablica o stałej długości zakodowanych wyrazów całkowitych. Schemat wyjściowy to tablica zmiennoprzecinkowa prawdopodobieństwa wskazująca, czy tonacja przeglądu jest ujemna, czy dodatnia. Te wartości sumuje się do 1, ponieważ prawdopodobieństwo dodatniego jest uzupełnieniem prawdopodobieństwa, że tonacja jest ujemna.
Tworzenie potoku ML.NET
Utwórz potok i podziel tekst wejściowy na wyrazy przy użyciu przekształcenia TokenizeIntoWords , aby podzielić tekst na wyrazy jako następny wiersz kodu:
IEstimator<ITransformer> pipeline = // Split the text into individual words mlContext.Transforms.Text.TokenizeIntoWords("TokenizedWords", "ReviewText")
Przekształcenie TokenizeIntoWords używa spacji do analizowania tekstu/ciągu na wyrazy. Tworzy nową kolumnę i dzieli każdy ciąg wejściowy na wektor podciągów na podstawie separatora zdefiniowanego przez użytkownika.
Zamapuj wyrazy na kodowanie całkowite przy użyciu tabeli odnośników zadeklarowanej powyżej:
// Map each word to an integer value. The array of integer makes up the input features. .Append(mlContext.Transforms.Conversion.MapValue("VariableLengthFeatures", lookupMap, lookupMap.Schema["Words"], lookupMap.Schema["Ids"], "TokenizedWords"))
Zmień rozmiar kodowań liczb całkowitych o zmiennej długości na stałą długość wymaganą przez model:
// Resize variable length vector to fixed length vector. .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
Klasyfikowanie danych wejściowych przy użyciu załadowanego modelu TensorFlow:
// Passes the data to TensorFlow for scoring .Append(tensorFlowModel.ScoreTensorFlowModel("Prediction/Softmax", "Features"))
Dane wyjściowe modelu TensorFlow są nazywane
Prediction/Softmax
. Należy pamiętać, że nazwaPrediction/Softmax
jest określana przez model TensorFlow. Nie można zmienić tej nazwy.Utwórz nową kolumnę dla przewidywania danych wyjściowych:
// Retrieves the 'Prediction' from TensorFlow and copies to a column .Append(mlContext.Transforms.CopyColumns("Prediction", "Prediction/Softmax"));
Należy skopiować kolumnę
Prediction/Softmax
do jednej z nazwą, która może być używana jako właściwość w klasie C#:Prediction
. Znak/
nie jest dozwolony w nazwie właściwości języka C#.
Tworzenie modelu ML.NET na podstawie potoku
Dodaj kod, aby utworzyć model z potoku:
// Create an executable model from the estimator pipeline IDataView dataView = mlContext.Data.LoadFromEnumerable(new List<MovieReview>()); ITransformer model = pipeline.Fit(dataView);
Model ML.NET jest tworzony na podstawie łańcucha narzędzi do szacowania w potoku przez wywołanie
Fit
metody . W tym przypadku nie dopasowujemy żadnych danych do utworzenia modelu, ponieważ model TensorFlow został już wcześniej wytrenowany. Dostarczamy pusty obiekt widoku danych, aby spełnić wymaganiaFit
metody.
Używanie modelu do przewidywania
Dodaj metodę
PredictSentiment
nad klasąMovieReview
:void PredictSentiment(MLContext mlContext, ITransformer model) { }
Dodaj następujący kod, aby utworzyć
PredictionEngine
element jako pierwszy wiersz w metodziePredictSentiment()
:var engine = mlContext.Model.CreatePredictionEngine<MovieReview, MovieReviewSentimentPrediction>(model);
PredictionEngine to wygodny interfejs API, który umożliwia przewidywanie dla pojedynczego wystąpienia danych.
PredictionEngine
nie jest bezpieczne wątkowo. Dopuszczalne jest użycie w środowiskach jednowątkowych lub prototypowych. Aby zwiększyć wydajność i bezpieczeństwo wątków w środowiskach produkcyjnych, użyjPredictionEnginePool
usługi, która tworzyObjectPool
PredictionEngine
obiekty do użycia w całej aplikacji. Zobacz ten przewodnik dotyczący używaniaPredictionEnginePool
w internetowym interfejsie API ASP.NET Core.Uwaga
PredictionEnginePool
Rozszerzenie usługi jest obecnie w wersji zapoznawczej.Dodaj komentarz, aby przetestować przewidywanie wytrenowanego modelu w metodzie
Predict()
, tworząc wystąpienie klasyMovieReview
:var review = new MovieReview() { ReviewText = "this film is really good" };
Przekaż dane komentarza testowego do
Prediction Engine
obiektu, dodając kolejne wiersze kodu w metodziePredictSentiment()
:var sentimentPrediction = engine.Predict(review);
Funkcja Predict() tworzy przewidywanie dla pojedynczego wiersza danych:
Właściwość Wartość Typ Przewidywanie [0.5459937, 0.454006255] float[] Wyświetl przewidywanie tonacji przy użyciu następującego kodu:
Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}"); Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
Dodaj wywołanie metody
PredictSentiment
po wywołaniuFit()
metody:PredictSentiment(mlContext, model);
Wyniki
Skompiluj i uruchom aplikację.
Wyniki powinny być podobne do poniższych. Podczas przetwarzania są wyświetlane komunikaty. Mogą pojawić się ostrzeżenia lub komunikaty przetwarzania. Te komunikaty zostały usunięte z poniższych wyników w celu uzyskania jasności.
Number of classes: 2
Is sentiment/review positive ? Yes
Gratulacje! Udało Ci się pomyślnie skompilować model uczenia maszynowego do klasyfikowania i przewidywania tonacji komunikatów przez ponowne korzystanie z wstępnie wytrenowanego TensorFlow
modelu w ML.NET.
Kod źródłowy tego samouczka można znaleźć w repozytorium dotnet/samples .
W niniejszym samouczku zawarto informacje na temat wykonywania następujących czynności:
- Ładowanie wstępnie wytrenowanego modelu TensorFlow
- Przekształcanie tekstu komentarza witryny internetowej w funkcje odpowiednie dla modelu
- Używanie modelu do przewidywania