Compartir vía


Tutorial: Análisis de opiniones de películas mediante un modelo tensorFlow entrenado previamente en ML.NET

En este tutorial se muestra cómo usar un modelo tensorFlow entrenado previamente para clasificar opiniones en los comentarios del sitio web. El clasificador de sentimiento binario es una aplicación de consola de C# desarrollada mediante Visual Studio.

El modelo de TensorFlow usado en este tutorial se entrenó mediante revisiones de películas de la base de datos IMDB. Una vez que haya terminado de desarrollar la aplicación, podrá proporcionar texto de revisión de películas y la aplicación le indicará si la revisión tiene opiniones positivas o negativas.

En este tutorial, aprenderá a:

  • Carga de un modelo de TensorFlow previamente entrenado
  • Transformar el texto del comentario del sitio web en características adecuadas para el modelo
  • Uso del modelo para realizar una predicción

Puede encontrar el código fuente de este tutorial en el repositorio dotnet/samples .

Prerrequisitos

Configuración

Creación de la aplicación

  1. Cree una aplicación de consola de C# denominada "TextClassificationTF". Haga clic en el botón Siguiente .

  2. Elija .NET 8 como marco de trabajo que se va a usar. Haga clic en el botón Crear.

  3. Cree un directorio denominado Data en el proyecto para guardar los archivos del conjunto de datos.

  4. Instale el paquete NuGet de Microsoft.ML:

    Nota:

    En este ejemplo se usa la versión estable más reciente de los paquetes NuGet mencionados a menos que se indique lo contrario.

    En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet. Elija "nuget.org" como origen del paquete y, a continuación, seleccione la pestaña Examinar . Busque Microsoft.ML, seleccione el paquete que desee y, a continuación, seleccione Instalar. Continúe con la instalación aceptando los términos de licencia del paquete que elija. Repita estos pasos para Microsoft.ML.TensorFlow, Microsoft.ML.SampleUtils y SciSharp.TensorFlow.Redist.

Adición del modelo de TensorFlow al proyecto

Nota:

El modelo de este tutorial procede del repositorio dotnet/machinelearning-testdata de GitHub. El modelo está en formato SavedModel de TensorFlow.

  1. Descargue el archivo zip sentiment_model y descomprima.

    El archivo ZIP contiene:

    • saved_model.pb: el propio modelo de TensorFlow. El modelo toma una matriz entera de longitud fija (tamaño 600) de características que representan el texto de una cadena de revisión de IMDB y genera dos probabilidades que suman a 1: la probabilidad de que la revisión de entrada tenga opiniones positivas y la probabilidad de que la revisión de entrada tenga opiniones negativas.
    • imdb_word_index.csv: un mapeo de cada palabra individual a un valor entero. La asignación se usa para generar las características de entrada para el modelo de TensorFlow.
  2. Copie el contenido del directorio más interno sentiment_model en el directorio TextClassificationTF del proyecto sentiment_model. Este directorio contiene el modelo y los archivos de soporte técnico adicionales necesarios para este tutorial, como se muestra en la siguiente imagen:

    contenido del directorio de sentiment_model

  3. En el Explorador de soluciones, haga clic con el botón derecho en cada uno de los archivos del sentiment_model directorio y subdirectorio y seleccione Propiedades. En Avanzado, cambie el valor de Copiar al directorio de salida a Copiar si es más reciente.

Adición using de directivas y variables globales

  1. Agregue las siguientes directivas adicionales using a la parte superior del archivo Program.cs :

    using Microsoft.ML;
    using Microsoft.ML.Data;
    using Microsoft.ML.Transforms;
    
  2. Cree una variable global justo después de las using directivas para almacenar la ruta de acceso del archivo del modelo guardado.

    string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");
    
    • _modelPath es la ruta de acceso del archivo del modelo entrenado.

Modelado de los datos

Las reseñas de películas son texto de forma libre. La aplicación convierte el texto en el formato de entrada esperado por el modelo en una serie de fases discretas.

La primera consiste en dividir el texto en palabras independientes y usar el archivo de asignación proporcionado para asignar cada palabra a una codificación de enteros. El resultado de esta transformación es una matriz de enteros de longitud variable con una longitud correspondiente al número de palabras de la oración.

Propiedad Importancia Tipo
ReviewText esta película es realmente buena cuerda / cadena
CaracterísticasDeLongitudVariable 14,22,9,66,78,... int[]

A continuación, se cambia el tamaño de la matriz de características de longitud variable a una longitud fija de 600. Esta es la longitud que espera el modelo de TensorFlow.

Propiedad Importancia Tipo
ReviewText esta película es realmente buena cuerda / cadena
CaracterísticasDeLongitudVariable 14,22,9,66,78,... int[]
Características 14,22,9,66,78,... int[600]
  1. Cree una clase para los datos de entrada en la parte inferior del archivo Program.cs :

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

    La clase de datos de entrada, MovieReview, tiene un string para los comentarios del usuario (ReviewText).

  2. Cree una clase para las características de longitud variable después de la MovieReview clase :

    /// <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 propiedad tiene un atributo VectorType para designarlo como vector. Todos los elementos vectoriales deben ser del mismo tipo. En conjuntos de datos con un gran número de columnas, la carga de varias columnas como un solo vector reduce el número de pasos de datos al aplicar transformaciones de datos.

    Esta clase se usa en la ResizeFeatures acción. Los nombres de sus propiedades (en este caso solo uno) se usan para indicar qué columnas de DataView se pueden usar como entrada para la acción de asignación personalizada.

  3. Cree una clase para las características de longitud fija, después de la VariableLength clase :

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

    Esta clase se usa en la ResizeFeatures acción. Los nombres de sus propiedades (en este caso solo una) se usan para indicar qué columnas de la vista de datos se pueden usar como salida de la acción de asignación personalizada.

    Tenga en cuenta que el nombre de la propiedad Features viene determinado por el modelo de TensorFlow. No se puede cambiar este nombre de propiedad.

  4. Cree una clase para la predicción después de la FixedLength clase :

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

    MovieReviewSentimentPrediction es la clase de predicción que se usa después del entrenamiento del modelo. MovieReviewSentimentPrediction tiene una sola float matriz (Prediction) y un VectorType atributo .

  5. Cree otra clase para contener valores de configuración, como la longitud del vector de características:

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

Creación del MLContext, diccionario de búsqueda y acción para redimensionar las características

La clase MLContext es un punto de partida para todas las operaciones de ML.NET. Inicializar mlContext crea un nuevo entorno de ML.NET que se puede compartir entre los objetos de flujo de trabajo de creación de modelos. Es similar, conceptualmente, a DBContext en Entity Framework.

  1. Reemplace la Console.WriteLine("Hello World!") línea por el código siguiente para declarar e inicializar la variable mlContext:

    MLContext mlContext = new MLContext();
    
  2. Cree un diccionario para codificar palabras como enteros utilizando el método LoadFromTextFile para cargar datos de asignación desde un archivo, como se muestra en la tabla siguiente.

    Palabra Index
    Niños 362
    querer 181
    Incorrecto 355
    Efectos 302
    sentimiento 547

    Agregue el código siguiente para crear el mapa de búsqueda:

    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. Agregue un Action para cambiar el tamaño de la matriz de enteros de palabras de longitud variable a una matriz entera de tamaño fijo, con las siguientes líneas de código:

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

Carga del modelo de TensorFlow previamente entrenado

  1. Agregue código para cargar el modelo de TensorFlow:

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

    Una vez cargado el modelo, puede extraer su esquema de entrada y salida. Los esquemas se muestran solo por interés y aprendizaje. No necesita este código para que la aplicación final funcione:

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

    El esquema de entrada es la matriz de longitud fija de palabras codificadas en enteros. El esquema de salida es una matriz flotante de probabilidades que indica si la opinión de una revisión es negativa o positiva. Estos valores suman 1, ya que la probabilidad de ser positiva es el complemento de la probabilidad de que la opinión sea negativa.

Creación de la canalización de ML.NET

  1. Cree la canalización y divida el texto de entrada en palabras mediante la transformación TokenizeIntoWords para dividir el texto en palabras como la siguiente línea de código:

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

    La transformación TokenizeIntoWords usa espacios para analizar el texto o la cadena en palabras. Crea una nueva columna y divide cada cadena de entrada en un vector de subcadenas en función del separador definido por el usuario.

  2. Asigne las palabras a su codificación de enteros mediante la tabla de búsqueda que declaró anteriormente:

    // 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. Cambie el tamaño de las codificaciones de enteros de longitud variable a la longitud fija que requiere el modelo:

    // Resize variable length vector to fixed length vector.
    .Append(mlContext.Transforms.CustomMapping(ResizeFeaturesAction, "Resize"))
    
  4. Clasifique la entrada con el modelo de TensorFlow cargado:

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

    La salida del modelo de TensorFlow se denomina Prediction/Softmax. Tenga en cuenta que el nombre Prediction/Softmax viene determinado por el modelo de TensorFlow. No puede cambiar este nombre.

  5. Cree una nueva columna para la predicción de salida:

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

    Debe copiar la Prediction/Softmax columna en una con un nombre que se pueda usar como propiedad en una clase de C#: Prediction. No se permite el / carácter en un nombre de propiedad de C#.

Creación del modelo de ML.NET a partir de la canalización

  1. Agregue el código para crear el modelo a partir de la canalización:

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

    Se crea un modelo ML.NET a partir de la cadena de estimadores de la canalización llamando al método Fit. En este caso, no haces ningún ajuste de datos para crear el modelo, ya que el modelo de TensorFlow ya se ha entrenado. Se proporciona un objeto de vista de datos vacío para satisfacer los requisitos del Fit método .

Uso del modelo para realizar una predicción

  1. Agregue el PredictSentiment método encima de la MovieReview clase :

    void PredictSentiment(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. Agregue el código siguiente para crear como PredictionEngine la primera línea del PredictSentiment() método :

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

    PredictionEngine es una API útil, que permite realizar una predicción en una sola instancia de datos. PredictionEngine no es seguro para subprocesos. Es aceptable usarlo en entornos de un solo hilo o en prototipos. Para mejorar el rendimiento y la seguridad de los subprocesos en entornos de producción, use el PredictionEnginePool servicio , que crea un ObjectPool de PredictionEngine objetos para su uso en toda la aplicación. Consulte esta guía sobre cómo usar PredictionEnginePool en una API web de ASP.NET Core.

    Nota:

    PredictionEnginePool la extensión de servicio está actualmente en versión preliminar.

  3. Agregue un comentario para probar la predicción del modelo entrenado en el Predict() método mediante la creación de una instancia de MovieReview:

    var review = new MovieReview()
    {
        ReviewText = "this film is really good"
    };
    
  4. Pase los datos del comentario de prueba al Prediction Engine agregando las siguientes líneas de código en el PredictSentiment() método :

    var sentimentPrediction = engine.Predict(review);
    
  5. La función Predict() realiza una predicción en una sola fila de datos:

    Propiedad Importancia Tipo
    Prediction [0.5459937, 0.454006255] flotante[]
  6. Muestre la predicción de opiniones con el código siguiente:

    Console.WriteLine($"Number of classes: {sentimentPrediction.Prediction?.Length}");
    Console.WriteLine($"Is sentiment/review positive? {(sentimentPrediction.Prediction?[1] > 0.5 ? "Yes." : "No.")}");
    
  7. Agregue una llamada a PredictSentiment después de llamar al Fit() método :

    PredictSentiment(mlContext, model);
    

Results

Compile y ejecute su aplicación.

Los resultados deben ser similares a los siguientes. Durante el procesamiento, se muestran los mensajes. Es posible que vea advertencias o mensajes de procesamiento. Estos mensajes se han quitado de los siguientes resultados para mayor claridad.

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

¡Felicidades! Ahora ha creado exitosamente un modelo de aprendizaje automático para clasificar y predecir el sentimiento de los mensajes reutilizando un modelo previamente entrenado TensorFlow en ML.NET.

Puede encontrar el código fuente de este tutorial en el repositorio dotnet/samples .

En este tutorial, ha aprendido a:

  • Carga de un modelo de TensorFlow previamente entrenado
  • Transformar el texto del comentario del sitio web en características adecuadas para el modelo
  • Uso del modelo para realizar una predicción