Tutorial: Analysieren der Stimmung von Filmkritiken mithilfe eines vortrainierten TensorFlow-Modells in ML.NET

In diesem Tutorial wird gezeigt, wie Sie ein vortrainiertes TensorFlow-Modell verwenden, um die Stimmung in Websitekommentaren zu klassifizieren. Der binäre Stimmungsklassifizierer ist eine C#-Konsolenanwendung, die mit Visual Studio entwickelt wurde.

Das in diesem Tutorial verwendete TensorFlow-Modell wurde mithilfe der Filmkritiken aus der IMDB-Datenbank trainiert. Sobald Sie die Entwicklung der Anwendung abgeschlossen haben, können Sie Filmkritiktext bereitstellen. Die Anwendung informiert Sie dann, ob die Rezension eine positive oder negative Stimmung hat.

In diesem Tutorial lernen Sie, wie die folgenden Aufgaben ausgeführt werden:

  • Laden eines vortrainierten TensorFlow-Modells
  • Umwandeln von Websitekommentartext in für das Modell geeignete Merkmale
  • Verwenden des Modells für Vorhersagen

Sie finden den Quellcode für dieses Tutorial im Repository dotnet/samples.

Voraussetzungen

Setup

Erstellen der Anwendung

  1. Erstellen Sie eine C#-Konsolenanwendung mit dem Namen „TextClassificationTF“. Klicken Sie auf die Schaltfläche Weiter.

  2. Wählen Sie .NET 6 als zu verwendendes Framework aus. Klicken Sie auf die Schaltfläche Erstellen .

  3. Erstellen Sie ein Verzeichnis mit dem Namen Data in Ihrem Projekt, um die Datasetdateien zu speichern.

  4. Installieren des Microsoft.ML NuGet-Pakets:

    Hinweis

    In diesem Beispiel wird, sofern nicht anders angegeben, die neueste stabile Version der genannten NuGet-Pakete verwendet.

    Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie NuGet-Pakete verwalten aus. Wählen Sie „nuget.org“ als Paketquelle aus und anschließend die Registerkarte Durchsuchen. Suchen Sie nach Microsoft.ML, wählen Sie das gewünschte Paket aus, und wählen Sie dann die Schaltfläche Installieren aus. Fahren Sie mit der Installation fort, indem Sie den Lizenzbedingungen für das von Ihnen gewählte Paket zustimmen. Wiederholen Sie diese Schritte für Microsoft.ML.TensorFlow, Microsoft.ML.SampleUtils und SciSharp.TensorFlow.Redist.

Hinzufügen des TensorFlow-Modells zum Projekt

Hinweis

Das Modell für dieses Tutorial stammt aus dem GitHub-Repository dotnet/machinelearning-testdata. Das Modell weist das SavedModel-Format von TensorFlow auf.

  1. Laden Sie die ZIP-Datei sentiment_model herunter, und entpacken Sie sie.

    Die ZIP-Datei enthält Folgendes:

    • saved_model.pb: Das TensorFlow-Modell selbst. Das Modell nimmt ein Integerarray mit einer festen Länge (Größe 600) von Merkmalen an, die den Text in einer IMDB-Kritikzeichenfolge darstellen, und gibt zwei Wahrscheinlichkeiten aus, die die Summe 1 bilden: die Wahrscheinlichkeit, dass die Eingabekritik eine positive Stimmung aufweist, und die Wahrscheinlichkeit, dass die Eingabekritik eine negative Stimmung hat.
    • imdb_word_index.csv: Eine Zuordnung von einzelnen Wörtern zu einem ganzzahligen Wert. Die Zuordnung wird verwendet, um die Eingabemerkmale für das TensorFlow-Modell zu generieren.
  2. Kopieren Sie den Inhalt des innersten sentiment_model-Verzeichnisses in Ihr TextClassificationTF-Projektverzeichnis sentiment_model. Dieses Verzeichnis enthält das Modell und die zusätzlich für dieses Tutorial erforderlichen Unterstützungsdateien wie in der folgenden Abbildung gezeigt:

    Inhalt des Verzeichnisses „sentiment_model“

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf jede Datei im Verzeichnis sentiment_modelund im Unterverzeichnis, und wählen Sie Eigenschaften aus. Ändern Sie unter Erweitert den Wert von In Ausgabeverzeichnis kopieren in Kopieren, wenn neuer.

Hinzufügen von using-Anweisungen und globalen Variablen

  1. Fügen Sie am Anfang der Datei Program.cs folgende zusätzliche using-Anweisungen hinzu:

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using Microsoft.ML.Transforms;
    
  2. Erstellen Sie direkt nach den using-Anweisungen eine globale Variable für den gespeicherten Modelldateipfad.

    string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
    
    • _modelPath ist der Dateipfad des trainierten Modells.

Modellieren der Daten

Filmkritiken sind Freiformtext. Ihre Anwendung konvertiert den Text in das vom Modell erwartete Eingabeformat in einer Reihe diskreter Schritte.

Der erste besteht darin, den Text in separate Wörter aufzuteilen und die bereitgestellte Zuordnungsdatei zu verwenden, um jedes Wort einer ganzzahligen Codierung zuzuordnen. Das Ergebnis dieser Transformation ist ein Intergerarray variabler Länge mit einer Länge, die der Anzahl der Wörter im Satz entspricht.

Eigenschaft Wert Typ
ReviewText this film is really good string
VariableLengthFeatures 14,22,9,66,78,... int[]

Die Größe des Merkmalsarrays variabler Länge wird dann in eine feste Länge von 600 geändert. Dies ist die Länge, die das TensorFlow-Modell erwartet.

Eigenschaft Wert Typ
ReviewText this film is really good string
VariableLengthFeatures 14,22,9,66,78,... int[]
Features 14,22,9,66,78,... int[600]
  1. Erstellen Sie unten in der Datei Program.cs eine Klasse für Ihre Eingabedaten:

    /// <summary>
    /// Class to hold original sentiment data.
    /// </summary>
    public class MovieReview
    {
        public string? ReviewText { get; set; }
    }
    

    Die Eingabedatenklasse (MovieReview) verfügt über ein string-Element für Benutzerkommentare (ReviewText).

  2. Erstellen Sie nach der MovieReview-Klasse eine Klasse für die Merkmale mit variabler Länge:

    /// <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; }
    }
    

    Die VariableLengthFeatures-Eigenschaft verfügt über ein Attribut VectorType, um sie als Vektor festzulegen. Alle Vektorelemente müssen denselben Typ aufweisen. In Datasets mit einer großen Anzahl von Spalten verringert das Laden mehrerer Spalten als einzelner Vektor die Anzahl der Datenübergabevorgänge, wenn Sie Datentransformationen anwenden.

    Diese Klasse wird in der ResizeFeatures-Aktion verwendet. Die Namen ihrer Eigenschaften (in diesem Fall nur ein Name) werden verwendet, um anzugeben, welche Spalten in der DataView als Eingabe für die benutzerdefinierte Zuordnungsaktion verwendet werden können.

  3. Erstellen Sie nach der VariableLength-Klasse eine Klasse für die Merkmale mit fester Länge:

    /// <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; }
    }
    

    Diese Klasse wird in der ResizeFeatures-Aktion verwendet. Die Namen ihrer Eigenschaften (in diesem Fall nur ein Name) werden verwendet, um anzugeben, welche Spalten in der DataView als Ausgabe für die benutzerdefinierte Zuordnungsaktion verwendet werden können.

    Beachten Sie, dass der Name der Features-Eigenschaft durch das TensorFlow-Modell bestimmt wird. Der Name dieser Eigenschaft kann nicht geändert werden.

  4. Erstellen Sie eine Klasse für die Vorhersage nach der FixedLength-Klasse:

    /// <summary>
    /// Class to contain the output values from the transformation.
    /// </summary>
    public class MovieReviewSentimentPrediction
    {
        [VectorType(2)]
        public float[]? Prediction { get; set; }
    }
    

    MovieReviewSentimentPrediction ist die nach dem Modelltraining verwendete Vorhersageklasse. MovieReviewSentimentPrediction weist ein einzelnes float-Array (Prediction) und ein VectorType-Attribut auf.

  5. Erstellen Sie eine weitere Klasse für die Konfigurationswerte, z. B. die Länge des Featurevektors:

    static class Config
    {
        public const int FeatureLength = 600;
    }
    

Erstellen von der MLContext-Klasse, des Nachschlagewörterbuchs und der Aktion zum Ändern der Größe von Merkmalen

Die MLContext-Klasse ist der Ausgangspunkt für alle ML.NET-Vorgänge. Beim Initialisieren von mlContext wird eine neue ML.NET-Umgebung erstellt, die für alle Objekte des Workflows für die Modellerstellung gemeinsam genutzt werden kann. Die Klasse ähnelt dem Konzept von DBContext in Entity Framework.

  1. Ersetzen Sie die Zeile Console.WriteLine("Hello World!") durch den folgenden Code, um die mlContext-Variable zu deklarieren und zu initialisieren:

    MLContext mlContext = new MLContext();
    
  2. Erstellen Sie ein Wörterbuch, um Wörter als Integerwerte zu codieren, indem Sie die LoadFromTextFile-Methode zum Laden von Zuordnungsdaten aus einer Datei verwenden, wie in der folgenden Tabelle gezeigt:

    Word Index
    kids 362
    want 181
    wrong 355
    effects 302
    feeling 547

    Fügen Sie den folgenden Code hinzu, um die Nachschlagezuordnung zu erstellen:

    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: ','
        );
    
  3. Fügen Sie mit den nächsten Codezeilen eine Action hinzu, um die Größe des Wortintegerarrays variabler Länge in ein Integerarray fester Größe zu ändern:

    Action<VariableLength, FixedLength> ResizeFeaturesAction = (s, f) =>
    {
        var features = s.VariableLengthFeatures;
        Array.Resize(ref features, Config.FeatureLength);
        f.Features = features;
    };
    

Laden des vortrainierten TensorFlow-Modells

  1. Fügen Sie Code hinzu, um das TensorFlow-Modell zu laden:

    TensorFlowModel tensorFlowModel = mlContext.Model.LoadTensorFlowModel(_modelPath);
    

    Nachdem das Modell geladen wurde, können Sie sein Eingabe- und Ausgabeschema extrahieren. Die Schemas werden nur aus Interesse und zu Lernzwecken angezeigt. Sie benötigen diesen Code nicht, damit die endgültige Anwendung funktioniert:

    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]})");
    
    

    Das Eingabeschema ist das Array fester Länge von ganzzahlig codierten Wörtern. Das Ausgabeschema ist ein Floatarray von Wahrscheinlichkeiten, das angibt, ob die Stimmung einer Kritik negativ oder positiv ist. Die Summe dieser Werte ist 1, da die Wahrscheinlichkeit, dass die Kritik positiv ist, das Komplement für die Wahrscheinlichkeit ist, dass die Stimmung negativ ist.

Erstellen der ML.NET-Pipeline

  1. Erstellen Sie die Pipeline, und teilen Sie den Eingabetext mithilfe der Transformation TokenizeIntoWords in der nächsten Codezeile in Wörter auf:

    IEstimator<ITransformer> pipeline =
        // Split the text into individual words
        mlContext.Transforms.Text.TokenizeIntoWords("TokenizedWords", "ReviewText")
    

    Die Transformation TokenizeIntoWords verwendet Leerzeichen, um den Text bzw. die Zeichenfolge in Wörter zu analysieren. Sie erstellt eine neue Spalte und teilt jede Eingabezeichenfolge in einen Vektor von Teilzeichenfolgen basierend auf dem benutzerdefinierten Trennzeichen auf.

  2. Ordnen Sie die Wörter mithilfe der Nachschlagetabelle, die Sie oben deklariert haben, ihrer Integercodierung zu:

    // 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"))
    
  3. Ändern Sie die Größe der Integercodierungen variabler Länge in die für das Modell erforderliche feste Länge:

    // Resize variable length vector to fixed length vector.
    .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
    
  4. Klassifizieren Sie die Eingabe mit dem geladenen TensorFlow-Modell:

    // Passes the data to TensorFlow for scoring
    .Append(tensorFlowModel.ScoreTensorFlowModel("Prediction/Softmax", "Features"))
    

    Die Ausgabe des TensorFlow-Modells wird als Prediction/Softmax bezeichnet. Beachten Sie, dass der Name Prediction/Softmax durch das TensorFlow-Modell bestimmt wird. Dieser Name kann nicht geändert werden.

  5. Erstellen Sie eine neue Spalte für die Ausgabevorhersage:

    // Retrieves the 'Prediction' from TensorFlow and copies to a column
    .Append(mlContext.Transforms.CopyColumns("Prediction", "Prediction/Softmax"));
    

    Sie müssen die Prediction/Softmax-Spalte in eine Spalte mit einem Namen kopieren, der als Eigenschaft in einer C#-Klasse verwendet werden kann: Prediction. Das Zeichen / ist in einem C# Eigenschaftsnamen unzulässig.

Erstellen des ML.NET-Modells aus der Pipeline

  1. Fügen Sie den Code hinzu, um das Modell aus der Pipeline zu erstellen:

    // Create an executable model from the estimator pipeline
    IDataView dataView = mlContext.Data.LoadFromEnumerable(new List<MovieReview>());
    ITransformer model = pipeline.Fit(dataView);
    

    Ein ML.NET-Modell wird aus der Kette der Kalkulatoren in der Pipeline erstellt, indem die Fit-Methode aufgerufen wird. In diesem Fall passen wir keine Daten an, um das Modell zu erstellen, da das TensorFlow-Modell bereits vortrainiert wurde. Wir stellen ein leeres Datenansichtsobjekt bereit, um die Anforderungen der Fit-Methode zu erfüllen.

Verwenden des Modells für Vorhersagen

  1. Fügen Sie die PredictSentiment-Methode über der MovieReview-Klasse hinzu:

    void PredictSentiment(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. Fügen wir den folgenden Code hinzu, um die PredictionEngine als erste Zeile in der PredictSentiment()-Methode zu erstellen:

    var engine = mlContext.Model.CreatePredictionEngine<MovieReview, MovieReviewSentimentPrediction>(model);
    

    Die PredictionEngine ist eine Hilfs-API, mit der Sie eine Vorhersage für eine einzelne Instanz der Daten treffen können. PredictionEngine ist nicht threadsicher. Die Verwendung in Singlethread-oder Prototypumgebungen ist zulässig. Zur Verbesserung der Leistung und Threadsicherheit in Produktionsumgebungen verwenden Sie den PredictionEnginePool-Dienst, der einen ObjectPool aus PredictionEngine-Objekten für die Verwendung in Ihrer gesamten Anwendung erstellt. Informationen zur Verwendung von PredictionEnginePool in einer ASP.NET Core-Web-API finden Sie in dieser Anleitung.

    Hinweis

    Die PredictionEnginePool-Diensterweiterung ist derzeit als Vorschauversion verfügbar.

  3. Fügen Sie einen Kommentar hinzu, um die Vorhersage des trainierten Modells in der Predict()-Methode zu testen, indem Sie eine MovieReview-Instanz erstellen:

    var review = new MovieReview()
    {
        ReviewText = "this film is really good"
    };
    
  4. Übergeben Sie die Testkommentardaten an die Prediction Engine, indem Sie die folgenden Codezeilen in der PredictSentiment()-Methode hinzufügen:

    var sentimentPrediction = engine.Predict(review);
    
  5. Die Predict()-Funktion trifft eine Vorhersage für eine einzelne Datenzeile:

    Eigenschaft Wert Typ
    Vorhersage [0,5459937, 0,454006255] float[]
  6. Mithilfe des folgenden Codes können Sie die Stimmungsvorhersage anzeigen:

    Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}");
    Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
    
  7. Fügen Sie nach dem Aufruf der Fit()-Methode einen Aufruf von PredictSentiment hinzu:

    PredictSentiment(mlContext, model);
    

Ergebnisse

Erstellen Sie Ihre Anwendung, und führen Sie sie aus.

Die Ergebnisse sollten den unten dargestellten ähneln. Während der Verarbeitung werden Meldungen angezeigt. Sie können Warnungen oder Verarbeitungsmeldungen sehen. Diese Nachrichten wurden der Übersichtlichkeit halber aus den folgenden Ergebnissen entfernt.

Number of classes: 2
Is sentiment/review positive ? Yes

Herzlichen Glückwunsch! Sie haben jetzt erfolgreich ein Machine Learning-Modell zum Klassifizieren und Vorhersagen von Stimmungen in Mitteilungen durch die Wiederverwendung eines vortrainierten TensorFlow-Modells in ML.NET erstellt.

Sie finden den Quellcode für dieses Tutorial im Repository dotnet/samples.

In diesem Tutorial haben Sie gelernt, wie die folgenden Aufgaben ausgeführt werden:

  • Laden eines vortrainierten TensorFlow-Modells
  • Umwandeln von Websitekommentartext in für das Modell geeignete Merkmale
  • Verwenden des Modells für Vorhersagen