Voorspellingen doen met een AutoML ONNX-model in .NET

In dit artikel leert u hoe u een Geautomatiseerd ML-model (AutoML) Open Neural Network Exchange (ONNX) gebruikt om voorspellingen te doen in een C# .NET Core-consoletoepassing met ML.NET.

ML.NET is een open-source, platformoverschrijdend machine learning-framework voor het .NET-ecosysteem waarmee u aangepaste machine learning-modellen kunt trainen en gebruiken met behulp van een code-first-benadering in C# of F# en via hulpprogramma's met weinig code, zoals Model Builder en de ML.NET CLI. Het framework is ook uitbreidbaar en biedt u de mogelijkheid om andere populaire machine learning-frameworks, zoals TensorFlow en ONNX, te gebruiken.

ONNX is een opensource-indeling voor AI-modellen. ONNX ondersteunt interoperabiliteit tussen frameworks. Dit betekent dat u een model kunt trainen in een van de vele populaire machine learning-frameworks zoals PyTorch, het kunt converteren naar ONNX-indeling en het ONNX-model in een ander framework kunt gebruiken, zoals ML.NET. Ga naar de ONNX-website voor meer informatie.

Vereisten

Een C#-consoletoepassing maken

In dit voorbeeld gebruikt u de .NET Core CLI om uw toepassing te bouwen, maar u kunt dezelfde taken uitvoeren met Behulp van Visual Studio. Meer informatie over de .NET Core CLI.

  1. Open een terminal en maak een nieuwe C# .NET Core-consoletoepassing. In dit voorbeeld is AutoMLONNXConsoleAppde naam van de toepassing. Er wordt een map gemaakt met dezelfde naam met de inhoud van uw toepassing.

    dotnet new console -o AutoMLONNXConsoleApp
    
  2. Navigeer in de terminal naar de map AutoMLONNXConsoleApp .

    cd AutoMLONNXConsoleApp
    

Softwarepakketten toevoegen

  1. Installeer de Microsoft.ML, Microsoft.ML.OnnxRuntime en Microsoft.ML.OnnxTransformer NuGet-pakketten met behulp van de .NET Core CLI.

    dotnet add package Microsoft.ML
    dotnet add package Microsoft.ML.OnnxRuntime
    dotnet add package Microsoft.ML.OnnxTransformer
    

    Deze pakketten bevatten de afhankelijkheden die vereist zijn voor het gebruik van een ONNX-model in een .NET-toepassing. ML.NET biedt een API die gebruikmaakt van de ONNX-runtime voor voorspellingen.

  2. Open het bestand Program.cs en voeg bovenaan de volgende using instructies toe om te verwijzen naar de juiste pakketten.

    using System.Linq;
    using Microsoft.ML;
    using Microsoft.ML.Data;
    using Microsoft.ML.Transforms.Onnx;
    

Een verwijzing toevoegen naar het ONNX-model

Een manier om de consoletoepassing toegang te geven tot het ONNX-model is door deze toe te voegen aan de uitvoermap van de build. Zie de MSBuild-handleiding voor meer informatie over algemene MSBuild-items. Als u nog geen model hebt, volgt u dit notebook om een voorbeeldmodel te maken.

Een verwijzing toevoegen naar uw ONNX-modelbestand in uw toepassing

  1. Kopieer uw ONNX-model naar de hoofdmap autoMLONNXConsoleApp van uw toepassing.

  2. Open het bestand AutoMLONNXConsoleApp.csproj en voeg de volgende inhoud toe in het Project knooppunt.

    <ItemGroup>
        <None Include="automl-model.onnx">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
    </ItemGroup>
    

    In dit geval is de naam van het ONNX-modelbestand automl-model.onnx.

  3. Open het bestand Program.cs en voeg de volgende regel toe in de Program klasse.

    static string ONNX_MODEL_PATH = "automl-model.onnx";
    

MLContext initialiseren

Maak in de Main methode van uw Program klasse een nieuw exemplaar van MLContext.

MLContext mlContext = new MLContext();

De MLContext klasse is een startpunt voor alle ML.NET bewerkingen en het initialiseren mlContext maakt een nieuwe ML.NET-omgeving die kan worden gedeeld tijdens de levenscyclus van het model. Het is vergelijkbaar met DbContext in Entity Framework.

Het modelgegevensschema definiëren

Uw model verwacht uw invoer- en uitvoergegevens in een specifieke indeling. ML.NET kunt u de indeling van uw gegevens definiëren via klassen. Soms weet u mogelijk al hoe deze indeling eruitziet. In gevallen waarin u de gegevensindeling niet kent, kunt u hulpprogramma's zoals Netron gebruiken om uw ONNX-model te inspecteren.

Het model dat in dit voorbeeld wordt gebruikt, maakt gebruik van gegevens uit de gegevensset NYC TLC Taxi Trip. Hieronder ziet u een voorbeeld van de gegevens:

vendor_id rate_code passenger_count trip_time_in_secs trip_distance payment_type fare_amount
VTS 1 1 1140 3,75 CRD 15.5
VTS 1 1 480 2.72 CRD 10.0
VTS 1 1 1680 7,8 KAS 26.5

Het ONNX-model inspecteren (optioneel)

Gebruik een hulpprogramma zoals Netron om de invoer en uitvoer van uw model te inspecteren.

  1. Open Netron.

  2. Selecteer in de bovenste menubalk de optie Bestand > openen en gebruik de bestandsbrowser om uw model te selecteren.

  3. Het model wordt geopend. De structuur van het model automl-model.onnx ziet er bijvoorbeeld als volgt uit:

    Netron AutoML ONNX Model

  4. Selecteer het laatste knooppunt onderaan de grafiek (variable_out1 in dit geval) om de metagegevens van het model weer te geven. De invoer en uitvoer op de zijbalk tonen de verwachte invoer, uitvoer en gegevenstypen van het model. Gebruik deze informatie om het invoer- en uitvoerschema van uw model te definiëren.

Modelinvoerschema definiëren

Maak een nieuwe klasse OnnxInput met de volgende eigenschappen in het bestand Program.cs .

public class OnnxInput
{
    [ColumnName("vendor_id")]
    public string VendorId { get; set; }

    [ColumnName("rate_code"),OnnxMapType(typeof(Int64),typeof(Single))]
    public Int64 RateCode { get; set; }

    [ColumnName("passenger_count"), OnnxMapType(typeof(Int64), typeof(Single))]
    public Int64 PassengerCount { get; set; }

    [ColumnName("trip_time_in_secs"), OnnxMapType(typeof(Int64), typeof(Single))]
    public Int64 TripTimeInSecs { get; set; }

    [ColumnName("trip_distance")]
    public float TripDistance { get; set; }

    [ColumnName("payment_type")]
    public string PaymentType { get; set; }
}

Elk van de eigenschappen wordt toegewezen aan een kolom in de gegevensset. De eigenschappen worden verder geannoteerd met kenmerken.

ColumnName Met het kenmerk kunt u opgeven hoe ML.NET naar de kolom moet verwijzen wanneer deze op de gegevens wordt uitgevoerd. Hoewel de TripDistance eigenschap bijvoorbeeld de standaard .NET-naamconventies volgt, kent het model alleen een kolom of functie die bekend staat als trip_distance. Om deze naamverschillen aan te pakken, wijst het ColumnName kenmerk de TripDistance eigenschap toe aan een kolom of functie op basis van de naam trip_distance.

Voor numerieke waarden werkt ML.NET alleen op Single waardetypen. Het oorspronkelijke gegevenstype van sommige kolommen is echter gehele getallen. Het OnnxMapType kenmerk wijst typen toe tussen ONNX en ML.NET.

Zie de handleiding ML.NET gegevens laden voor meer informatie over gegevenskenmerken.

Modeluitvoerschema definiëren

Zodra de gegevens zijn verwerkt, produceert deze een uitvoer van een bepaalde indeling. Definieer uw gegevensuitvoerschema. Maak een nieuwe klasse OnnxOutput met de volgende eigenschappen in het bestand Program.cs .

public class OnnxOutput
{
    [ColumnName("variable_out1")]
    public float[] PredictedFare { get; set; }
}

OnnxInputGebruik het ColumnName kenmerk om de variable_out1 uitvoer toe te wijzen aan een meer beschrijvende naamPredictedFare.

Een voorspellingspijplijn definiëren

Een pijplijn in ML.NET is doorgaans een reeks ketentransformaties die op de invoergegevens werken om een uitvoer te produceren. Zie de handleiding ML.NET gegevenstransformatie voor meer informatie over gegevenstransformaties.

  1. Een nieuwe methode maken die in de Program klasse wordt aangeroepen GetPredictionPipeline

    static ITransformer GetPredictionPipeline(MLContext mlContext)
    {
    
    }
    
  2. Definieer de naam van de invoer- en uitvoerkolommen. Voeg de volgende code toe in de GetPredictionPipeline methode.

    var inputColumns = new string []
    {
        "vendor_id", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance", "payment_type"
    };
    
    var outputColumns = new string [] { "variable_out1" };
    
  3. Definieer uw pijplijn. Een IEstimator biedt een blauwdruk van de bewerkingen, invoer- en uitvoerschema's van uw pijplijn.

    var onnxPredictionPipeline =
        mlContext
            .Transforms
            .ApplyOnnxModel(
                outputColumnNames: outputColumns,
                inputColumnNames: inputColumns,
                ONNX_MODEL_PATH);
    

    In dit geval ApplyOnnxModel is dit de enige transformatie in de pijplijn, die de namen van de invoer- en uitvoerkolommen en het pad naar het ONNX-modelbestand accepteert.

  4. Een IEstimator sjabloon definieert alleen de set bewerkingen die moeten worden toegepast op uw gegevens. Wat op uw gegevens werkt, wordt een ITransformer. Gebruik de Fit methode om er een te maken op basis van uw onnxPredictionPipeline.

    var emptyDv = mlContext.Data.LoadFromEnumerable(new OnnxInput[] {});
    
    return onnxPredictionPipeline.Fit(emptyDv);
    

    De Fit methode verwacht een IDataView als invoer voor het uitvoeren van de bewerkingen. Een IDataView is een manier om gegevens in ML.NET weer te geven met behulp van een tabelindeling. Aangezien in dit geval de pijplijn alleen wordt gebruikt voor voorspellingen, kunt u een lege IDataView opgeven om de ITransformer benodigde invoer- en uitvoerschemagegevens te geven. De inrichting ITransformer wordt vervolgens geretourneerd voor verder gebruik in uw toepassing.

    Fooi

    In dit voorbeeld wordt de pijplijn gedefinieerd en gebruikt binnen dezelfde toepassing. Het wordt echter aanbevolen om afzonderlijke toepassingen te gebruiken om uw pijplijn te definiëren en te gebruiken om voorspellingen te doen. In ML.NET uw pijplijnen kunnen worden geserialiseerd en opgeslagen voor verder gebruik in andere .NET-toepassingen voor eindgebruikers. ML.NET ondersteunt verschillende implementatiedoelen, zoals bureaubladtoepassingen, webservices, WebAssembly-toepassingen*, en nog veel meer. Zie de handleiding ML.NET getrainde modellen opslaan en laden voor meer informatie over het opslaan van pijplijnen.

    *WebAssembly wordt alleen ondersteund in .NET Core 5 of hoger

  5. Roep in de Main methode de methode aan GetPredictionPipeline met de vereiste parameters.

    var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
    

Het model gebruiken om voorspellingen te doen

Nu u een pijplijn hebt, is het tijd om deze te gebruiken om voorspellingen te doen. ML.NET biedt een handige API voor het maken van voorspellingen over één gegevensexemplaren met de naam PredictionEngine.

  1. Maak in de Main methode een PredictionEngine met behulp van de CreatePredictionEngine methode.

    var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
    
  2. Maak een invoer voor testgegevens.

    var testInput = new OnnxInput
    {
        VendorId = "CMT",
        RateCode = 1,
        PassengerCount = 1,
        TripTimeInSecs = 1271,
        TripDistance = 3.8f,
        PaymentType = "CRD"
    };
    
  3. Gebruik de predictionEngine opdracht om voorspellingen te doen op basis van de nieuwe testInput gegevens met behulp van de Predict methode.

    var prediction = onnxPredictionEngine.Predict(testInput);
    
  4. Voer het resultaat van uw voorspelling uit naar de console.

    Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
    
  5. Gebruik de .NET Core CLI om uw toepassing uit te voeren.

    dotnet run
    

    Het resultaat moet er ongeveer uitzien als in de volgende uitvoer:

    Predicted Fare: 15.621523
    

Zie het gebruik van een model om voorspellingen te doen voor meer informatie over het maken van voorspellingen in ML.NET.

Volgende stappen