Xamarin.iOS 中的核心 ML 2

Core ML 是 iOS、macOS、tvOS 和 watchOS 上提供的機器學習技術。 它可讓應用程式根據機器學習模型進行預測。

在 iOS 12 中,Core ML 包含批處理 API。 此 API 可讓 Core ML 更有效率,並在模型用來進行一連串預測的案例中提供效能改善。

範例應用程式:MarsHabitatCoreMLTimer

若要示範與 Core ML 的批次預測,請參閱 MarsHabitatCoreMLTimer 範例應用程式。 此範例會使用經過定型的核心 ML 模型,根據各種輸入預測在火星上建造棲息地的成本:太陽能電池板數目、溫室數目和英畝數。

本檔中的代碼段來自此範例。

產生範例資料

ViewController中,範例應用程式的 ViewDidLoad 方法會呼叫 LoadMLModel,這會載入包含的核心 ML 模型:

void LoadMLModel()
{
    var assetPath = NSBundle.MainBundle.GetUrlForResource("CoreMLModel/MarsHabitatPricer", "mlmodelc");
    model = MLModel.Create(assetPath, out NSError mlErr);
}

然後,範例應用程式會建立100,000 MarsHabitatPricerInput 個物件,作為循序核心ML預測的輸入。 每個產生的樣本都有一個隨機值,用於太陽能電池板數目、溫室數目和英畝數:

async void CreateInputs(int num)
{
    // ...
    Random r = new Random();
    await Task.Run(() =>
    {
        for (int i = 0; i < num; i++)
        {
            double solarPanels = r.NextDouble() * MaxSolarPanels;
            double greenHouses = r.NextDouble() * MaxGreenHouses;
            double acres = r.NextDouble() * MaxAcres;
            inputs[i] = new MarsHabitatPricerInput(solarPanels, greenHouses, acres);
        }
    });
    // ...
}

點選任何應用程式的三個按鈕會執行兩個預測序列:一個 for 使用迴圈,另一個使用 iOS 12 中引進的新批次 GetPredictions 方法:

async void RunTest(int num)
{
    // ...
    await FetchNonBatchResults(num);
    // ...
    await FetchBatchResults(num);
    // ...
}

for 迴圈

測試 for 的迴圈版本會逐一查看指定的輸入數目,針對每個輸入呼叫 GetPrediction 並捨棄結果。 方法會花費多少時間進行預測:

async Task FetchNonBatchResults(int num)
{
    Stopwatch stopWatch = Stopwatch.StartNew();
    await Task.Run(() =>
    {
        for (int i = 0; i < num; i++)
        {
            IMLFeatureProvider output = model.GetPrediction(inputs[i], out NSError error);
        }
    });
    stopWatch.Stop();
    nonBatchMilliseconds = stopWatch.ElapsedMilliseconds;
}

GetPredictions (新的批次 API)

測試的批次版本會 MLArrayBatchProvider 從輸入數位建立物件(因為這是方法的必要輸入參數 GetPredictions ),會建立 MLPredictionOptions 物件,防止預測計算限制為CPU,並使用 GetPredictions API來擷取預測,再次捨棄結果:

async Task FetchBatchResults(int num)
{
    var batch = new MLArrayBatchProvider(inputs.Take(num).ToArray());
    var options = new MLPredictionOptions()
    {
        UsesCpuOnly = false
    };

    Stopwatch stopWatch = Stopwatch.StartNew();
    await Task.Run(() =>
    {
        model.GetPredictions(batch, options, out NSError error);
    });
    stopWatch.Stop();
    batchMilliseconds = stopWatch.ElapsedMilliseconds;
}

結果

在模擬器和裝置上, GetPredictions 完成的速度會比迴圈型核心 ML 預測更快。