Condividi tramite


Esercitazione: Analizzare il sentiment delle recensioni di film usando un modello TensorFlow con training preliminare in ML.NET

Questa esercitazione illustra come usare un modello TensorFlow con training preliminare per classificare il sentiment nei commenti del sito Web. Il classificatore di valutazione binario è un'applicazione console C# sviluppata con Visual Studio.

Il modello TensorFlow usato in questa esercitazione è stato sottoposto a training usando recensioni di film dal database IMDB. Al termine dello sviluppo dell'applicazione, sarà possibile fornire il testo della recensione cinematografica e l'applicazione indicherà se la recensione ha un sentiment positivo o negativo.

In questa esercitazione verranno illustrate le procedure per:

  • Caricare un modello TensorFlow con training preliminare
  • Trasformare il testo del commento del sito Web in funzionalità adatte per il modello
  • Usare il modello per eseguire una stima

È possibile trovare il codice sorgente per questa esercitazione nel repository dotnet/samples.

Prerequisiti

Installazione

Creare l'applicazione

  1. Creare un'applicazione console C# denominata "TextClassificationTF". Fare clic sul pulsante Next (Avanti).

  2. Scegliere .NET 6 come framework da usare. Fare clic sul pulsante Crea.

  3. Creare una directory denominata Data nel progetto per salvare i file del set di dati.

  4. Installare il pacchetto NuGet Microsoft.ML:

    Nota

    In questo esempio viene usata la versione stabile più recente dei pacchetti NuGet menzionati, se non diversamente specificato.

    In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e selezionare Gestisci pacchetti NuGet. Scegliere "nuget.org" come origine del pacchetto e quindi selezionare la scheda Sfoglia . Cercare Microsoft.ML, selezionare il pacchetto desiderato e quindi selezionare il pulsante Installa . Procedere con l'installazione accettando le condizioni di licenza per il pacchetto scelto. Ripetere questi passaggi per Microsoft.ML.TensorFlow, Microsoft.ML.SampleUtils e SciSharp.TensorFlow.Redist.

Aggiungere il modello TensorFlow al progetto

Nota

Il modello per questa esercitazione proviene dal repository GitHub dotnet/machinelearning-testdata . Il modello è in formato TensorFlow SavedModel.

  1. Scaricare il file ZIP sentiment_model e decomprimere.

    Il file ZIP contiene:

    • saved_model.pb: il modello TensorFlow stesso. Il modello accetta una matrice di valori interi a lunghezza fissa (dimensione 600) di caratteristiche che rappresentano il testo in una stringa di revisione IMDB e restituisce due probabilità che sommano a 1: la probabilità che la revisione di input abbia un sentiment positivo e la probabilità che la revisione di input abbia un sentiment negativo.
    • imdb_word_index.csv: mapping da singole parole a un valore intero. Il mapping viene usato per generare le funzionalità di input per il modello TensorFlow.
  2. Copiare il contenuto della directory più sentiment_model interna nella directory del progetto sentiment_modelTextClassificationTF. Questa directory contiene il modello e i file di supporto aggiuntivi necessari per questa esercitazione, come illustrato nell'immagine seguente:

    contenuto della directory sentiment_model

  3. In Esplora soluzioni fare clic con il pulsante destro del mouse su ognuno dei file nella directory e nella sentiment_model sottodirectory e scegliere Proprietà. In Avanzate modificare il valore di Copia nella directory di output in Copia se più recente.

Aggiungere istruzioni using e variabili globali

  1. Aggiungere le istruzioni using seguenti all'inizio del file Program.cs:

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using Microsoft.ML.Transforms;
    
  2. Creare una variabile globale subito dopo le istruzioni using per contenere il percorso del file del modello salvato.

    string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
    
    • _modelPath è il percorso del file del modello sottoposto a training.

Modellare i dati

Le recensioni di film sono testo in formato libero. L'applicazione converte il testo nel formato di input previsto dal modello in diverse fasi discrete.

Il primo consiste nel suddividere il testo in parole separate e usare il file di mapping fornito per eseguire il mapping di ogni parola a una codifica integer. Il risultato di questa trasformazione è una matrice integer a lunghezza variabile con una lunghezza corrispondente al numero di parole nella frase.

Proprietà Valore Tipo
ReviewText questo film è davvero buono string
VariableLengthFeatures 14,22,9,66,78,... int[]

La matrice di caratteristiche a lunghezza variabile viene quindi ridimensionata a una lunghezza fissa di 600. Si tratta della lunghezza prevista dal modello TensorFlow.

Proprietà Valore Tipo
ReviewText questo film è davvero buono string
VariableLengthFeatures 14,22,9,66,78,... int[]
Funzionalità 14,22,9,66,78,... int[600]
  1. Creare una classe per i dati di input nella parte inferiore del file Program.cs :

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

    La classe di dati di input, MovieReview, ha un string oggetto per i commenti dell'utente (ReviewText).

  2. Creare una classe per le funzionalità di lunghezza variabile dopo la MovieReview classe :

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

    La VariableLengthFeatures proprietà ha un attributo VectorType per designarlo come vettore. Tutti gli elementi vettoriali devono essere dello stesso tipo. Nei set di dati con un numero elevato di colonne, il caricamento di più colonne come singolo vettore riduce il numero di passaggi di dati quando si applicano trasformazioni dei dati.

    Questa classe viene usata nell'azione ResizeFeatures . I nomi delle relative proprietà (in questo caso solo uno) vengono usati per indicare quali colonne in DataView possono essere usate come input per l'azione di mapping personalizzata.

  3. Creare una classe per le funzionalità a lunghezza fissa, dopo la VariableLength classe :

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

    Questa classe viene usata nell'azione ResizeFeatures . I nomi delle relative proprietà (in questo caso solo uno) vengono usati per indicare quali colonne in DataView possono essere usate come output dell'azione di mapping personalizzata.

    Si noti che il nome della proprietà Features è determinato dal modello TensorFlow. Non è possibile modificare questo nome di proprietà.

  4. Creare una classe per la stima dopo la FixedLength classe :

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

    MovieReviewSentimentPrediction è la classe di stima usata dopo il training del modello. MovieReviewSentimentPrediction ha una singola float matrice (Prediction) e un VectorType attributo.

  5. Creare un'altra classe per contenere i valori di configurazione, ad esempio la lunghezza del vettore di funzionalità:

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

Creare mlContext, dizionario di ricerca e azione per ridimensionare le funzionalità

La classe MLContext è un punto di partenza per tutte le operazioni ML.NET. L'inizializzazione di mlContext crea un nuovo ambiente ML.NET che può essere condiviso tra gli oggetti del flusso di lavoro di creazione del modello. Dal punto di vista concettuale è simile a DBContext in Entity Framework.

  1. Sostituire la Console.WriteLine("Hello World!") riga con il codice seguente per dichiarare e inizializzare la variabile mlContext:

    MLContext mlContext = new MLContext();
    
  2. Creare un dizionario per codificare le parole come numeri interi usando il LoadFromTextFile metodo per caricare i dati di mapping da un file, come illustrato nella tabella seguente:

    Word Indice
    Bambini 362
    want 181
    Sbagliato 355
    effects 302
    Sensazione 547

    Aggiungere il codice seguente per creare la mappa di ricerca:

    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. Aggiungere un Action oggetto per ridimensionare la matrice integer di lunghezza variabile a una matrice integer di dimensioni fisse, con le righe successive di codice:

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

Caricare il modello TensorFlow pre-sottoposto a training

  1. Aggiungere codice per caricare il modello TensorFlow:

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

    Dopo aver caricato il modello, è possibile estrarre il relativo schema di input e output. Gli schemi vengono visualizzati solo per interesse e apprendimento. Non è necessario questo codice per la funzione dell'applicazione finale:

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

    Lo schema di input è la matrice a lunghezza fissa di parole con codifica integer. Lo schema di output è una matrice float di probabilità che indica se il sentiment di una revisione è negativo o positivo. Questi valori sommano a 1, poiché la probabilità di essere positivi è il complemento della probabilità del sentiment essere negativo.

Creare la pipeline di ML.NET

  1. Creare la pipeline e suddividere il testo di input in parole usando TokenizeIntoWords trasforma per suddividere il testo in parole come riga di codice successiva:

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

    La trasformazione TokenizeIntoWords usa spazi per analizzare il testo/stringa in parole. Crea una nuova colonna e divide ogni stringa di input in un vettore di sottostringa in base al separatore definito dall'utente.

  2. Eseguire il mapping delle parole alla codifica integer usando la tabella di ricerca dichiarata in precedenza:

    // 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. Ridimensionare le codifiche integer di lunghezza variabile a lunghezza fissa richiesta dal modello:

    // Resize variable length vector to fixed length vector.
    .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
    
  4. Classificare l'input con il modello TensorFlow caricato:

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

    L'output del modello TensorFlow è denominato Prediction/Softmax. Si noti che il nome Prediction/Softmax è determinato dal modello TensorFlow. Non è possibile modificare questo nome.

  5. Creare una nuova colonna per la stima dell'output:

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

    È necessario copiare la Prediction/Softmax colonna in una con un nome che può essere usato come proprietà in una classe C#: Prediction. Il / carattere non è consentito in un nome di proprietà C#.

Creare il modello di ML.NET dalla pipeline

  1. Aggiungere il codice per creare il modello dalla pipeline:

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

    Un modello di ML.NET viene creato dalla catena di estimatori nella pipeline chiamando il Fit metodo . In questo caso, non si adattano dati per creare il modello, poiché il modello TensorFlow è già stato sottoposto a training. Viene fornito un oggetto visualizzazione dati vuoto per soddisfare i requisiti del Fit metodo.

Usare il modello per eseguire una stima

  1. Aggiungere il metodo sopra la PredictSentimentMovieReview classe:

    void PredictSentiment(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. Aggiungere il codice seguente per creare la PredictionEngine prima riga nel PredictSentiment() metodo:

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

    PredictionEngine è un'API pratico, che consente di eseguire una stima in una singola istanza di dati. PredictionEngine non è thread-safe. È accettabile usare in ambienti a thread singolo o prototipo. Per migliorare le prestazioni e la sicurezza dei thread negli ambienti di produzione, usare il PredictionEnginePool servizio, che crea un ObjectPool oggetto da PredictionEngine usare in tutta l'applicazione. Vedere questa guida su come usare PredictionEnginePool in un'API Web di ASP.NET Core.

    Nota

    L'estensione del servizio PredictionEnginePool è attualmente in anteprima.

  3. Aggiungere un commento per testare la stima del modello sottoposto a training nel metodo Predict() creando un'istanza di MovieReview:

    var review = new MovieReview()
    {
        ReviewText = "this film is really good"
    };
    
  4. Passare i dati del commento di test all'oggetto Prediction Engine aggiungendo le righe successive di codice nel PredictSentiment() metodo:

    var sentimentPrediction = engine.Predict(review);
    
  5. La funzione Predict() effettua una stima su una singola riga di dati:

    Proprietà Valore Tipo
    Stima [0.5459937, 0.454006255] float[]
  6. Visualizzare la stima del sentiment usando il codice seguente:

    Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}");
    Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
    
  7. Aggiungere una chiamata a PredictSentiment dopo aver chiamato il Fit() metodo:

    PredictSentiment(mlContext, model);
    

Risultati

Compilare ed eseguire l'applicazione.

I risultati dovrebbero essere simili a quanto riportato di seguito. Durante l'elaborazione, vengono visualizzati alcuni messaggi. Possono essere mostrati avvisi o messaggi relativi all'elaborazione. Questi messaggi sono stati rimossi dai risultati seguenti per maggiore chiarezza.

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

Congratulazioni! È stato creato un modello di Machine Learning per classificare e stimare il sentiment dei messaggi riutilizzando un modello pre-sottoposto TensorFlow a training in ML.NET.

È possibile trovare il codice sorgente per questa esercitazione nel repository dotnet/samples.

In questa esercitazione sono state illustrate le procedure per:

  • Caricare un modello TensorFlow pre-sottoposto a training
  • Trasformare il testo del commento del sito Web in funzionalità adatte per il modello
  • Usare il modello per eseguire una stima