Självstudie: Analysera sentiment för filmrecensioner med hjälp av en förtränad TensorFlow-modell i ML.NET
Den här handledningen visar hur du använder en förtränad TensorFlow-modell för att klassificera sentiment i webbplatskommentarer. Den binära sentimentklassificeraren är ett C#-konsolprogram som utvecklats med Visual Studio.
TensorFlow-modellen som användes i den här självstudien tränades med filmrecensioner från IMDB-databasen. När du har utvecklat programmet kommer du att kunna ange text för filmgranskning och programmet kommer att berätta om recensionen har positiva eller negativa sentiment.
I den här handledningen lär du dig hur du:
- Läsa in en förtränad TensorFlow-modell
- Omvandla webbplatskommentartext till funktioner som är lämpliga för modellen
- Använd modellen för att göra en förutsägelse
Du hittar källkoden för den här självstudien på dotnet/samples-lagringsplatsen.
Förutsättningar
- Visual Studio 2022 med verktyget ".NET Desktop Development" installerat.
Konfiguration
Skapa programmet
Skapa ett C# -konsolprogram med namnet "TextClassificationTF". Klicka på knappen Nästa.
Välj .NET 8 som ramverk att använda. Klicka på knappen Skapa.
Skapa en katalog med namnet Data i projektet för att spara dina datamängdsfiler.
Installera Microsoft.ML NuGet-paketet:
Anteckning
Det här exemplet använder den senaste stabila versionen av De NuGet-paket som nämns om inget annat anges.
Högerklicka på projektet i Solution Explorer och välj Hantera NuGet-paket. Välj "nuget.org" som paketkälla och välj sedan fliken Bläddra. Sök efter Microsoft.ML, välj önskat paket och välj sedan Installera. Fortsätt med installationen genom att godkänna licensvillkoren för det paket du väljer. Upprepa de här stegen för Microsoft.ML.TensorFlow, Microsoft.ML.SampleUtils och SciSharp.TensorFlow.Redist.
Lägg till TensorFlow-modellen i projektet
Not
Modellen för den här handledningen kommer från dotnet/machinelearning-testdata GitHub-repo. Modellen är i TensorFlow SavedModel-format.
Ladda ned sentiment_model zip-filenoch packa upp.
Zip-filen innehåller:
-
saved_model.pb
: Själva TensorFlow-modellen. Modellen tar en heltalsmatris med fast längd (storlek 600) med funktioner som representerar texten i en IMDB-granskningssträng och matar ut två sannolikheter som summerar till 1: sannolikheten att indatagranskningen har positiv attityd och sannolikheten att indatagranskningen har negativ attityd. -
imdb_word_index.csv
: en mappning från enskilda ord till ett heltalsvärde. Mappningen används för att generera indatafunktionerna för TensorFlow-modellen.
-
Kopiera innehållet i den innersta katalogen
sentiment_model
till ditt TextClassificationTF-projektetssentiment_model
projektkatalog. Den här katalogen innehåller modellen och ytterligare supportfiler som behövs för den här självstudien, som du ser i följande bild:Högerklicka på var och en av filerna i
sentiment_model
-katalogen och underkatalogen i Solution Explorer och välj Egenskaper. Under Advancedändrar du värdet för Kopiera till utdatakatalog till Kopiera om nyare.
Lägga till using
direktiv och globala variabler
Lägg till följande ytterligare
using
-direktiv överst i filen Program.cs:using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms;
Skapa en global variabel direkt efter
using
-direktiven för att lagra den sparade modellfilens sökväg.string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
-
_modelPath
är filsökvägen för den tränade modellen.
-
Modellera data
Filmrecensioner är fri formtext. Ditt program konverterar texten till det indataformat som förväntas av modellen i ett antal diskreta steg.
Det första är att dela upp texten i separata ord och använda den angivna mappningsfilen för att mappa varje ord till en heltalskodning. Resultatet av den här omvandlingen är en heltalsmatris för variabellängd med en längd som motsvarar antalet ord i meningen.
Egenskap | Värde | Typ |
---|---|---|
Recensionstext | den här filmen är riktigt bra | sträng |
FunktionerMedVariabelLängd | 14,22,9,66,78,... | int[] |
Funktionsarrayen med variabel längd ändras sedan till en fast längd på 600. Det här är den längd som TensorFlow-modellen förväntar sig.
Egenskap | Värde | Typ |
---|---|---|
Recensionstext | den här filmen är riktigt bra | sträng |
VariabelLängdFunktioner | 14,22,9,66,78,... | int[] |
Funktioner | 14,22,9,66,78,... | int[600] |
Skapa en klass för dina indata längst ned i Program.cs-filen:
/// <summary> /// Class to hold original sentiment data. /// </summary> public class MovieReview { public string? ReviewText { get; set; } }
Indataklassen
MovieReview
har enstring
för användarkommentare (ReviewText
).Skapa en klass för variablernas längdfunktioner efter klassen
MovieReview
:/// <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; } }
Egenskapen
VariableLengthFeatures
har ett VectorType-attribut som anger den som en vektor. Alla vektorelement måste vara av samma typ. I datauppsättningar med ett stort antal kolumner minskar inläsningen av flera kolumner som en enda vektor antalet data som skickas när du tillämpar datatransformeringar.Den här klassen används i åtgärden
ResizeFeatures
. Namnen på dess egenskaper (i det här fallet endast en) används för att ange vilka kolumner i DataView som kan användas som indata till den anpassade mappningsåtgärden.Skapa en klass för funktionerna med fast längd efter klassen
VariableLength
:/// <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; } }
Den här klassen används i åtgärden
ResizeFeatures
. Namnen på dess egenskaper (i det här fallet endast en) används för att ange vilka kolumner i DataView som kan användas som utdata av den anpassade mappningsåtgärden.Observera att namnet på egenskapen
Features
bestäms av TensorFlow-modellen. Du kan inte ändra det här egenskapsnamnet.Skapa en klass för förutsägelsen efter klassen
FixedLength
:/// <summary> /// Class to contain the output values from the transformation. /// </summary> public class MovieReviewSentimentPrediction { [VectorType(2)] public float[]? Prediction { get; set; } }
MovieReviewSentimentPrediction
är förutsägelseklassen som används efter modellträningen.MovieReviewSentimentPrediction
har en endafloat
matris (Prediction
) och ettVectorType
-attribut.Skapa en annan klass för att lagra konfigurationsvärden, till exempel funktionsvektorlängden:
static class Config { public const int FeatureLength = 600; }
Skapa MLContext, uppslagsordlistan och åtgärden för att ändra storlek på funktioner
Klassen MLContext är en startpunkt för alla ML.NET åtgärder. När du initierar mlContext
skapas en ny ML.NET miljö som kan delas mellan arbetsflödesobjekten för modellskapande. Det är liknande som DBContext
konceptuellt sett i Entity Framework.
Ersätt raden
Console.WriteLine("Hello World!")
med följande kod för att deklarera och initiera variabeln mlContext:MLContext mlContext = new MLContext();
Skapa en ordlista för att koda ord som heltal med hjälp av metoden
LoadFromTextFile
för att läsa in mappningsdata från en fil, enligt följande tabell:Ord Index Barn 362 vilja 181 orätt 355 effekter 302 känsla 547 Lägg till koden nedan för att skapa uppslagskartan:
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: ',' );
Lägg till en
Action
för att ändra storleken på en word-heltalsarray av variabel längd till en heltalsarray med fast storlek, med följande kod:Action<VariableLength, FixedLength> ResizeFeaturesAction = (s, f) => { var features = s.VariableLengthFeatures; Array.Resize(ref features, Config.FeatureLength); f.Features = features; };
Ladda den förtränade TensorFlow-modellen
Lägg till kod för att läsa in TensorFlow-modellen:
TensorFlowModel tensorFlowModel = mlContext.Model.LoadTensorFlowModel(_modelPath);
När modellen har lästs in kan du extrahera dess indata- och utdataschema. Schemana visas endast för intresse och inlärning. Du behöver inte den här koden för att det slutliga programmet ska fungera:
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]})");
Indataschemat är matrisen med heltalskodade ord med fast längd. Utdataschemat är en flyttalmatris med sannolikheter som anger om en gransknings sentiment är negativt eller positivt . Dessa värden summerar till 1, eftersom sannolikheten för att vara positiv är ett komplement till sannolikheten för att sentimentet är negativt.
Skapa ML.NET pipeline
Skapa pipelinen och dela upp indatatexten i ord med hjälp av TokenizeIntoWords transformera för att dela upp texten i ord som nästa kodrad:
IEstimator<ITransformer> pipeline = // Split the text into individual words mlContext.Transforms.Text.TokenizeIntoWords("TokenizedWords", "ReviewText")
TokenizeIntoWords- transformering använder blanksteg för att dela upp texten/strängen till ord. Den skapar en ny kolumn och delar upp varje indatasträng till en vektor med delsträngar baserat på den användardefinierade avgränsaren.
Mappa orden till heltalskodningen med hjälp av uppslagstabellen som du deklarerade ovan:
// 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"))
Anpassa heltalskodningarna av variabellängd till den fastställda längden som modellen kräver.
// Resize variable length vector to fixed length vector. .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
Klassificera indata med den inlästa TensorFlow-modellen:
// Passes the data to TensorFlow for scoring .Append(tensorFlowModel.ScoreTensorFlowModel("Prediction/Softmax", "Features"))
TensorFlow-modellutdata kallas
Prediction/Softmax
. Observera att namnetPrediction/Softmax
bestäms av TensorFlow-modellen. Du kan inte ändra det här namnet.Skapa en ny kolumn för utdataförutsägelse:
// Retrieves the 'Prediction' from TensorFlow and copies to a column .Append(mlContext.Transforms.CopyColumns("Prediction", "Prediction/Softmax"));
Du måste kopiera kolumnen
Prediction/Softmax
till en med ett namn som kan användas som en egenskap i en C#-klass:Prediction
. Det/
tecknet tillåts inte i ett C#-egenskapsnamn.
Skapa ML.NET-modellen från pipelinen
Lägg till koden för att skapa modellen från pipelinen:
// Create an executable model from the estimator pipeline IDataView dataView = mlContext.Data.LoadFromEnumerable(new List<MovieReview>()); ITransformer model = pipeline.Fit(dataView);
En ML.NET modell skapas från kedjan med skattningar i pipelinen genom att anropa metoden
Fit
. I det här fallet passar du inte in några data för att skapa modellen, eftersom TensorFlow-modellen redan har tränats tidigare. Du anger ett tomt datavyobjekt för att uppfylla kraven för metodenFit
.
Använd modellen för att göra en förutsägelse
Lägg till metoden
PredictSentiment
ovanför klassenMovieReview
:void PredictSentiment(MLContext mlContext, ITransformer model) { }
Lägg till följande kod för att skapa
PredictionEngine
som den första raden i metodenPredictSentiment()
:var engine = mlContext.Model.CreatePredictionEngine<MovieReview, MovieReviewSentimentPrediction>(model);
PredictionEngine är ett bekvämlighets-API som gör att du kan utföra en förutsägelse på en enda instans av data.
PredictionEngine
är inte trådsäkert. Det är acceptabelt att använda i entrådade miljöer eller prototypmiljöer. För bättre prestanda och trådsäkerhet i produktionsmiljöer använder du tjänstenPredictionEnginePool
, vilket skapar enObjectPool
avPredictionEngine
objekt för användning i hela programmet. Se den här guiden om hur du användaPredictionEnginePool
i en ASP.NET Core Web API-.Not
PredictionEnginePool
tjänsttillägget är för närvarande i förhandsversion.Lägg till en kommentar för att testa den tränade modellens förutsägelse i metoden
Predict()
genom att skapa en instans avMovieReview
:var review = new MovieReview() { ReviewText = "this film is really good" };
Skicka testkommentardata till
Prediction Engine
genom att lägga till följande kodrader i metodenPredictSentiment()
:var sentimentPrediction = engine.Predict(review);
Funktionen Predict() gör en förutsägelse på en enda rad med data:
Egenskap Värde Typ Prognos [0.5459937, 0.454006255] float[] Visa attitydförutsägelse med hjälp av följande kod:
Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}"); Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
Lägg till ett anrop till
PredictSentiment
när du har anropat metodenFit()
:PredictSentiment(mlContext, model);
Resultat
Skapa och kör ditt program.
Resultatet bör likna följande. Under bearbetningen visas meddelanden. Du kan se varningar eller bearbeta meddelanden. Dessa meddelanden har tagits bort från följande resultat för tydlighetens skull.
Number of classes: 2
Is sentiment/review positive ? Yes
Grattis! Nu har du skapat en maskininlärningsmodell för att klassificera och förutsäga meddelanden genom att återanvända en förtränad TensorFlow
modell i ML.NET.
Du hittar källkoden för den här självstudien på dotnet/samples-lagringsplatsen.
I den här handledningen lärde du dig att:
- Ladda en förtränad TensorFlow-modell
- Omvandla webbplatskommentartext till funktioner som är lämpliga för modellen
- Använd modellen för att göra en förutsägelse