Een model implementeren in Azure Functions

Meer informatie over het implementeren van een vooraf getraind ML.NET machine learning-model voor voorspellingen via HTTP via een serverloze Azure Functions-omgeving.

Vereisten

Overzicht van Azure Functions-voorbeeld

Dit voorbeeld is een C# HTTP Trigger Azure Functions-toepassing die gebruikmaakt van een vooraf getraind binair classificatiemodel om het gevoel van tekst als positief of negatief te categoriseren. Azure Functions biedt een eenvoudige manier om kleine stukjes code op schaal uit te voeren op een beheerde serverloze omgeving in de cloud. De code voor dit voorbeeld vindt u in de opslagplaats dotnet/machinelearning-samples op GitHub.

Een Azure Functions-project maken

  1. Open in Visual Studio 2022 het dialoogvenster Een nieuw project maken.

  2. Selecteer in het dialoogvenster Een nieuw project maken de Azure Functions-projectsjabloon .

  3. Typ 'SentimentAnalysisFunctionsApp' in het tekstvak Naam en selecteer de knop Volgende .

  4. Laat in het dialoogvenster Aanvullende informatie alle standaardwaarden staan en selecteer de knop Maken .

  5. Het Microsoft.ML NuGet-pakket installeren

    1. Klik in Solution Explorer met de rechtermuisknop op uw project en selecteer NuGet-pakketten beheren.
    2. Kies 'nuget.org' als pakketbron.
    3. Selecteer het tabblad Bladeren.
    4. Zoek naar Microsoft.ML.
    5. Selecteer dat pakket in de lijst en selecteer de knop Installeren .
    6. Selecteer de knop OK in het dialoogvenster Voorbeeldwijzigingen
    7. Selecteer de knop Accepteren in het dialoogvenster Licentie accepteren als u akkoord gaat met de licentievoorwaarden voor de vermelde pakketten.

    Volg dezelfde stappen om de nuGet-pakketten Microsoft.Extensions.ML, Microsoft.Extensions.DependencyInjection en Microsoft.Azure.Functions.Extensions Te installeren.

Vooraf getraind model toevoegen aan project

  1. Maak een map met de naam MLModels in uw project om uw vooraf gemaakte model op te slaan: Klik in Solution Explorer met de rechtermuisknop op uw project en selecteer Nieuwe map toevoegen>. Typ MLModels en druk op Enter.
  2. Kopieer uw vooraf gebouwde model naar de map MLModels .
  3. Klik in Solution Explorer met de rechtermuisknop op het vooraf gemaakte modelbestand en selecteer Eigenschappen. Wijzig onder Geavanceerd de waarde van Kopiëren naar Uitvoermap om te kopiëren als nieuwer.

Een Azure-functie maken om sentiment te analyseren

Maak een klasse om sentiment te voorspellen. Voeg een nieuwe klasse toe aan uw project:

  1. Klik in Solution Explorer met de rechtermuisknop op het project en selecteer Nieuwe Azure-functie toevoegen>.

  2. Selecteer in het dialoogvenster Nieuw item toevoegen De Azure-functie en wijzig het veld Naam in AnalyzeSentiment.cs. Selecteer vervolgens de knop Toevoegen .

  3. Selecteer In het dialoogvenster Nieuwe Azure-functie http-trigger en kies Anoniem in de vervolgkeuzelijst Autorisatieniveau. Selecteer vervolgens de knop OK .

    Het bestand AnalyzeSentiment.cs wordt geopend in de code-editor. Voeg de volgende using instructie toe aan het begin van AnalyzeSentiment.cs:

    using System;
    using System.IO;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Microsoft.Extensions.ML;
    using SentimentAnalysisFunctionsApp.DataModels;
    

    Standaard is staticde AnalyzeSentiment klasse . Zorg ervoor dat u het static trefwoord uit de klassedefinitie verwijdert.

    public class AnalyzeSentiment
    {
    
    }
    

Gegevensmodellen maken

U moet enkele klassen maken voor uw invoergegevens en voorspellingen. Voeg een nieuwe klasse toe aan uw project:

  1. Maak een map met de naam DataModels in uw project om uw gegevensmodellen op te slaan: Klik in Solution Explorer met de rechtermuisknop op uw project en selecteer Nieuwe map toevoegen>. Typ 'DataModels' en druk op Enter.

  2. Klik in Solution Explorer met de rechtermuisknop op de map DataModels en selecteer Klasse toevoegen.>

  3. Selecteer in het dialoogvenster Nieuw item toevoegen de optie Klasse en wijzig het veld Naam in SentimentData.cs. Selecteer vervolgens de knop Toevoegen .

    Het bestand SentimentData.cs wordt geopend in de code-editor. Voeg de volgende using-instructie toe aan het begin van SentimentData.cs:

    using Microsoft.ML.Data;
    

    Verwijder de bestaande klassedefinitie en voeg de volgende code toe aan het SentimentData.cs-bestand :

    public class SentimentData
    {
        [LoadColumn(0)]
        public string SentimentText;
    
        [LoadColumn(1)]
        [ColumnName("Label")]
        public bool Sentiment;
    }
    
  4. Klik in Solution Explorer met de rechtermuisknop op de map DataModels en selecteer Klasse toevoegen.>

  5. Selecteer in het dialoogvenster Nieuw item toevoegen de optie Klasse en wijzig het veld Naam in SentimentPrediction.cs. Selecteer vervolgens de knop Toevoegen . Het SentimentPrediction.cs-bestand wordt geopend in de code-editor. Voeg de volgende using-instructie toe aan het begin van SentimentPrediction.cs:

    using Microsoft.ML.Data;
    

    Verwijder de bestaande klassedefinitie en voeg de volgende code toe aan het bestand SentimentPrediction.cs :

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

    SentimentPredictionSentimentData neemt over van waaruit toegang wordt verkregen tot de oorspronkelijke gegevens in de SentimentText eigenschap, evenals de uitvoer die door het model wordt gegenereerd.

PredictionEnginePool-service registreren

Als u één voorspelling wilt doen, moet u een PredictionEngine. PredictionEngine is niet thread-safe. Daarnaast moet u overal een exemplaar van het exemplaar maken dat nodig is in uw toepassing. Naarmate uw toepassing groeit, kan dit proces onbeheerbaar worden. Gebruik voor betere prestaties en threadveiligheid een combinatie van afhankelijkheidsinjectie en de PredictionEnginePool service, waarmee een ObjectPool van PredictionEngine de objecten wordt gemaakt voor gebruik in uw toepassing.

De volgende koppeling bevat meer informatie als u meer wilt weten over afhankelijkheidsinjectie.

  1. Klik in Solution Explorer met de rechtermuisknop op het project en selecteer Klasse toevoegen>.

  2. Selecteer in het dialoogvenster Nieuw item toevoegen de optie Klasse en wijzig het veld Naam in Startup.cs. Selecteer vervolgens de knop Toevoegen .

  3. Voeg de volgende using-instructies toe aan het begin van Startup.cs:

    using Microsoft.Azure.Functions.Extensions.DependencyInjection;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.ML;
    using SentimentAnalysisFunctionsApp;
    using SentimentAnalysisFunctionsApp.DataModels;
    using System.IO;
    using System;
    
  4. Verwijder de bestaande code onder de using-instructies en voeg de volgende code toe:

    [assembly: FunctionsStartup(typeof(Startup))]
    namespace SentimentAnalysisFunctionsApp
    {
        public class Startup : FunctionsStartup
        {
    
        }
    }
    
  5. Definieer variabelen voor het opslaan van de omgeving waarin de app wordt uitgevoerd en het bestandspad waarin het model zich in de Startup klasse bevindt

    private readonly string _environment;
    private readonly string _modelPath;
    
  6. Maak daaronder een constructor om de waarden van de _environment en _modelPath variabelen in te stellen. Wanneer de toepassing lokaal wordt uitgevoerd, is de standaardomgeving Ontwikkeling.

    public Startup()
    {
        _environment = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT");
    
        if (_environment == "Development")
        {
            _modelPath = Path.Combine("MLModels", "sentiment_model.zip");
        }
        else
        {
            string deploymentPath = @"D:\home\site\wwwroot\";
            _modelPath = Path.Combine(deploymentPath, "MLModels", "sentiment_model.zip");
        }
    }
    
  7. Voeg vervolgens een nieuwe methode toe die wordt aangeroepen Configure om de PredictionEnginePool service onder de constructor te registreren.

    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddPredictionEnginePool<SentimentData, SentimentPrediction>()
            .FromFile(modelName: "SentimentAnalysisModel", filePath: _modelPath, watchForChanges: true);
    }
    

Op hoog niveau initialiseert deze code de objecten en services automatisch voor later gebruik wanneer deze door de toepassing worden aangevraagd, in plaats van dit handmatig te doen.

Machine learning-modellen zijn niet statisch. Naarmate er nieuwe trainingsgegevens beschikbaar komen, wordt het model opnieuw getraind en opnieuw geïmplementeerd. Een manier om de nieuwste versie van het model in uw toepassing op te halen, is door uw toepassing opnieuw te starten of opnieuw te implementeren. Dit introduceert echter downtime van toepassingen. De PredictionEnginePool service biedt een mechanisme voor het opnieuw laden van een bijgewerkt model zonder uw toepassing opnieuw te starten of opnieuw te implementeren.

Stel de watchForChanges parameter in op true, en de PredictionEnginePool start een FileSystemWatcher die luistert naar de meldingen van het bestandssysteemwijziging en gebeurtenissen genereert wanneer er een wijziging in het bestand is. Hiermee wordt gevraagd PredictionEnginePool het model automatisch opnieuw te laden.

Het model wordt geïdentificeerd door de modelName parameter, zodat meer dan één model per toepassing opnieuw kan worden geladen bij wijziging.

Tip

U kunt ook de methode gebruiken bij het FromUri werken met modellen die extern zijn opgeslagen. In plaats van te kijken naar gewijzigde gebeurtenissen van bestanden, FromUri wordt de externe locatie gecontroleerd op wijzigingen. Het polling-interval wordt standaard ingesteld op 5 minuten. U kunt het polling-interval verhogen of verlagen op basis van de vereisten van uw toepassing. In het onderstaande codevoorbeeld wordt het PredictionEnginePool model elke minuut opgeslagen op de opgegeven URI gepeild.

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

Het model in de functie laden

Voeg de volgende code in de klasse AnalyzeSentiment in :

public AnalyzeSentiment(PredictionEnginePool<SentimentData, SentimentPrediction> predictionEnginePool)
{
    _predictionEnginePool = predictionEnginePool;
}

Met deze code wordt de PredictionEnginePool code toegewezen door deze door te geven aan de constructor van de functie die u krijgt via afhankelijkheidsinjectie.

Het model gebruiken om voorspellingen te doen

Vervang de bestaande implementatie van de Run-methode in de klasse AnalyzeSentiment door de volgende code:

public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    // Parse HTTP Request Body
    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    SentimentData data = JsonConvert.DeserializeObject<SentimentData>(requestBody);

    //Make Prediction
    SentimentPrediction prediction = _predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", example: data);

    //Convert prediction to string
    string sentiment = Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative";

    //Return Prediction
    return new OkObjectResult(sentiment);
}

Wanneer de Run methode wordt uitgevoerd, worden de binnenkomende gegevens van de HTTP-aanvraag gedeserialiseerd en gebruikt als invoer voor de PredictionEnginePool. De Predict methode wordt vervolgens aangeroepen om voorspellingen te doen met behulp van de SentimentAnalysisModel geregistreerde in de Startup klasse en retourneert de resultaten terug naar de gebruiker als dit lukt.

Lokaal testen

Nu alles is ingesteld, is het tijd om de toepassing te testen:

  1. De toepassing uitvoeren

  2. Open PowerShell en voer de code in de prompt in waar POORT de poort is waarop uw toepassing wordt uitgevoerd. Normaal gesproken is de poort 7071.

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

    Als dit lukt, moet de uitvoer er ongeveer uitzien als in de onderstaande tekst:

    Negative
    

Gefeliciteerd U hebt uw model geleverd om voorspellingen te doen via internet met behulp van een Azure-functie.

Volgende stappen