在 .NET 中使用 AutoML ONNX 模型進行預測
在本文中,您將瞭解如何使用自動化 ML (AutoML) 開放式類神經網路交換 (ONNX) 模型,在具有 ML.NET 的 C# 控制台應用程式中進行預測。
ML.NET 是適用於 .NET 生態系統的開放原始碼、跨平臺機器學習架構,可讓您使用 C# 或 F# 中的程式碼優先方法,或透過模型產生器和 ML.NET CLI 等低程式代碼工具,來定型及取用自定義機器學習模型。 此架構是可延伸的,可讓您利用 TensorFlow 和 ONNX 等其他熱門機器學習架構。
ONNX 是 AI 模型的開放原始碼格式。 ONNX 支援架構間的互通性。 這表示您可以在其中一個熱門的機器學習架構 (例如 PyTorch) 中定型模型、將它轉換成 ONNX 格式,然後在 ML.NET 等不同的架構中取用 ONNX 模型。 若要深入了解,請前往 ONNX 網站。
必要條件
- .NET 6 SDK 或更新版本
- 文字編輯器或 IDE (例如 Visual Studio 或 Visual Studio Code)
- ONNX 模型。 若要了解如何定型 AutoML ONNX 模型,請參閱下列銀行行銷分類 Notebook。
- Netron (選擇性)
建立 C# 主控台應用程式
在此範例中,您會使用 .NET CLI 來建置應用程式,但您可以使用 Visual Studio 執行相同的工作。 深入瞭解 .NET CLI。
開啟終端機並建立新的 C# .NET 主控台應用程式。 在此範例中,應用程式的名稱為
AutoMLONNXConsoleApp
。 將會以該名稱建立目錄,目錄中有應用程式的內容。dotnet new console -o AutoMLONNXConsoleApp
在終端中,瀏覽至 AutoMLONNXConsoleApp 目錄。
cd AutoMLONNXConsoleApp
新增軟體套件
使用 .NET CLI 安裝 Microsoft.ML、Microsoft.ML.OnnxRuntime 和 Microsoft.ML.OnnxTransformer NuGet 套件。
dotnet add package Microsoft.ML dotnet add package Microsoft.ML.OnnxRuntime dotnet add package Microsoft.ML.OnnxTransformer
這些封裝中有在 .NET 應用程式中使用 ONNX 模型所需的相依性。 ML.NET 提供一個使用 ONNX 執行階段進行預測的 API。
開啟Program.cs檔案,並在頂端新增下列
using
指示詞。using System.Linq; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.Onnx;
新增 ONNX 模型的參考
將 ONNX 模型新增至組建輸出目錄,即可供主控台應用程式存取。 如果您還沒有模型,請遵循 此筆記本 來建立範例模型。
在應用程式中新增 ONNX 模型檔案的參考:
將 ONNX 模型複製到應用程式的 AutoMLONNXConsoleApp 根目錄。
開啟 AutoMLONNXConsoleApp.csproj 檔案,在
Project
節點內新增下列內容。<ItemGroup> <None Include="automl-model.onnx"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
在此案例中,ONNX 模型檔的名稱為 automl-model.onnx。
(若要深入瞭解 MSBuild 一般專案,請參閱 MSBuild 指南。)
開啟 Program.cs 檔案,在
Program
類別內新增下列這一行。static string ONNX_MODEL_PATH = "automl-model.onnx";
初始化 MLContext
在 Program
類別的 Main
方法內,建立 MLContext
的新執行個體。
MLContext mlContext = new MLContext();
MLContext
類別是所有 ML.NET 作業的起點,初始化 mlContext
會建立新的 ML.NET 環境,供整個模型生命週期共用。 就概念而言,類似於 Entity Framework 中的 DbContext。
定義模型資料結構描述
模型需要特定格式的輸入和輸出數據。 ML.NET 可讓您透過類別來定義資料的格式。 有時候您可能已經知道該格式的外觀。 如果您不知道數據格式,您可以使用 Netron 之類的工具來檢查 ONNX 模型。
此範例所用的模型使用「NYC TLC 計程車車程」資料集的資料。 下表顯示資料的範例:
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 |
檢查 ONNX 模型 (選擇性)
使用 Netron 之類的工具來檢查模型的輸入和輸出。
開啟 Netron。
在頂端功能表列,選取 [檔案] > [開啟],然後使用檔案瀏覽器選取您的模型。
模型隨即開啟。 例如,automl-model.onnx 模型的結構如下所示:
選取圖表底部的最後一個節點 (此案例中的
variable_out1
),以顯示模型的中繼資料。 提要欄位上的輸入和輸出顯示模型預期的輸入、輸出和資料類型。 使用此資訊來定義模型的輸入和輸出結構描述。
定義模型輸入結構描述
在 Program.cs 檔案內,使用下列屬性建立名為 OnnxInput
的新類別。
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; }
}
每個屬性各對應到資料集的一個資料行。 屬性 (Property) 由屬性 (Attribute) 進一步標註。
ColumnName
屬性可讓您指定 ML.NET 在操作資料時,應該如何參考資料行。 例如,雖然 TripDistance
屬性遵循標準的 .NET 命名慣例,但模型只知道一個稱為 trip_distance
的資料行或功能。 為了解決此命名差異,ColumnName
屬性 (attribute) 將 TripDistance
屬性 (Property) 對應至名為 trip_distance
的資料行或功能。
對於數值,ML.NET 只操作 Single
實值型別。 不過,某些資料行的原始資料類型是整數。 OnnxMapType
屬性會在 ONNX 和 ML.NET 之間對應型別。
若要深入了解資料屬性,請參閱 ML.NET 載入資料指南。
定義模型輸出結構描述
處理資料後會產生特定格式的輸出。 定義資料輸出結構描述。 在 Program.cs 檔案內,使用下列屬性建立名為 OnnxOutput
的新類別。
public class OnnxOutput
{
[ColumnName("variable_out1")]
public float[] PredictedFare { get; set; }
}
類似於 OnnxInput
,請使用 ColumnName
屬性,將 variable_out1
輸出對應至更具描述性的名稱 PredictedFare
。
定義預測管線
ML.NET 中的管線通常是一系列的連鎖轉換,可操作輸入資料來產生輸出。 若要深入了解資料轉換,請參閱 ML.NET 資料轉換指南。
在
Program
類別內建立名為GetPredictionPipeline
的新方法static ITransformer GetPredictionPipeline(MLContext mlContext) { }
定義輸入和輸出資料行的名稱。 將下列程式碼新增至
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" };
定義管線。
IEstimator
提供作業的藍圖,以及管線的輸入和輸出架構。var onnxPredictionPipeline = mlContext .Transforms .ApplyOnnxModel( outputColumnNames: outputColumns, inputColumnNames: inputColumns, ONNX_MODEL_PATH);
在此案例中,
ApplyOnnxModel
是管線中唯一的轉換,接受輸入和輸出資料行的名稱,以及 ONNX 模型檔的路徑。IEstimator
只定義要套用至資料的一組作業。 真正操作資料的是ITransformer
。 使用Fit
方法從onnxPredictionPipeline
建立這一項。var emptyDv = mlContext.Data.LoadFromEnumerable(new OnnxInput[] {}); return onnxPredictionPipeline.Fit(emptyDv);
Fit
方法需要IDataView
作為要操作的輸入。IDataView
是在 ML.NET 中使用表格式來表示資料的一種方法。 因為在此案例中,管線只用於預測,您可以提供空白IDataView
,為ITransformer
提供必要的輸入和輸出結構描述資訊。 然後會傳回填好的ITransformer
,供您的應用程式進一步使用。提示
在此範例中,管線是在相同的應用程式中定義和使用。 不過,建議您使用個別的應用程式來定義和使用管線來進行預測。 在 ML.NET 中,您的管線可以串行化並儲存,以供其他 .NET 終端使用者應用程式進一步使用。 ML.NET 支援各種部署目標,例如桌面應用程式、Web 服務、WebAssembly 應用程式等等。 若要深入了解儲存管線,請參閱 ML.NET 儲存和載入定型的模型指南。
在
Main
方法中,使用必要參數來呼叫GetPredictionPipeline
方法。var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
使用模型來進行預測
您已有管線,現在可以用來進行預測。 ML.NET 提供一個方便的 API,可在名為 PredictionEngine
的單一資料執行個體上進行預測。
在
Main
方法中,使用CreatePredictionEngine
方法建立PredictionEngine
。var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
建立測試資料輸入。
var testInput = new OnnxInput { VendorId = "CMT", RateCode = 1, PassengerCount = 1, TripTimeInSecs = 1271, TripDistance = 3.8f, PaymentType = "CRD" };
使用
predictionEngine
,根據新的testInput
資料,利用Predict
方法進行預測。var prediction = onnxPredictionEngine.Predict(testInput);
將預測結果輸出至主控台。
Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
使用 .NET CLI 來執行您的應用程式。
dotnet run
結果看起來應該類似下列輸出:
Predicted Fare: 15.621523
若要深入瞭解在 ML.NET 中進行預測,請參閱 使用模型進行預測。
下一步
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應