Eseguire stime con un modello ONNX AutoML in .NET
Questo articolo illustra come usare un modello Open Neural Network Exchange (ONNX) di Machine Learning automatizzato (AutoML) per eseguire stime in un'applicazione console C# .NET Core con ML.NET.
ML.NET è un framework open source multipiattaforma e multipiattaforma per l'ecosistema .NET che consente di eseguire il training e l'uso di modelli di Machine Learning personalizzati usando un approccio code-first in C# o F# e strumenti a basso codice come Model Builder e l'interfaccia della riga di comando di ML.NET. Il framework è anche estendibile e consente di sfruttare altri framework di Machine Learning più diffusi, ad esempio TensorFlow e ONNX.
ONNX è un formato open source per i modelli di intelligenza artificiale. ONNX supporta l'interoperabilità tra framework. Ciò significa che è possibile eseguire il training di un modello in uno dei numerosi framework di Machine Learning più diffusi, ad esempio PyTorch, convertirlo in formato ONNX e usare il modello ONNX in un framework diverso, ad esempio ML.NET. Per altre informazioni, vedere il sito Web ONNX.
Prerequisiti
- .NET Core SDK 3.1 o versione successiva
- Editor di testo o IDE (ad esempio Visual Studio o Visual Studio Code)
- Modello ONNX. Per informazioni su come eseguire il training di un modello ONNX autoML, vedere il notebook di classificazione di marketing bancario seguente.
- Netron (facoltativo)
Creare un'applicazione console C#
In questo esempio si usa l'interfaccia della riga di comando di .NET Core per compilare l'applicazione, ma è possibile eseguire le stesse attività usando Visual Studio. Altre informazioni sull'interfaccia della riga di comando di .NET Core.
Aprire un terminale e creare una nuova applicazione console C# .NET Core. In questo esempio il nome dell'applicazione è
AutoMLONNXConsoleApp
. Una directory viene creata con lo stesso nome con il contenuto dell'applicazione.dotnet new console -o AutoMLONNXConsoleApp
Nel terminale passare alla directory AutoMLONNXConsoleApp .
cd AutoMLONNXConsoleApp
Aggiungere pacchetti software
Installare i pacchetti NuGet Microsoft.ML, Microsoft.ML.OnnxRuntime e Microsoft.ML.OnnxTransformer usando l'interfaccia della riga di comando di .NET Core.
dotnet add package Microsoft.ML dotnet add package Microsoft.ML.OnnxRuntime dotnet add package Microsoft.ML.OnnxTransformer
Questi pacchetti contengono le dipendenze necessarie per usare un modello ONNX in un'applicazione .NET. ML.NET fornisce un'API che usa il runtime ONNX per le stime.
Aprire il file Program.cs e aggiungere le istruzioni seguenti
using
nella parte superiore per fare riferimento ai pacchetti appropriati.using System.Linq; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.Onnx;
Aggiungere un riferimento al modello ONNX
Un modo per consentire all'applicazione console di accedere al modello ONNX consiste nell'aggiungerlo alla directory di output di compilazione. Per altre informazioni sugli elementi comuni di MSBuild, vedere la guida a MSBuild. Se non si ha già un modello, seguire questo notebook per creare un modello di esempio.
Aggiungere un riferimento al file del modello ONNX nell'applicazione
Copiare il modello ONNX nella directory radice AutoMLONNXConsoleApp dell'applicazione.
Aprire il file AutoMLONNXConsoleApp.csproj e aggiungere il contenuto seguente all'interno del
Project
nodo.<ItemGroup> <None Include="automl-model.onnx"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
In questo caso, il nome del file del modello ONNX è automl-model.onnx.
Aprire il file Program.cs e aggiungere la riga seguente all'interno della
Program
classe .static string ONNX_MODEL_PATH = "automl-model.onnx";
Inizializzare MLContext
All'interno del Main
metodo della Program
classe creare una nuova istanza di MLContext
.
MLContext mlContext = new MLContext();
La MLContext
classe è un punto di partenza per tutte le operazioni ML.NET e l'inizializzazione mlContext
crea un nuovo ambiente ML.NET che può essere condiviso nel ciclo di vita del modello. È simile, concettualmente, a DbContext in Entity Framework.
Definire lo schema dei dati del modello
Il modello prevede un formato specifico per i dati di input e output. ML.NET consente di definire il formato dei dati tramite classi. A volte potresti già sapere che aspetto ha questo formato. Nei casi in cui non si conosce il formato dei dati, è possibile usare strumenti come Netron per controllare il modello ONNX.
Il modello usato in questo esempio usa i dati del set di dati NYC TLC Taxi Trip. Di seguito è riportato un esempio di dati:
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 | CSH | 26.5 |
Esaminare il modello ONNX (facoltativo)
Usare uno strumento come Netron per esaminare gli input e gli output del modello.
Aprire Netron.
Nella barra dei menu in alto selezionare File > Apri e usare il browser file per selezionare il modello.
Verrà aperto il modello. Ad esempio, la struttura del modello automl-model.onnx è simile alla seguente:
Selezionare l'ultimo nodo nella parte inferiore del grafico (
variable_out1
in questo caso) per visualizzare i metadati del modello. Gli input e gli output sulla barra laterale mostrano gli input, gli output e i tipi di dati previsti del modello. Usare queste informazioni per definire lo schema di input e output del modello.
Definire lo schema di input del modello
Creare una nuova classe denominata OnnxInput
con le proprietà seguenti all'interno del file 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; }
}
Ognuna delle proprietà esegue il mapping a una colonna nel set di dati. Le proprietà vengono ulteriormente annotate con attributi.
L'attributo ColumnName
consente di specificare come ML.NET deve fare riferimento alla colonna quando si opera sui dati. Ad esempio, anche se la TripDistance
proprietà segue convenzioni di denominazione .NET standard, il modello conosce solo una colonna o una funzionalità nota come trip_distance
. Per risolvere questa discrepanza di denominazione, l'attributo esegue il ColumnName
mapping della TripDistance
proprietà a una colonna o a una funzionalità in base al nome trip_distance
.
Per i valori numerici, ML.NET opera solo sui Single
tipi valore. Tuttavia, il tipo di dati originale di alcune colonne è integer. L'attributo esegue il OnnxMapType
mapping dei tipi tra ONNX e ML.NET.
Per altre informazioni sugli attributi dei dati, vedere la guida al caricamento dei dati ML.NET.
Definire lo schema di output del modello
Una volta elaborati i dati, genera un output di un determinato formato. Definire lo schema di output dei dati. Creare una nuova classe denominata OnnxOutput
con le proprietà seguenti all'interno del file Program.cs .
public class OnnxOutput
{
[ColumnName("variable_out1")]
public float[] PredictedFare { get; set; }
}
Analogamente a OnnxInput
, usare l'attributo per eseguire il ColumnName
mapping dell'output variable_out1
a un nome PredictedFare
più descrittivo.
Definire una pipeline di stima
Una pipeline in ML.NET è in genere una serie di trasformazioni concatenati che operano sui dati di input per produrre un output. Per altre informazioni sulle trasformazioni dei dati, vedere la guida alla trasformazione dei dati ML.NET.
Creare un nuovo metodo denominato
GetPredictionPipeline
all'interno dellaProgram
classestatic ITransformer GetPredictionPipeline(MLContext mlContext) { }
Definire il nome delle colonne di input e output. Aggiungere il codice seguente all'interno del metodo
GetPredictionPipeline
.var inputColumns = new string [] { "vendor_id", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance", "payment_type" }; var outputColumns = new string [] { "variable_out1" };
Definire la pipeline. Un oggetto
IEstimator
fornisce un progetto di operazioni, input e schemi di output della pipeline.var onnxPredictionPipeline = mlContext .Transforms .ApplyOnnxModel( outputColumnNames: outputColumns, inputColumnNames: inputColumns, ONNX_MODEL_PATH);
In questo caso,
ApplyOnnxModel
è l'unica trasformazione nella pipeline, che accetta i nomi delle colonne di input e output, nonché il percorso del file di modello ONNX.Definisce
IEstimator
solo il set di operazioni da applicare ai dati. Ciò che opera sui dati è noto comeITransformer
. Usare ilFit
metodo per crearne uno dall'oggettoonnxPredictionPipeline
.var emptyDv = mlContext.Data.LoadFromEnumerable(new OnnxInput[] {}); return onnxPredictionPipeline.Fit(emptyDv);
Il
Fit
metodo prevede che un oggettoIDataView
come input esegua le operazioni. UnIDataView
è un modo per rappresentare i dati in ML.NET usando un formato tabulare. Poiché in questo caso la pipeline viene usata solo per le stime, è possibile fornire un valore vuotoIDataView
per fornire leITransformer
informazioni necessarie sullo schema di input e output. L'oggetto montato viene quindi restituitoITransformer
per un ulteriore uso nell'applicazione.Suggerimento
In questo esempio la pipeline viene definita e usata all'interno della stessa applicazione. È tuttavia consigliabile usare applicazioni separate per definire e usare la pipeline per eseguire stime. In ML.NET le pipeline possono essere serializzate e salvate per un uso aggiuntivo in altre applicazioni degli utenti finali .NET. ML.NET supporta diverse destinazioni di distribuzione, ad esempio applicazioni desktop, servizi Web, applicazioni WebAssembly* e molti altri ancora. Per altre informazioni sul salvataggio delle pipeline, vedere la guida ML.NET salvare e caricare i modelli sottoposti a training.
*WebAssembly è supportato solo in .NET Core 5 o versione successiva
All'interno del
Main
metodo chiamare ilGetPredictionPipeline
metodo con i parametri obbligatori.var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
Usare il modello per effettuare previsioni
Ora che si dispone di una pipeline, è possibile usarla per eseguire stime. ML.NET fornisce un'API utile per eseguire stime su una singola istanza di dati denominata PredictionEngine
.
All'interno del
Main
metodo creare unPredictionEngine
oggetto usando ilCreatePredictionEngine
metodo .var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
Creare un input di dati di test.
var testInput = new OnnxInput { VendorId = "CMT", RateCode = 1, PassengerCount = 1, TripTimeInSecs = 1271, TripDistance = 3.8f, PaymentType = "CRD" };
predictionEngine
Usare per eseguire stime in base ai nuovitestInput
dati usando ilPredict
metodo .var prediction = onnxPredictionEngine.Predict(testInput);
Restituire il risultato della stima nella console.
Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
Usare l'interfaccia della riga di comando di .NET Core per eseguire l'applicazione.
dotnet run
Il risultato dovrebbe essere simile all'output seguente:
Predicted Fare: 15.621523
Per altre informazioni sull'esecuzione di stime in ML.NET, vedere la guida sull'uso di un modello per eseguire stime.