Implantar um modelo em uma API Web do ASP.NET CoreDeploy a model in an ASP.NET Core Web API

Saiba como fornecer um modelo de machine Learning do ML.NET previamente treinado na Web usando uma API Web do ASP.NET Core.Learn how to serve a pre-trained ML.NET machine learning model on the web using an ASP.NET Core Web API. Veicular um modelo por uma API Web habilita previsões por meio de métodos HTTP padrão.Serving a model over a web API enables predictions via standard HTTP methods.

Observação

A extensão de serviço PredictionEnginePool está atualmente em versão prévia.PredictionEnginePool service extension is currently in preview.

Pré-requisitosPrerequisites

Criar o projeto da API Web do ASP.NET CoreCreate ASP.NET Core Web API project

  1. Abra o Visual Studio 2017.Open Visual Studio 2017. No menu, selecione Arquivo > Novo > Projeto.Select File > New > Project from the menu bar. Na caixa de diálogo Novo projeto, selecione o nó Visual C# seguido pelo nó Web.In the New Project dialog, select the Visual C# node followed by the Web node. Em seguida, selecione o modelo de projeto Aplicativo ASP.NET Core Web.Then select the ASP.NET Core Web Application project template. Na caixa de texto Nome, digite "SentimentAnalysisWebAPI" e, depois, selecione o botão OK.In the Name text box, type "SentimentAnalysisWebAPI" and then select the OK button.

  2. Na janela que exibe os diferentes tipos de projetos do ASP.NET Core, selecione API e, depois, o botão OK.In the window that displays the different types of ASP.NET Core Projects, select API and the select the OK button.

  3. Crie um diretório chamado MLModels em seu projeto para salvar os arquivos de modelo de machine learning criados previamente:Create a directory named MLModels in your project to save your pre-built machine learning model files:

    No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar > Nova Pasta.In Solution Explorer, right-click on your project and select Add > New Folder. Digite "MLModels" e pressione ENTER.Type "MLModels" and hit Enter.

  4. Instalar o Pacote NuGet Microsoft.ML:Install the Microsoft.ML NuGet Package:

    No Gerenciador de Soluções, clique com o botão direito do mouse no seu projeto e selecione Gerenciar Pacotes NuGet.In Solution Explorer, right-click on your project and select Manage NuGet Packages. Escolha "nuget.org" como a origem do pacote, selecione a guia Procurar, pesquise Microsoft.ML, selecione o pacote na lista e selecione o botão Instalar.Choose "nuget.org" as the Package source, select the Browse tab, search for Microsoft.ML, select that package in the list, and select the Install button. Selecione o botão OK na caixa de diálogo Visualizar alterações e, depois, o botão Aceito na caixa de diálogo Aceitação da Licença, se concordar com o termos de licença para os pacotes listados.Select the OK button on the Preview Changes dialog and then select the I Accept button on the License Acceptance dialog if you agree with the license terms for the packages listed.

  5. Instalar o Pacote do Nuget Microsoft.Extensions.ML:Install the Microsoft.Extensions.ML Nuget Package:

    No Gerenciador de Soluções, clique com o botão direito do mouse no seu projeto e selecione Gerenciar Pacotes NuGet.In Solution Explorer, right-click on your project and select Manage NuGet Packages. Escolha "nuget.org" como a origem do pacote, selecione a guia Procurar, pesquise Microsoft.Extensions.ML, selecione o pacote na lista e selecione o botão Instalar.Choose "nuget.org" as the Package source, select the Browse tab, search for Microsoft.Extensions.ML, select that package in the list, and select the Install button. Selecione o botão OK na caixa de diálogo Visualizar alterações e, depois, o botão Aceito na caixa de diálogo Aceitação da Licença, se concordar com o termos de licença para os pacotes listados.Select the OK button on the Preview Changes dialog and then select the I Accept button on the License Acceptance dialog if you agree with the license terms for the packages listed.

Adicionar um modelo ao projeto da API Web do ASP.NET CoreAdd model to ASP.NET Core Web API project

  1. Copie seu modelo previamente criado para o diretório MLModelsCopy your pre-built model to the MLModels directory
  2. No Gerenciador de Soluções, clique com o botão direito do mouse no arquivo zip e selecione Propriedades.In Solution Explorer, right-click the model zip file and select Properties. Em Avançado, altere o valor de Copiar para diretório de saída para Copiar se for mais novo.Under Advanced, change the value of Copy to Output Directory to Copy if newer.

Criar modelo de dadosCreate data models

Você precisa criar algumas classes para os dados e previsões de entrada.You need to create some classes for your input data and predictions. Adicione uma nova classe ao seu projeto:Add a new class to your project:

  1. Crie um diretório chamado DataModels em seu projeto para salvar os modelos de dados:Create a directory named DataModels in your project to save your data models:

    No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar > Nova Pasta.In Solution Explorer, right-click on your project and select Add > New Folder. Digite "DataModels" e pressione ENTER.Type "DataModels" and hit Enter.

  2. No Gerenciador de Soluções, clique com o botão direito do mouse no diretório DataModels e selecione Adicionar > Novo item.In Solution Explorer, right-click the DataModels directory, and then select Add > New Item.

  3. Na caixa de diálogo Adicionar Novo Item, selecione Classe e altere o campo Nome para SentimentData.cs.In the Add New Item dialog box, select Class and change the Name field to SentimentData.cs. Em seguida, selecione o botão Adicionar.Then, select the Add button. O arquivo SentimentData.cs é aberto no editor de códigos.The SentimentData.cs file opens in the code editor. Adicione a seguinte instrução using na parte superior do SentimentData.cs:Add the following using statement to the top of SentimentData.cs:

    using Microsoft.ML.Data;
    

    Remova a definição de classe existente e adicione o seguinte código ao arquivo SentimentData.cs:Remove the existing class definition and add the following code to the SentimentData.cs file:

    public class SentimentData
    {
        [LoadColumn(0)]
        public string SentimentText;
    
        [LoadColumn(1)]
        [ColumnName("Label")]
        public bool Sentiment;
    }
    
  4. No Gerenciador de Soluções, clique com o botão direito do mouse no diretório DataModels e selecione Adicionar > Novo Item.In Solution Explorer, right-click the DataModels directory, and then select Add > New Item.

  5. Na caixa de diálogo Adicionar Novo Item, selecione Classe e altere o campo Nome para SentimentPrediction.cs.In the Add New Item dialog box, select Class and change the Name field to SentimentPrediction.cs. Em seguida, selecione o botão Adicionar.Then, select the Add button. O arquivo SentimentPrediction.cs é aberto no editor de códigos.The SentimentPrediction.cs file opens in the code editor. Adicione a seguinte instrução "using" na parte superior do SentimentPrediction.cs:Add the following using statement to the top of SentimentPrediction.cs:

    using Microsoft.ML.Data;
    

    Remova a definição de classe existente e adicione o seguinte código ao arquivo SentimentPrediction.cs:Remove the existing class definition and add the following code to the SentimentPrediction.cs file:

    public class SentimentPrediction : SentimentData
    {
    
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

    SentimentPrediction herda de SentimentData.SentimentPrediction inherits from SentimentData. Isso torna mais fácil ver os dados originais na propriedade SentimentText junto com a saída gerada pelo modelo.This makes it easier to see the original data in the SentimentText property along with the output generated by the model.

Registrar PredictionEnginePool para uso no aplicativoRegister PredictionEnginePool for use in the application

Para fazer uma única previsão, você precisa criar um PredictionEngine.To make a single prediction, you have to create a PredictionEngine. PredictionEngine não é thread-safe.PredictionEngine is not thread-safe. Além disso, você precisa criar uma instância dela em qualquer lugar em que seja necessário dentro de seu aplicativo.Additionally, you have to create an instance of it everywhere it is needed within your application. À medida que seu aplicativo cresce, esse processo pode se tornar não gerenciável.As your application grows, this process can become unmanageable. Para melhorar o desempenho e a segurança do thread, use uma combinação de injeção de dependência e o serviço PredictionEnginePool, que cria um ObjectPool de objetos PredictionEngine para uso em todo o aplicativo.For improved performance and thread safety, use a combination of dependency injection and the PredictionEnginePool service, which creates an ObjectPool of PredictionEngine objects for use throughout your application.

O link a seguir fornece mais informações se você quiser saber mais sobre injeção de dependência em ASP.NET Core.The following link provides more information if you want to learn more about dependency injection in ASP.NET Core.

  1. Abra a classe Startup.cs e adicione a seguinte instrução using à parte superior do arquivo:Open the Startup.cs class and add the following using statement to the top of the file:

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.ML;
    using SentimentAnalysisWebAPI.DataModels;
    
  2. Adicione o seguinte código ao método ConfigureServices:Add the following code to the ConfigureServices method:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddPredictionEnginePool<SentimentData, SentimentPrediction>()
            .FromFile(modelName: "SentimentAnalysisModel", filePath:"MLModels/sentiment_model.zip", watchForChanges: true);
    }
    

Em um alto nível, esse código inicializa os objetos e os serviços automaticamente para uso posterior quando solicitado pelo aplicativo em vez de ter que fazê-lo manualmente.At a high level, this code initializes the objects and services automatically for later use when requested by the application instead of having to manually do it.

Os modelos de aprendizado de máquina não são estáticos.Machine learning models are not static. À medida que novos dados de treinamento ficam disponíveis, o modelo é retreinado e reimplantado.As new training data becomes available, the model is retrained and redeployed. Uma maneira de obter a versão mais recente do modelo em seu aplicativo é reimplantar o aplicativo inteiro.One way to get the latest version of the model into your application is to redeploy the entire application. No entanto, isso introduz o tempo de inatividade do aplicativo.However, this introduces application downtime. O serviço PredictionEnginePool fornece um mecanismo para recarregar um modelo atualizado sem levar seu aplicativo para baixo.The PredictionEnginePool service provides a mechanism to reload an updated model without taking your application down.

Defina o parâmetro watchForChanges como true, e o PredictionEnginePool inicia um FileSystemWatcher que escuta as notificações de alteração do sistema de arquivos e gera eventos quando há uma alteração no arquivo.Set the watchForChanges parameter to true, and the PredictionEnginePool starts a FileSystemWatcher that listens to the file system change notifications and raises events when there is a change to the file. Isso solicita que o PredictionEnginePool recarregue o modelo automaticamente.This prompts the PredictionEnginePool to automatically reload the model.

O modelo é identificado pelo parâmetro modelName para que mais de um modelo por aplicativo possa ser recarregado após a alteração.The model is identified by the modelName parameter so that more than one model per application can be reloaded upon change.

Dica

Como alternativa, você pode usar o método FromUri ao trabalhar com modelos armazenados remotamente.Alternatively, you can use the FromUri method when working with models stored remotely. Em vez de observar os eventos de alteração de arquivo, FromUri pesquisa o local remoto em busca de alterações.Rather than watching for file changed events, FromUri polls the remote location for changes. O padrão do intervalo de sondagem é de 5 minutos.The polling interval defaults to 5 minutes. Você pode aumentar ou diminuir o intervalo de sondagem com base nos requisitos do seu aplicativo.You can increase or decrease the polling interval based on your application's requirements. No exemplo de código abaixo, o PredictionEnginePool sonda o modelo armazenado no URI especificado a cada minuto.In the code sample below, the PredictionEnginePool polls the model stored at the specified URI every minute.

builder.Services.AddPredictionEnginePool<SentimentData, SentimentPrediction>()
  .FromUri(
      modelName: "SentimentAnalysisModel", 
      uri:"https://github.com/dotnet/samples/raw/master/machine-learning/models/sentimentanalysis/sentiment_model.zip", 
      period: TimeSpan.FromMinutes(1));

Criar o Controlador de PrevisãoCreate Predict controller

Para processar as solicitações HTTP de entrada, crie um controlador.To process your incoming HTTP requests, create a controller.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no diretório Controladores e selecione Adicionar > Controlador.In Solution Explorer, right-click the Controllers directory, and then select Add > Controller.

  2. Na caixa de diálogo Adicionar Novo Item, selecione Controlador de API Vazio e, então, Adicionar.In the Add New Item dialog box, select API Controller Empty and select Add.

  3. No prompt, altere o campo do Nome do Controlador para PredictController.cs.In the prompt change the Controller Name field to PredictController.cs. Em seguida, selecione o botão Adicionar.Then, select the Add button. O arquivo PredictController.cs é aberto no editor de códigos.The PredictController.cs file opens in the code editor. Adicione a seguinte instrução using na parte superior do PredictController.cs:Add the following using statement to the top of PredictController.cs:

    using System;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.ML;
    using SentimentAnalysisWebAPI.DataModels;
    

    Remova a definição de classe existente e adicione o seguinte código ao arquivo PredictController.cs:Remove the existing class definition and add the following code to the PredictController.cs file:

    public class PredictController : ControllerBase
    {
        private readonly PredictionEnginePool<SentimentData, SentimentPrediction> _predictionEnginePool;
    
        public PredictController(PredictionEnginePool<SentimentData,SentimentPrediction> predictionEnginePool)
        {
            _predictionEnginePool = predictionEnginePool;
        }
    
        [HttpPost]
        public ActionResult<string> Post([FromBody] SentimentData input)
        {
            if(!ModelState.IsValid)
            {
                return BadRequest();
            }
    
            SentimentPrediction prediction = _predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", example: input);
    
            string sentiment = Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative";
    
            return Ok(sentiment);
        }
    }
    

Esse código atribui o PredictionEnginePool passando-o para o construtor do controlador que você obtém por meio da injeção de dependência.This code assigns the PredictionEnginePool by passing it to the controller's constructor which you get via dependency injection. Em seguida, o método Post do controlador Predict usa o PredictionEnginePool para fazer previsões usando o SentimentAnalysisModel registrado na classe Startup e retorna os resultados de volta para o usuário, se for bem-sucedido.Then, the Predict controller's Post method uses the PredictionEnginePool to make predictions using the SentimentAnalysisModel registered in the Startup class and returns the results back to the user if successful.

Testar a API Web localmenteTest web API locally

Depois que tudo estiver definido, é hora de testar o aplicativo.Once everything is set up, it's time to test the application.

  1. Execute o aplicativo.Run the application.

  2. Abra o Powershell e digite o seguinte código, em que PORT é a porta em que seu aplicativo está escutando.Open Powershell and enter the following code where PORT is the port your application is listening on.

    Invoke-RestMethod "https://localhost:<PORT>/api/predict" -Method Post -Body (@{SentimentText="This was a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
    

    Se houver êxito, a saída deverá ser semelhante ao texto abaixo:If successful, the output should look similar to the text below:

    Negative
    

Parabéns!Congratulations! Você usou com êxito seu modelo para fazer previsões pela internet usando um ASP.NET Core API Web.You have successfully served your model to make predictions over the internet using an ASP.NET Core Web API.

Próximas etapasNext Steps