共用方式為


在 .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 網站

必要條件

建立 C# 主控台應用程式

在此範例中,您會使用 .NET CLI 來建置應用程式,但您可以使用 Visual Studio 執行相同的工作。 深入瞭解 .NET CLI

  1. 開啟終端機並建立新的 C# .NET 主控台應用程式。 在此範例中,應用程式的名稱為 AutoMLONNXConsoleApp。 將會以該名稱建立目錄,目錄中有應用程式的內容。

    dotnet new console -o AutoMLONNXConsoleApp
    
  2. 在終端中,瀏覽至 AutoMLONNXConsoleApp 目錄。

    cd AutoMLONNXConsoleApp
    

新增軟體套件

  1. 使用 .NET CLI 安裝 Microsoft.MLMicrosoft.ML.OnnxRuntimeMicrosoft.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。

  2. 開啟Program.cs檔案,並在頂端新增下列using指示詞。

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

新增 ONNX 模型的參考

將 ONNX 模型新增至組建輸出目錄,即可供主控台應用程式存取。 如果您還沒有模型,請遵循 此筆記本 來建立範例模型。

在應用程式中新增 ONNX 模型檔案的參考:

  1. 將 ONNX 模型複製到應用程式的 AutoMLONNXConsoleApp 根目錄。

  2. 開啟 AutoMLONNXConsoleApp.csproj 檔案,在 Project 節點內新增下列內容。

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

    在此案例中,ONNX 模型檔的名稱為 automl-model.onnx

    (若要深入瞭解 MSBuild 一般專案,請參閱 MSBuild 指南。)

  3. 開啟 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 之類的工具來檢查模型的輸入和輸出。

  1. 開啟 Netron。

  2. 在頂端功能表列,選取 [檔案] > [開啟],然後使用檔案瀏覽器選取您的模型。

  3. 模型隨即開啟。 例如,automl-model.onnx 模型的結構如下所示:

    Netron AutoML ONNX 模型

  4. 選取圖表底部的最後一個節點 (此案例中的 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 資料轉換指南

  1. Program 類別內建立名為 GetPredictionPipeline 的新方法

    static ITransformer GetPredictionPipeline(MLContext mlContext)
    {
    
    }
    
  2. 定義輸入和輸出資料行的名稱。 將下列程式碼新增至 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" };
    
  3. 定義管線。 IEstimator提供作業的藍圖,以及管線的輸入和輸出架構。

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

    在此案例中,ApplyOnnxModel 是管線中唯一的轉換,接受輸入和輸出資料行的名稱,以及 ONNX 模型檔的路徑。

  4. 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 儲存和載入定型的模型指南

  5. Main 方法中,使用必要參數來呼叫 GetPredictionPipeline 方法。

    var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
    

使用模型來進行預測

您已有管線,現在可以用來進行預測。 ML.NET 提供一個方便的 API,可在名為 PredictionEngine 的單一資料執行個體上進行預測。

  1. Main 方法中,使用 CreatePredictionEngine 方法建立 PredictionEngine

    var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
    
  2. 建立測試資料輸入。

    var testInput = new OnnxInput
    {
        VendorId = "CMT",
        RateCode = 1,
        PassengerCount = 1,
        TripTimeInSecs = 1271,
        TripDistance = 3.8f,
        PaymentType = "CRD"
    };
    
  3. 使用 predictionEngine,根據新的 testInput 資料,利用 Predict 方法進行預測。

    var prediction = onnxPredictionEngine.Predict(testInput);
    
  4. 將預測結果輸出至主控台。

    Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
    
  5. 使用 .NET CLI 來執行您的應用程式。

    dotnet run
    

    結果看起來應該類似下列輸出:

    Predicted Fare: 15.621523
    

若要深入瞭解在 ML.NET 中進行預測,請參閱 使用模型進行預測

下一步