使用ML.NET進行自定義機器學習


ML.NET是Microsoft最近發布的用於機器學習的開源,跨平台,代碼優先的框架。盡管對我們來說是一個新的框架,但該框架的根源是Microsoft Research,並且在過去十年中已被許多內部團隊使用,包括那些您幾乎肯定聽說過的產品的開發人員-Microsoft Windows,Office和Bing,僅舉幾例。

ML.NET使.NET開發人員可以輕松地將機器學習集成到其應用程序中,無論是控制台,桌面還是Web。它涵蓋了機器學習活動的整個生命周期,從模型的訓練和評估到使用和部署。支持許多典型的有監督和無監督機器學習任務,包括分類回歸推薦聚類該框架還與TensorFlow集成,使.NET開發人員能夠從熟悉的環境調用深度學習模型(適用於諸如對象檢測或語音分析之類的任務)。

為什么選擇ML.NET?

如今,在為我們的應用程序添加機器學習或AI功能的選項方面,我們總是無所適從。借助NuGet包和僅幾行代碼,我們就可以利用Azure認知服務的強大功能以高度的准確性和性能執行情感分析,對象檢測和OCR等復雜任務。微軟確實做了令人難以置信的工作,使各種經驗的開發人員都可以使用這些工具。

ML.NET如何適合?您可以使用ML.NET來執行許多與Azure一樣的機器學習任務。但是,作為一個高度可配置的基於代碼的框架,它肯定會花費多行代碼。在差異化方面,您可能會考慮ML.NET的一些關鍵原因是:

  • 訓練特定領域的模型
    許多認知服務模型都在廣泛的數據集上進行了訓練,以便為各種用例提供​​良好的體驗。這非常適合接送和使用以及許多實際需求。但是,如果您正在處理特殊問題,那么通用模型可能不太適合。例如,認知服務將毫不費力地告訴您圖像是否包含帽子或動物。如果您想檢測和區分不同種類的帽子(例如,您自己的帽子收藏)並且不關心識別動物或其他物體,則可以從訓練自己的領域特定模型中受益,ML.NET允許你輕松做。

  • 將數據保存在網絡中或用戶的機器上
    許多Cognitive Services確實允許您通過提供自定義示例來訓練自定義模型或擴展內置模型。在某些情況下,還可以導出和下載模型,以實現離線使用。但是,出於法規或隱私的原因,您可能不希望或被允許上傳訓練數據或將預測輸入發送到雲提供商。ML.NET可以以離線方式端到端地用於訓練和預測。如果您需要訓練和/或預測數據來保持內部,則ML.NET是一個不錯的選擇。

  • 動態生成ML模型
    作為代碼優先的框架,ML.NET使得基於編譯時未知的信息來動態生成機器學習模型非常容易。如果您的應用程序支持動態內容(例如,用戶定義的模式),並且您希望集成ML功能,則可以選擇ML.NET。

  • 修改或擴展框架
    作為一個開放源代碼項目,ML.NET的完整源代碼可在GitHub上獲得,從而使您可以根據需要快速研究實現細節,修復錯誤甚至添加功能。

  • 避免基於消耗的定價
    ML.NET可以免費使用,無論您執行多少操作。當然,運行自己的系統也要付費!

與Azure認知服務相比,訪問這些差異化功能的最大障礙可能是ML.NET對機器學習知識的更高要求。使用ML.NET要求您更多地考慮諸如數據預處理,數據管道,算法選擇,模型驗證和性能指標之類的事情。雖然理解這些概念將為您提供扎實的機器學習基礎,但立即解決所有這些問題可能會有些令人生畏。幸運的是,ML.NET團隊已經完成了一些工作,可以幫助新手入門。

縮小差距— AutoML和Model Builder

如果您想使用ML.NET,但是構建管道,選擇訓練師和評估模型的想法讓您三思而后行,那么您可以選擇AutoML形式的選擇,它ML.NET的配套庫。AutoML通過自動化生命周期的各個部分並嘗試為您的數據生成最佳的機器學習模型,降低了新機器學習開發人員的進入門檻。具體來說,它會自動:

  • 從SQL或基於文本的源中加載訓練數據

  • 執行輸入數據的基本預處理,包括檢測分類字段和刪除對預測無用的字段

  • 探索潛在的算法和參數,迭代訓練模型並根據輸入數據評估每種算法和有效性

  • (通過CLI或Model Builder使用時)生成代碼以加載經過訓練的最佳模型,准備提供新的預測

可以從代碼(Install-Package Microsoft.ML.AutoML),命令行界面(dotnet tool install -g mlnet)或通過GUI工具(以Visual Studio擴展,Model Builder的形式調用AutoML 

在本文的其余部分,我們將通過一個示例使用Model Builder自動訓練機器學習模型並生成使用該模型的代碼。

演練—使用Model Builder自動訓練出租車票價預測模型

在本演練中,我們將基於時間,距離,乘客人數和付款方式等輸入信息,構建一個預測紐約出租車票價的模型。我們將使用ML.NET示例存儲庫中的數據作為輸入。

先決條件:

如果您沒有Visual Studio 2017或2019,請在嘗試安裝Model Builder擴展之前安裝其中之一。

步驟1:在Visual Studio中創建一個新項目

ML.NET可在.NET Core所運行的任何x86或x64環境中運行,因此我們可以從許多內置模板開始。在這種情況下,我們將創建一個新的.NET Core控制台應用程序。

 

 

 創建項目后,請等到屏幕上看到熟悉的空控制台應用程序項目。

步驟2:將“機器學習”添加到您的項目中

安裝擴展后,我們可以通過在解決方案資源管理器中右鍵單擊我們的項目,然后選擇添加->機器學習來調用模型生成器。完成此操作后,您會看到ML.NET Model Builder首屏引導界面。

 

步驟3:為您的數據集配置Model Builder

選擇方案

我們與Model Builder的交互首先是從一些預定義的場景中進行選擇。本質上,這些是針對特定機器學習任務量身定制的模板。在我們的案例中,我們希望預測出租車價格,因此“價格預測”是一個不錯的選擇。

 

加載訓練數據

下一個任務是指定我們要用於訓練的數據。價格預測是監督學習任務的一個示例,其中訓練了機器學習模型,通過顯示歷史數據的示例來進行預測。示例包括模型輸入(在我們的示例中為時間,距離和乘客數量)以及輸出值(行程的實際票價)。稍后,當我們要預測票價時,我們的模型將采用新行程的詳細信息,並將其與從訓練數據中得出的關系一起使用,以預測票價。

為了評估機器學習模型的質量,我們通常從訓練中排除部分歷史數據。這樣可以確保我們擁有一些已知的良好輸入/輸出組合(我們的模型尚未看到),可以將它們與模型的輸出進行比較。為此,AutoML會自動撤消部分數據,因此我們可以為其提供完整的數據集。如果完成了可選的先決條件,則應在“選擇文件”對話框中選擇級聯的數據集。否則,您可以粘貼訓練數據URL使用級聯數據集的好處是您將為AutoML提供更大的訓練數據。

加載文件后,Model Builder將自動檢測列並提供數據預覽。我們需要告訴Model Builder我們要預測哪個領域;在我們的例子中是“ fare_amount”字段。

 

步驟4:使用模型生成器生成最佳模型

訓練優化模型

Model Builder使用AutoML迭代探索選項並確定給定數據集的最佳預測算法和參數。迭代時間的上限取決於我們,主要應受訓練數據集的大小影響。

ML.NET團隊對各種數據集大小的迭代持續時間有一些指導對於我們的數據集(介於2.5mb和5mb之間,取決於您是否將測試數據和訓練數據連接在一起),僅十秒鍾就足夠了。單擊“訓練”后,Model Builder將開始迭代模型並顯示有關其進度的一些詳細信息。Model Builder評估它訓練的每個模型,並將模型的RSquared得分用作比較它們的機制。

 

審查模型效果

執行優化后,Model Builder將概述該過程,包括它能夠在迭代時間內生成的最佳五種配置的評估指標。

 

盡管“Model Builder”會自動選擇效果最佳的模型,但是值得花一點時間查看最終指標。如果所選模型的指標不佳,則不太可能在新輸入上表現良好。在這種情況下,您可能需要迭代模型訓練過程。選項可能包括:

  • 增加AutoML的探索時間(允許它查找更好的算法或參數)
  • 訓練數據的數量增加(提供更多示例,更好地代表您的域的可變性)
  • 預處理訓練數據(公開可以提高可預測性的新功能,或刪除可能無法提高的功能)

在上面的例子中,使用LightGbmRegression訓練器生成了最佳模型,其RSquared得分為0.94,這應該表現良好。

步驟5:使用模型

評估后,Model Builder將自動將兩個新項目添加到您的解決方案中。第一個是包含模型和輸入類的庫,現有項目可以引用該庫。第二個是帶有代碼的示例控制台應用程序,該代碼演示了如何加載和使用模型。

 

生成了這兩個項目后,我們就可以看到實際的模型了。該示例應用程序使用來自訓練數據集的硬編碼單個輸入來演示模型的用法。為了使其更具交互性,您可以使用以下內容替換Program.cs的內容,從而使您可以交互地輸入行程詳細信息並獲得預計的票價:

using System;
using System.IO;
using System.Linq;
using Microsoft.ML;
using PredictTaxiFareML.Model.DataModels;
using static System.Console;
using static System.Environment;

namespace PredictTaxiFareML.ConsoleApp
{
    class Program
    {
        private const string Quit = "quit";
        private const string ModelPath = @"MLModel.zip";
        
        static void Main(string[] args)
        {
            var context = new MLContext().Model;
            var model = context.Load(GetPath(ModelPath), out _);
            var engine = context.CreatePredictionEngine<ModelInput, ModelOutput>(model);

            WriteLine("== AutoML Interactive Taxi Fare Predictor == ");
            while (GetInput(out var input))
                WriteLine($"{NewLine}Predicted fare: " +
                 $"{engine.Predict(input).Score:C}{NewLine}");
        }

        private static bool GetInput(out ModelInput input)
        {
            WriteLine($"{NewLine}Enter trip details:{NewLine}");

            input = new ModelInput
            {
                Passenger_count = ReadF("Passenger count", 1),
                Trip_time_in_secs = ReadF("Trip time (mins)", 1) * 60,
                Trip_distance = ReadF("Distance (mi)", 0),
                Vendor_id = ReadCat("Vendor", "VTS", "CMD"),
                Rate_code = ReadF("Rate code (0 - 6)", 0, 6),
                Payment_type = ReadCat("Payment type", "CRD", "CSH"),
            };

            return true;
        }

        private static float ReadF(string title, 
            float min = float.MinValue, float max = float.MaxValue)
        {
            while (true)
            {
                try { return Clamp(float.Parse(Prompt(title)), min, max); } 
                catch (Exception ex) { WriteLine(ex.Message); }
            }
        }

        private static string ReadCat(string title, params string[] values)
        {
            title = $"{title} [{String.Join(", ", values)}]";

            var ret = "";
            while (!values.Contains(ret))
                ret = Prompt(title);

            return ret;
        }

        private static string Prompt(string title)
        {
            Write($"  - {title}: ");
            return ReadLine().Trim().ToUpper();
        }

        private static float Clamp(float input, float min, float max)
        {
            var ret = Math.Max(Math.Min(input, max), min);

            if (Math.Abs(ret - input) > 0.1)
                WriteLine($"Clamping to {ret}");

            return ret;
        }

        private static string GetPath(string relativePath)
        {
            var root = new FileInfo(typeof(Program).Assembly.Location);
            var asmPath = root.Directory.FullName;

            return Path.Combine(asmPath, relativePath);
        }
    }
}

運行中的代碼如下所示:

 

就是這樣!我們已經成功地使用了Model Builder來自動生成優化的模型,以便根據出租車費用數據集進行預測。AutoML自動為我們處理了一些棘手的步驟,使我們無需成為機器學習專家就可以從ML.NET的某些獨特功能中受益。希望這個例子有助於為您提供使用ML.NET的啟發,您自己可以嘗試在某些數據上創建自定義模型。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM