Przewidywanie za pomocą modelu ONNX rozwiązania AutoML na platformie .NET
Z tego artykułu dowiesz się, jak używać modelu automatycznego uczenia maszynowego (AutoML) Open Neural Network Exchange (ONNX) do przewidywania w aplikacji konsolowej języka C# za pomocą ML.NET.
ML.NET to międzyplatformowa platforma uczenia maszynowego typu open source dla ekosystemu platformy .NET, która umożliwia trenowanie i używanie niestandardowych modeli uczenia maszynowego przy użyciu podejścia opartego na kodzie w języku C# lub F#, albo za pomocą narzędzi o niskim kodzie, takich jak Model Builder i interfejs wiersza polecenia ML.NET. Struktura jest rozszerzalna i umożliwia korzystanie z innych popularnych platform uczenia maszynowego, takich jak TensorFlow i ONNX.
ONNX to format typu open source dla modeli sztucznej inteligencji. Platforma ONNX obsługuje współdziałanie między platformami. Oznacza to, że można wytrenować model w jednej z wielu popularnych struktur uczenia maszynowego, takich jak PyTorch, przekonwertować go na format ONNX i korzystać z modelu ONNX w innej strukturze, takiej jak ML.NET. Aby dowiedzieć się więcej, odwiedź witrynę internetową ONNX.
Wymagania wstępne
- Zestaw .NET 6 SDK lub nowszy
- Edytor tekstu lub środowisko IDE (takie jak Visual Studio lub Visual Studio Code)
- Model ONNX. Aby dowiedzieć się, jak wytrenować model ONNX rozwiązania AutoML, zobacz następujący notes klasyfikacji marketingu bankowego.
- Netron (opcjonalnie)
Tworzenie aplikacji konsolowej w języku C#
W tym przykładzie używasz interfejsu wiersza polecenia platformy .NET do kompilowania aplikacji, ale możesz wykonywać te same zadania przy użyciu programu Visual Studio. Dowiedz się więcej o interfejsie wiersza polecenia platformy .NET.
Otwórz terminal i utwórz nową aplikację konsolową platformy .NET w języku C#. W tym przykładzie nazwa aplikacji to
AutoMLONNXConsoleApp
. Katalog jest tworzony przez tę samą nazwę z zawartością aplikacji.dotnet new console -o AutoMLONNXConsoleApp
W terminalu przejdź do katalogu AutoMLONNXConsoleApp .
cd AutoMLONNXConsoleApp
Dodawanie pakietów oprogramowania
Zainstaluj pakiety NuGet Microsoft.ML, Microsoft.ML.OnnxRuntime i Microsoft.ML.OnnxTransformer przy użyciu interfejsu wiersza polecenia platformy .NET.
dotnet add package Microsoft.ML dotnet add package Microsoft.ML.OnnxRuntime dotnet add package Microsoft.ML.OnnxTransformer
Te pakiety zawierają zależności wymagane do używania modelu ONNX w aplikacji .NET. ML.NET udostępnia interfejs API, który używa środowiska uruchomieniowego ONNX do przewidywania.
Otwórz plik Program.cs i dodaj następujące
using
dyrektywy u góry.using System.Linq; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.Onnx;
Dodawanie odwołania do modelu ONNX
Sposobem na uzyskanie dostępu do modelu ONNX przez aplikację konsolową jest dodanie go do katalogu wyjściowego kompilacji. Jeśli nie masz jeszcze modelu, postępuj zgodnie z tym notesem , aby utworzyć przykładowy model.
Dodaj odwołanie do pliku modelu ONNX w aplikacji:
Skopiuj model ONNX do katalogu głównego AutoMLONNXConsoleApp aplikacji.
Otwórz plik AutoMLONNXConsoleApp.csproj i dodaj następującą zawartość w węźle
Project
.<ItemGroup> <None Include="automl-model.onnx"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
W tym przypadku nazwa pliku modelu ONNX to automl-model.onnx.
(Aby dowiedzieć się więcej o typowych elementach programu MSBuild, zobacz Przewodnik programu MSBuild).
Otwórz plik Program.cs i dodaj następujący wiersz wewnątrz
Program
klasy.static string ONNX_MODEL_PATH = "automl-model.onnx";
Inicjowanie obiektu MLContext
Main
Wewnątrz metody Program
klasy utwórz nowe wystąpienie klasy MLContext
.
MLContext mlContext = new MLContext();
Klasa MLContext
jest punktem wyjścia dla wszystkich operacji ML.NET, a inicjowanie mlContext
tworzy nowe środowisko ML.NET, które może być współużytkowane w całym cyklu życia modelu. Jest ona podobna, koncepcyjnie, do DbContext w programie Entity Framework.
Definiowanie schematu danych modelu
Model oczekuje danych wejściowych i wyjściowych w określonym formacie. ML.NET umożliwia zdefiniowanie formatu danych za pomocą klas. Czasami możesz już wiedzieć, jak wygląda ten format. W przypadkach, gdy nie znasz formatu danych, możesz użyć narzędzi, takich jak Netron, aby sprawdzić model ONNX.
Model używany w tym przykładzie używa danych z zestawu danych TLC Taxi Trip w Nowym Jorku. Przykładowe dane przedstawiono w poniższej tabeli:
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 |
Sprawdzanie modelu ONNX (opcjonalnie)
Użyj narzędzia, takiego jak Netron, aby sprawdzić dane wejściowe i wyjściowe modelu.
Otwórz narzędzie Netron.
Na górnym pasku menu wybierz pozycję Plik > Otwórz i użyj przeglądarki plików, aby wybrać model.
Zostanie otwarty model. Na przykład struktura modelu automl-model.onnx wygląda następująco:
Wybierz ostatni węzeł w dolnej części grafu (
variable_out1
w tym przypadku), aby wyświetlić metadane modelu. Dane wejściowe i wyjściowe na pasku bocznym pokazują oczekiwane dane wejściowe, dane wyjściowe i typy danych modelu. Te informacje służą do definiowania schematu danych wejściowych i wyjściowych modelu.
Definiowanie schematu wejściowego modelu
Utwórz nową klasę o nazwie OnnxInput
z następującymi właściwościami w pliku 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; }
}
Każda z właściwości jest mapowania na kolumnę w zestawie danych. Właściwości są dodatkowo oznaczone atrybutami.
Atrybut ColumnName
umożliwia określenie, jak ML.NET odwoływać się do kolumny podczas działania na danych. Na przykład, chociaż TripDistance
właściwość jest zgodna ze standardowymi konwencjami nazewnictwa platformy .NET, model zna tylko kolumnę lub funkcję znaną jako trip_distance
. Aby rozwiązać tę rozbieżność nazewnictwa, ColumnName
atrybut mapuje TripDistance
właściwość na kolumnę lub funkcję według nazwy trip_distance
.
W przypadku wartości liczbowych ML.NET działa tylko na Single
typach wartości. Jednak oryginalny typ danych niektórych kolumn to liczby całkowite. Atrybut OnnxMapType
mapuje typy między ONNX i ML.NET.
Aby dowiedzieć się więcej na temat atrybutów danych, zobacz przewodnik ML.NET ładowania danych.
Definiowanie schematu wyjściowego modelu
Po przetworzeniu danych generuje dane wyjściowe określonego formatu. Zdefiniuj schemat danych wyjściowych. Utwórz nową klasę o nazwie OnnxOutput
z następującymi właściwościami w pliku Program.cs .
public class OnnxOutput
{
[ColumnName("variable_out1")]
public float[] PredictedFare { get; set; }
}
Podobnie jak OnnxInput
, użyj atrybutu ColumnName
, aby zamapować variable_out1
dane wyjściowe na bardziej opisową nazwę PredictedFare
.
Definiowanie potoku przewidywania
Potok w ML.NET jest zazwyczaj serią przekształceń łańcuchowych, które działają na danych wejściowych w celu wygenerowania danych wyjściowych. Aby dowiedzieć się więcej na temat przekształceń danych, zobacz przewodnik ML.NET przekształcania danych.
Tworzenie nowej metody o nazwie
GetPredictionPipeline
wewnątrzProgram
klasystatic ITransformer GetPredictionPipeline(MLContext mlContext) { }
Zdefiniuj nazwę kolumn wejściowych i wyjściowych. Dodaj następujący kod wewnątrz
GetPredictionPipeline
metody .var inputColumns = new string [] { "vendor_id", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance", "payment_type" }; var outputColumns = new string [] { "variable_out1" };
Zdefiniuj potok. Element
IEstimator
zawiera strategię operacji oraz schematy danych wejściowych i wyjściowych potoku.var onnxPredictionPipeline = mlContext .Transforms .ApplyOnnxModel( outputColumnNames: outputColumns, inputColumnNames: inputColumns, ONNX_MODEL_PATH);
W takim przypadku
ApplyOnnxModel
jest to jedyna transformacja w potoku, która przyjmuje nazwy kolumn wejściowych i wyjściowych, a także ścieżkę do pliku modelu ONNX.Element
IEstimator
definiuje tylko zestaw operacji, które mają być stosowane do danych. To, co działa na danych, jest nazywaneITransformer
.Fit
Użyj metody , aby utworzyć element na podstawie elementuonnxPredictionPipeline
.var emptyDv = mlContext.Data.LoadFromEnumerable(new OnnxInput[] {}); return onnxPredictionPipeline.Fit(emptyDv);
Metoda
Fit
oczekujeIDataView
jako danych wejściowych do wykonania operacji. ElementIDataView
to sposób reprezentowania danych w ML.NET przy użyciu formatu tabelarycznego. Ponieważ w tym przypadku potok jest używany tylko do przewidywania, możesz podać pusteIDataView
, aby nadaćITransformer
niezbędne informacje o schemacie wejściowym i wyjściowym. Następnie dopasowanyITransformer
element zostanie zwrócony do dalszego użycia w aplikacji.Napiwek
W tym przykładzie potok jest definiowany i używany w tej samej aplikacji. Zaleca się jednak używanie oddzielnych aplikacji do definiowania potoku i używania go do przewidywania. W ML.NET potoki można serializować i zapisywać do dalszego użycia w innych aplikacjach użytkownika końcowego platformy .NET. ML.NET obsługuje różne cele wdrażania, takie jak aplikacje klasyczne, usługi internetowe, aplikacje zestawu WebAssembly i wiele innych. Aby dowiedzieć się więcej na temat zapisywania potoków, zobacz przewodnik ML.NET zapisywania i ładowania wytrenowanych modeli.
Wewnątrz metody wywołaj
Main
metodęGetPredictionPipeline
z wymaganymi parametrami.var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
Korzystanie z modelu do przewidywania
Teraz, gdy masz potok, nadszedł czas, aby użyć go do przewidywania. ML.NET udostępnia wygodny interfejs API do przewidywania w pojedynczym wystąpieniu danych o nazwie PredictionEngine
.
Main
Wewnątrz metody utwórz elementPredictionEngine
przy użyciuCreatePredictionEngine
metody .var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
Utwórz dane wejściowe danych testowych.
var testInput = new OnnxInput { VendorId = "CMT", RateCode = 1, PassengerCount = 1, TripTimeInSecs = 1271, TripDistance = 3.8f, PaymentType = "CRD" };
Użyj elementu ,
predictionEngine
aby tworzyć przewidywania na podstawie nowychtestInput
danych przy użyciuPredict
metody .var prediction = onnxPredictionEngine.Predict(testInput);
Wygeneruj wynik przewidywania w konsoli programu .
Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
Użyj interfejsu wiersza polecenia platformy .NET, aby uruchomić aplikację.
dotnet run
Wynik powinien wyglądać podobnie do następujących danych wyjściowych:
Predicted Fare: 15.621523
Aby dowiedzieć się więcej na temat tworzenia przewidywań w ML.NET, zobacz Używanie modelu do przewidywania.