Distribuera en modell i ett ASP.NET Core-webb-API

Lär dig hur du hanterar en förtränad ML.NET maskininlärningsmodell på webben med hjälp av ett ASP.NET Core-webb-API. Att hantera en modell via ett webb-API möjliggör förutsägelser via vanliga HTTP-metoder.

Förutsättningar

Skapa ASP.NET Core Web API-projekt

  1. Starta Visual Studio 2022 och välj Skapa ett nytt projekt.

  2. I dialogrutan Skapa ett nytt projekt:

    • Ange Web API i sökrutan.
    • Välj mallen ASP.NET Core Web API och välj Nästa.
  3. I dialogrutan Konfigurera projektet:

    • Ge projektet namnet SentimentAnalysisWebAPI.
    • Välj Nästa.
  4. I dialogrutan Ytterligare information :

    • Avmarkera Använd inte toppnivåinstruktioner.
    • Välj Skapa.
  5. Installera följande NuGet-paket:

    Mer information om hur du installerar NuGet-paket i Visual Studio finns i guiden Installera och använda ett NuGet-paket i Visual Studio .

Lägga till modell i ASP.NET Core Web API-projekt

  1. Kopiera din färdiga modell till din SentimentAnalysisWebAPI-projektkatalog .

  2. Konfigurera projektet för att kopiera modellfilen till utdatakatalogen. I Solution Explorer:

    • Högerklicka på zip-filen modell och välj Egenskaper.
    • Under Avancerat ändrar du värdet för Kopiera till utdatakatalog till Kopiera om det är nyare.

Skapa datamodeller

Du måste skapa några klasser för att definiera schemat för indata och utdata för modellen.

Kommentar

Egenskaperna för dina indata- och utdataschemaklasser beror på de datamängdskolumner som används för att träna din modell samt maskininlärningsuppgiften (regression, klassificering osv.).

I din Program.cs-fil :

  1. Lägg till följande using-uttryck:

    using Microsoft.ML.Data;
    using Microsoft.Extensions.ML;
    
  2. Lägg till följande klasser längst ned i filen:

    Modellindata

    För den här modellen innehåller indata en enda egenskap SentimentText som är en sträng som representerar en användarkommentare.

    public class ModelInput
    {
        public string SentimentText;
    }
    

    Modellutdata

    När modellen utvärderar indata returnerar den en förutsägelse med tre egenskaper: Sentiment, Probabilityoch Score. I det här fallet Sentiment är den förutsagda attityden för användarkommentatorn och Probability och Score är konfidensmått för förutsägelsen.

    public class ModelOutput
    {
        [ColumnName("PredictedLabel")]
        public bool Sentiment { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

Registrera PredictionEnginePool för användning i programmet

Om du vill göra en enda förutsägelse måste du skapa en PredictionEngine. PredictionEngine är inte trådsäker. Dessutom måste du skapa en instans av den överallt där den behövs i ditt program. När programmet växer kan den här processen bli ohanterlig. För bättre prestanda och trådsäkerhet använder du en kombination av beroendeinmatning och PredictionEnginePool tjänsten, som skapar en ObjectPool av PredictionEngine objekt som kan användas i hela programmet.

Följande länk innehåller mer information om du vill veta mer om beroendeinmatning i ASP.NET Core.

Lägg till följande kod i din Program.cs-fil :

builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
    .FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", watchForChanges: true);

På hög nivå initierar den här koden objekten och tjänsterna automatiskt för senare användning när programmet begär det i stället för att behöva göra det manuellt.

Maskininlärningsmodeller är inte statiska. När nya träningsdata blir tillgängliga tränas modellen om och distribueras om. Ett sätt att hämta den senaste versionen av modellen i ditt program är att starta om eller distribuera om programmet. Detta medför dock programavbrott. Tjänsten PredictionEnginePool tillhandahåller en mekanism för att läsa in en uppdaterad modell igen utan att starta om eller distribuera om programmet.

Ange parametern watchForChanges till true, och PredictionEnginePool startar en FileSystemWatcher som lyssnar på meddelanden om filsystemets ändring och genererar händelser när filen ändras. Detta uppmanar PredictionEnginePool till att automatiskt läsa in modellen igen.

Modellen identifieras av parametern modelName så att fler än en modell per program kan läsas in igen vid ändring.

Dricks

Du kan också använda FromUri metoden när du arbetar med modeller som lagras på distans. I stället för att titta efter ändrade filhändelser avsöker FromUri du fjärrplatsen efter ändringar. Avsökningsintervallet är som standard 5 minuter. Du kan öka eller minska avsökningsintervallet baserat på programmets krav. I kodexemplet nedan PredictionEnginePool avsöker modellen som lagras vid den angivna URI:n varje minut.

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));

Mappa förutsägelseslutpunkt

Om du vill bearbeta dina inkommande HTTP-begäranden skapar du en slutpunkt.

/ Ersätt slutpunkten med följande:

var predictionHandler =
    async (PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool, ModelInput input) =>
        await Task.FromResult(predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", input));

app.MapPost("/predict", predictionHandler);

Slutpunkten /predict accepterar HTTP POST-begäranden och använder förutsägelsemotorpoolen för att returnera en förutsägelse med hjälp av angivna indata.

När du är klar bör din Program.cs se ut så här:

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

Testa webb-API lokalt

När allt har konfigurerats är det dags att testa programmet.

  1. Kör programmet.

  2. Öppna PowerShell och ange följande kod där PORT är den port som programmet lyssnar på.

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

    Om det lyckas bör utdata se ut ungefär som texten nedan:

    sentiment probability score
    --------- ----------- -----
    False         0.5     0
    

Grattis! Du har hanterat din modell för att göra förutsägelser via Internet med hjälp av ett ASP.NET Core Web API.

Nästa steg