Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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
- Visual Studio 2022 o posterior con la carga de trabajo Desarrollo de escritorio de .NET instalada.
Configuración
Creación de la aplicación
Cree una aplicación de consola de C# denominada "TextClassificationTF". Haga clic en el botón Siguiente .
Elija .NET 8 como marco de trabajo que se va a usar. Haga clic en el botón Crear.
Cree un directorio denominado Data en el proyecto para guardar los archivos del conjunto de datos.
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.
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.
-
Copie el contenido del directorio más interno
sentiment_modelen el directorio TextClassificationTF del proyectosentiment_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:
En el Explorador de soluciones, haga clic con el botón derecho en cada uno de los archivos del
sentiment_modeldirectorio 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
Agregue las siguientes directivas adicionales
usinga la parte superior del archivo Program.cs :using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms;Cree una variable global justo después de las
usingdirectivas para almacenar la ruta de acceso del archivo del modelo guardado.string _modelPath = Path.Combine(Environment.CurrentDirectory, "sentiment_model");-
_modelPathes 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] |
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 unstringpara los comentarios del usuario (ReviewText).Cree una clase para las características de longitud variable después de la
MovieReviewclase :/// <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
VariableLengthFeaturespropiedad 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
ResizeFeaturesacció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.Cree una clase para las características de longitud fija, después de la
VariableLengthclase :/// <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
ResizeFeaturesacció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
Featuresviene determinado por el modelo de TensorFlow. No se puede cambiar este nombre de propiedad.Cree una clase para la predicción después de la
FixedLengthclase :/// <summary> /// Class to contain the output values from the transformation. /// </summary> public class MovieReviewSentimentPrediction { [VectorType(2)] public float[]? Prediction { get; set; } }MovieReviewSentimentPredictiones la clase de predicción que se usa después del entrenamiento del modelo.MovieReviewSentimentPredictiontiene una solafloatmatriz (Prediction) y unVectorTypeatributo .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.
Reemplace la
Console.WriteLine("Hello World!")línea por el código siguiente para declarar e inicializar la variable mlContext:MLContext mlContext = new MLContext();Cree un diccionario para codificar palabras como enteros utilizando el método
LoadFromTextFilepara 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: ',' );Agregue un
Actionpara 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
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
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.
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"))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"))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 nombrePrediction/Softmaxviene determinado por el modelo de TensorFlow. No puede cambiar este nombre.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/Softmaxcolumna 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
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 delFitmétodo .
Uso del modelo para realizar una predicción
Agregue el
PredictSentimentmétodo encima de laMovieReviewclase :void PredictSentiment(MLContext mlContext, ITransformer model) { }Agregue el código siguiente para crear como
PredictionEnginela primera línea delPredictSentiment()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.
PredictionEngineno 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 elPredictionEnginePoolservicio , que crea unObjectPooldePredictionEngineobjetos para su uso en toda la aplicación. Consulte esta guía sobre cómo usarPredictionEnginePoolen una API web de ASP.NET Core.Nota:
PredictionEnginePoolla extensión de servicio está actualmente en versión preliminar.Agregue un comentario para probar la predicción del modelo entrenado en el
Predict()método mediante la creación de una instancia deMovieReview:var review = new MovieReview() { ReviewText = "this film is really good" };Pase los datos del comentario de prueba al
Prediction Engineagregando las siguientes líneas de código en elPredictSentiment()método :var sentimentPrediction = engine.Predict(review);La función Predict() realiza una predicción en una sola fila de datos:
Propiedad Importancia Tipo Prediction [0.5459937, 0.454006255] flotante[] 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.")}");Agregue una llamada a
PredictSentimentdespués de llamar alFit()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