Implementación de un modelo en una ASP.NET Core Web API
Aprenda cómo publicar un modelo de Machine Learning de ML.NET entrenado previamente en la Web a través de una ASP.NET Core Web API. Publicar un modelo a través de una API web permite predicciones mediante métodos HTTP estándar.
Requisitos previos
- Visual Studio 2022 con la carga de trabajo de desarrollo de ASP.NET y web.
- PowerShell.
- Modelo previamente entrenado. Use el tutorial de análisis de sentimiento de ML.NET para generar su propio modelo o descargue este modelo de Machine Learning de análisis de sentimiento entrenado previamente.
Creación de un proyecto de ASP.NET Core Web API
Inicie Visual Studio 2022 y seleccione Crear un proyecto.
En el cuadro de diálogo Crear un proyecto:
- Escriba
Web API
en el cuadro de búsqueda. - Seleccione la plantilla API web de ASP.NET Core y seleccione Siguiente.
- Escriba
En el cuadro de diálogo Configure el proyecto:
- Asigne al proyecto el nombre SentimentAnalysisWebAPI.
- Seleccione Next (Siguiente).
En el cuadro de diálogo Información adicional:
- Anule la sección de No usar instrucciones de nivel superior.
- Seleccione Crear.
Instale los siguientes paquetes NuGet:
Para obtener más información sobre cómo instalar paquetes de en Visual Studio, consulte la guía Instalación y uso de un paquete NuGet en Visual Studio.
Incorporación del modelo a un proyecto de ASP.NET Core Web API
Copie el modelo pregenerado en el directorio del proyecto SentimentAnalysisWebAPI.
Configure el proyecto para copiar el archivo de modelo en el directorio de salida. En el Explorador de soluciones:
- Haga clic con el botón derecho en el archivo ZIP del modelo y seleccione Propiedades.
- En Avanzadas, cambie el valor de Copiar en el directorio de salida por Copiar si es posterior.
Creación de modelos de datos
Debe crear algunas clases para definir el esquema de la entrada y salida del modelo.
Nota
Las propiedades de las clases de esquema de entrada y salida dependen de las columnas del conjunto de datos usadas para entrenar el modelo, así como de la tarea de aprendizaje automático (regresión, clasificación, etc.).
En el archivo Program.cs:
Agregue las siguientes directivas
using
:using Microsoft.ML.Data; using Microsoft.Extensions.ML;
En la parte inferior del archivo, agregue las siguientes clases:
Entrada del modelo
Para este modelo, la entrada contiene una sola propiedad
SentimentText
, que es una cadena que representa un comentario de usuario.public class ModelInput { public string SentimentText; }
Salida del modelo
Una vez que el modelo evalúa la entrada, genera una predicción con tres propiedades:
Sentiment
,Probability
yScore
. En este caso,Sentiment
es la opinión prevista del comentario del usuario yProbability
yScore
son medidas de confianza para la predicción.public class ModelOutput { [ColumnName("PredictedLabel")] public bool Sentiment { get; set; } public float Probability { get; set; } public float Score { get; set; } }
Registro de PredictionEngine para usarlo en la aplicación
Para realizar una sola predicción, tendrá que crear un objeto PredictionEngine
. PredictionEngine
no es seguro para subprocesos. Además, tiene que crear una instancia de ella en cualquier lugar en que se necesite dentro de la aplicación. A medida que crece la aplicación, este proceso puede volverse difícil de administrar. Para mejorar el rendimiento y la seguridad para subprocesos, use una combinación de inserción de dependencias y el servicio PredictionEnginePool
, que crea un elemento ObjectPool
de objetos PredictionEngine
para usarlo en toda la aplicación.
En el vínculo siguiente se proporciona más información si quiere aprender sobre la inserción de dependencias en ASP.NET Core.
Agregue el código siguiente al archivo Program.cs:
builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
.FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", watchForChanges: true);
En un nivel alto, este código inicializa los objetos y servicios de manera automática para su uso más adelante cuando lo solicite la aplicación en lugar de tener que hacerlo manualmente.
Los modelos de Machine Learning no son estáticos. A medida que haya nuevos datos de entrenamiento disponibles, el modelo se vuelve a entrenar y a implementar. Una manera de obtener la versión más reciente del modelo en la aplicación es volver a empezar o volver a implementar la aplicación. Sin embargo, esto implica un tiempo de inactividad de la aplicación. El servicio PredictionEnginePool
proporciona un mecanismo para volver a cargar un modelo actualizado sin necesidad de volver a empezar o volver a implementar la aplicación.
Establezca el parámetro watchForChanges
en true
y el PredictionEnginePool
inicia un FileSystemWatcher
que escucha las notificaciones de cambios en el sistema de archivos y genera eventos cuando se produce un cambio en el archivo. Este solicita al PredictionEnginePool
que vuelva a cargar automáticamente el modelo.
El modelo se identifica mediante el parámetro modelName
, por lo que se puede volver a cargar más de un modelo por aplicación tras el cambio.
Sugerencia
Como alternativa, puede usar el método FromUri
al trabajar con modelos almacenados de manera remota. En lugar de ver si hay eventos modificados de archivo, FromUri
sondea la ubicación remota en busca de cambios. El intervalo de sondeo predeterminado es de 5 minutos. Puede aumentar o disminuir el intervalo de sondeo en función de los requisitos de la aplicación. En el ejemplo de código siguiente, PredictionEnginePool
sondea el modelo almacenado en el URI especificado cada minuto.
services.AddPredictionEnginePool<SentimentData, SentimentPrediction>()
.FromUri(
modelName: "SentimentAnalysisModel",
uri:"https://github.com/dotnet/samples/raw/main/machine-learning/models/sentimentanalysis/sentiment_model.zip",
period: TimeSpan.FromMinutes(1));
Asignación de punto de conexión de predicción
Para procesar las solicitudes HTTP entrantes, cree un punto de conexión.
Reemplace el punto de conexión /
por lo siguiente:
var predictionHandler =
async (PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool, ModelInput input) =>
await Task.FromResult(predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", input));
app.MapPost("/predict", predictionHandler);
El punto de conexión /predict
acepta solicitudes HTTP POST y usa el grupo del motor de predicción para devolver una predicción mediante la entrada proporcionada.
Cuando haya terminado, program.cs debe tener un aspecto similar al siguiente:
using Microsoft.ML.Data;
using Microsoft.Extensions.ML;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
.FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", watchForChanges: true);
var app = builder.Build();
var predictionHandler =
async (PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool, ModelInput input) =>
await Task.FromResult(predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", input));
app.MapPost("/predict", predictionHandler);
app.Run();
public class ModelInput
{
public string SentimentText;
}
public class ModelOutput
{
[ColumnName("PredictedLabel")]
public bool Sentiment { get; set; }
public float Probability { get; set; }
public float Score { get; set; }
}
Prueba local de Web API
Una vez que todo está configurado, es momento de probar la aplicación.
Ejecute la aplicación.
Abra PowerShell y escriba el código siguiente, donde PORT es el puerto donde escuchar la aplicación.
Invoke-RestMethod "https://localhost:<PORT>/predict" -Method Post -Body (@{SentimentText="This was a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
Si se realiza correctamente, la salida debería ser similar al texto siguiente:
sentiment probability score --------- ----------- ----- False 0.5 0
¡Enhorabuena! Publicó correctamente el modelo para realizar predicciones en Internet mediante una ASP.NET Core Web API.