用C#也能做機器學習?

2023-12-21 15:00:54

前言✨

說到機器學習,大家可能都不陌生,但是用C#來做機器學習,可能很多人還第一次聽說。其實在C#中基於ML.NET也是可以做機器學習的,這種方式比較適合.NET程式設計師在專案中整合機器學習模型,不太適合專門學習機器學習,本文我將基於ML.NET Model Builder(低程式碼、入門簡單)構建一個貓狗識別範例,並在.NET應用中整合它。

效果✨

效果如下所示:

貓狗識別效果

目錄✨

  1. ML.NET簡介

  2. ML.NET Model Builder簡介

  3. 資料集準備

  4. 新增機器學習模型

  5. 選擇方案

  6. 選擇訓練環境

  7. 新增資料

  8. 訓練

  9. 評估模型

  10. 在.NET應用中使用模型

  11. 總結

ML.NET簡介✨

ML.NET 是由 Microsoft 為 .NET 開發者平臺建立的免費、開源、跨平臺的機器學習框架。

ML.NET,無需離開 .NET 生態系統,便可以使用 C# 或 F# 建立自定義 ML 模型。

ML.NET 提供 Model Builder(簡單的 UI 工具)和 ML.NET CLI,使生成自定義 ML 模型變得非常容易。

ML.NET 被設計為一個可延伸平臺,因此可以使用其他流行的 ML 框架(TensorFlow、ONNX、Infer.NET 等)並存取更多機器學習場景,如影象分類、物體檢測等。

image-20231220210642734

ML.NET Model Builder簡介✨

Model Builder 提供易於理解的可視介面,用於在 Visual Studio 內生成、訓練和部署自定義機器學習模型。無需先前的機器學習專業知識。

Model Builder 支援 AutoML,它會自動探索不同的機器學習演演算法和設定,以幫助找到最適合方案的演演算法和設定。

Model Builder 的當前預覽版可用於 csv 檔案、tsv 檔案以及 SQL Server 資料庫。

Model Builder 可生成經過訓練的模型,以及載入模型和開始進行預測所需的程式碼。

Model Builder 為你提供計算機上所需的一切功能。不需要連線到雲資源或其他服務即可生成和使用模型。

Model Builder 是一個 Visual Studio 擴充套件,便於你在已知的開發環境中繼續工作。

Model Builder 可用於在 Visual Studio 中開發的任何 .NET 應用。

image-20231221103403282

資料集準備✨

本文使用的資料集,來源於kaggle,共包含25000張JPEG資料集照片,其中貓和狗的照片各佔12500張。

下載地址:https://www.kaggle.com/c/dogs-vs-cats/data

將壓縮包解壓,有test1.zip與train.zip,再分別解壓得到test1與train資料夾:

image-20231220221657444

在train資料夾中各有12500張貓的圖片和狗的圖片,本範例不用那麼多的圖片,分別選取2500張的貓和狗的圖片。

新增機器學習模型✨

右鍵解決方案,新建一個類庫,命名為IdentifyDogsAndCats:

image-20231220222726459

右鍵該類庫,新增機器學習模型:

image-20231220222911054

命名為IdentifyDogsAndCats.mbconfig,然後會跳出如下介面:

image-20231220223109571

選擇方案✨

本文中的貓狗識別,屬於計算機視覺中的影象分類,因此選擇該方案:

image-20231220223329503

選擇訓練環境✨

本文只是範例,選擇本地(CPU):

image-20231220223412642

新增資料✨

新增資料需要選擇一個資料夾,資料夾的結構範例,如右側所示:

image-20231220223727032

像右側所示這樣組織檔案:

image-20231221090614621

先建立一個名為貓狗圖片的資料夾然後在裡面再分別新增一個命名為狗和貓的資料夾,在裡面各新增2500張圖片。

在狗資料夾中新增狗的圖片:

image-20231221090811257

在貓資料夾中新增貓的圖片:

image-20231221091034432

訓練模型✨

開始訓練:

image-20231220210411840

需要等待一定的時間。

訓練完成:

image-20231220212720758

評估模型✨

image-20231220213352174

image-20231220213451843

image-20231220213534280

在.NET應用中使用模型✨

訓練完成後,在解決方案的mbconfig下生成了三個檔案:

image-20231221092356947

IdentifyDogsAndCats.consumption.cs: 此檔案包含模型輸入和輸出類以及可用於模型消耗的 Predict 方法。

IdentifyDogsAndCats.mlnet: 該檔案是經過訓練的 ML.NET 模型,它是一個序列化的 zip 檔案。

IdentifyDogsAndCats.training.cs: 此檔案包含用於瞭解輸入列對模型預測的重要性的程式碼。

在應用臺程式中整合該模型✨

建立一個控制檯應用:

image-20231221092839597

新增專案依賴:

右鍵TestModel,選擇「新增專案參照」。

image-20231221092945301

選擇包含模型的類庫:

image-20231221093034754

將Program.cs中的程式碼替換為如下程式碼:

using Model = IdentifyDogsAndCats;
namespace TestModel
{
   internal class Program
  {
       static void Main(string[] args)
      {
           //Load sample data
           var imageBytes = File.ReadAllBytes(@"D:\學習路線\C#\ML.NET\IdentifyDogsAndCats\test1\21.jpg");
           Model.IdentifyDogsAndCats.ModelInput sampleData = new()
          {
               ImageSource = imageBytes,
          };

           //Load model and predict output
           var result = Model.IdentifyDogsAndCats.Predict(sampleData);

           //輸出結果
           Console.WriteLine(result.PredictedLabel);
      }
  }

開始執行:

image-20231221102750438

image-20231221102810219

檢視這張圖片:

image-20231221102839318

在winform中整合該模型✨

新增一個winform專案,右鍵新增專案參照:

image-20231221103159329

為了便於演示,設計頁面如下:

image-20231221104030480

Form1.cs中程式碼如下:

namespace WinFormsApp1
{
   public partial class Form1 : Form
  {
       string selectedImagePath;
       public Form1()
      {
           InitializeComponent();
      }

       private void button1_Click(object sender, EventArgs e)
      {
           OpenFileDialog openFileDialog = new OpenFileDialog();

           // 設定對話方塊的標題
           openFileDialog.Title = "選擇圖片檔案";

             // 設定對話方塊初始目錄
 openFileDialog.InitialDirectory = @"D:\學習路線\C#\ML.NET\IdentifyDogsAndCats\test1";
           
           // 設定對話方塊允許選擇的檔案型別
           openFileDialog.Filter = "圖片檔案|*.jpg;*.jpeg;*.png;*.gif;*.bmp|所有檔案|*.*";

           // 如果使用者點選了「確定」按鈕
           if (openFileDialog.ShowDialog() == DialogResult.OK)
          {
               // 獲取選擇的檔案路徑
               selectedImagePath = openFileDialog.FileName;

               // 在這裡可以使用selectedImagePath進行後續操作,比如顯示圖片到表單上
               pictureBox1.Image = new Bitmap(selectedImagePath);



          }
      }

       private void button2_Click(object sender, EventArgs e)
      {
           //Load sample data
           var imageBytes = File.ReadAllBytes(selectedImagePath);
           IdentifyDogsAndCats.IdentifyDogsAndCats.ModelInput sampleData = new()
          {
               ImageSource = imageBytes,
          };

           //Load model and predict output
           var result = IdentifyDogsAndCats.IdentifyDogsAndCats.Predict(sampleData);

           //提示識別是否完成
           MessageBox.Show($"識別已完成,識別結果為:{result.PredictedLabel}");
           //將結果顯示在label1上
           label1.Text = result.PredictedLabel;
      }

       private void Form1_Load(object sender, EventArgs e)
      {

      }
  }
}

執行效果如下所示:

貓狗識別效果

可見第一次識別確實久一點,但是後面識別挺快的。

執行效果截圖:

image-20231221111125031

image-20231221110957744

總結✨

本文先是簡單介紹了ML.NETML.NET Model Builder,其次基於ML.NET Model Builder構建了一個貓狗識別的機器學習模型範例,最後在.NET專案中整合了它。

總體流程圖如下所示:

image-20231221120437686

希望對你有所幫助。