Giới thiệu Các thư viện Machine Learning (ML) như TensorFlow, Keras, CNTK hay PyTorch sử dụng ngôn ngữ Python làm nền tảng và rất khó cho các ứng dụng. NET có thể truy cập đến các thư viện này. Vì vậy, các nhà phát triển. NET đã phát triển thư viện ML. NET như là chiếc cầu nối giữa các thư viện Python và ứng dụng. NET. Chương trình DEMO Bài viết này sẽ hướng dẫn cách dùng ML. NET trong Visual Studio 2017 (tôi đang dùng VS 2017 Community) bằng cách tạo một chương trình dựa trên bài viết Introduction to the ML. NET Library của James McCaffrey trong tạp chí MSDN tháng 11/2018 . Chương trình xây dựng một mô hình ML để dự đoán một bệnh nhân (patient) sẽ chết (die) hay sống sót (survive) dựa trên các đặc trưng (features) như tuổi (age), giới tính (sex) và chỉ số chức năng thận (score on a kidney medical test). Vì kết quả dự đoán chỉ có hai khả năng là sống hay chết nên đây là vấn đề phân loại nhị phân (binary classification problem) trong Machine Learning. Bước 1: Tạo ứng dụng C# Console (. NET Framework) Mở Visual Studio 2017 tạo một dự án C# Console Application (. NET Framework) và đặt tên nó là MyFirstMLDOTNET. Trong cửa sổ Solution Explorer, tìm đến tập tin Program. Cs và đổi tên thành MyFirstMLDOTNET. Cs Bước 2: Cài đặt thư viện ML. NET Cũng trong cửa sổ Solution Explorer, nhấn chuột phải vào dự án MyFirstMLDOTNET và chọn Manage NuGet Packages Trong cửa sổ NuGet chọn tab Browse và gõ cụm từ "ML. NET" chọn Microsoft. ML và nhấn Install: Nhấn OK từ hộp thoại Preview Changes và nhấn I Accept trong License Acceptance và chờ cài đặt. Nếu cài thành công sẽ xuất hiện thông điệp trong cửa sổ Output như sau: Lúc này nếu thực thi ứng dụng chúng ta sẽ nhận lỗi sau: Khắc phục lỗi này bằng cách nhấn chuột phải vào dự án MyFirstMLDOTNET và chọn Properties. Trong cửa sổ Properties chọn Build bên trái và thay đổi từ Any CPU đến x64 trong mục Platform target: Nhấn Save và chọn mục Application. Trong Target framework chọn . NET Framework 4.7 trở lên, nếu chưa cài đặt thì chọnInstall other frameworks sẽ đến trang chủ Microsoft để tải gói Developer Pack v à cài đặt Nếu chúng ta chọn. NET Framework phiên bản thấp hơn 4.7 sẽ gặp các lỗi khi thực thi một số thư viện toán học. Lúc này chúng ta thực thi lại chương trình sẽ không còn xuất hiện lỗi. Bước 3: Tạo tập tin dữ liệu huấn luyện Sau khi tạo thành công một ứng dụng, chúng ta sẽ tạo một tập tin chứa các dữ liệu dùng cho việc huấn luyện (training data) bằng cách nhấn chuột phải vào dự án MyFirstMLDOTNET và chọn Add > New Item và chọn kiểu Text File và gõ tận tập tin là myMLData. Txt Và nhấn Add. Trong tập tin myMLData. Txt nhập nội dung sau: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 48, +1, 4.40, survive 60, -1, 7.89, die 51, -1, 3.48, survive 66, -1, 8.41, die 40, +1, 3.05, survive 44, +1, 4.56, survive 80, -1, 6.91, die 52, -1, 5.69, survive 56, -1, 4.01, survive 55, -1, 4.48, survive 72, +1, 5.97, survive 57, -1, 6.71, die 50, -1, 6.40, survive 80, -1, 6.67, die 69, +1, 5.79, survive 39, -1, 5.42, survive 68, -1, 7.61, die 47, +1, 3.24, survive 45, +1, 4.29, survive 79, +1, 7.44, die 44, -1, 2.55, survive 52, +1, 3.71, survive 55, +1, 5.56, die 76, -1, 7.80, die 51, -1, 5.94, survive 46, +1, 5.52, survive 48, -1, 3.25, survive 58, +1, 4.71, survive 44, +1, 2.52, survive 68, -1, 8.38, die Bước 4: Sử dụng thư viện ML. NET Trong tập tin MyFirstMLDOTNET. Cs thay nội dung đã có bằng nội dung sau: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 Using System; Using Microsoft. ML. Runtime. Api; Using System. Threading. Tasks; Using Microsoft. ML. Legacy; Using Microsoft. ML. Legacy. Data; Using Microsoft. ML. Legacy. Transforms; Using Microsoft. ML. Legacy. Trainers; Using Microsoft. ML. Legacy. Models; Namespace MyFirstMLDOTNET { Class MyFirstMLDOTNET { Public class myData { [Column (ordinal: "0", name: "Age") ] Public float Age; [Column (ordinal: "1", name: "Sex") ] Public float Sex; [Column (ordinal: "2", name: "Kidney") ] Public float Kidney; [Column (ordinal: "3", name: "Label") ] Public string Label; } Public class myPrediction { [ColumnName ( "PredictedLabel") ] Public string PredictedLabels; } Static void Main (string[] args) { Console. WriteLine ( "ML. NET (v0.3. 0 preview) demo run") ; Console. WriteLine ( "Survival based on age, sex, kidney") ; Var pipeline = new LearningPipeline () ; String dataPath = ".. \\.. \\myMLData. Txt"; Pipeline. Add (new TextLoader (dataPath). CreateFrom<myData> (separator: ', ')) ; Pipeline. Add (new Dictionarizer ( "Label")) ; Pipeline. Add (new ColumnConcatenator ( "Features", "Age", "Sex", "Kidney")) ; Pipeline. Add (new LogisticRegressionBinaryClassifier ()) ; Pipeline. Add (new PredictedLabelColumnOriginalValueConverter () { PredictedLabelColumn = "PredictedLabel" }) ; Console. WriteLine ( "\nStarting training \n") ; Var model = pipeline. Train<myData, myPrediction> () ; Console. WriteLine ( "\nTraining complete \n") ; String ModelPath = ".. \\.. \\myFirstMLModel. Zip"; Task. Run (async () => { Await model. WriteAsync (ModelPath) ; }). GetAwaiter (). GetResult () ; Var testData = new TextLoader (dataPath). CreateFrom<myData> (separator: ', ') ; Var evaluator = new BinaryClassificationEvaluator () ; Var metrics = evaluator. Evaluate (model, testData) ; Double acc = metrics. Accuracy * 100; Console. WriteLine ( "Model accuracy =" + acc. ToString ( "F2") + "%") ; Console. WriteLine ( "Predict 50-year male, Kidney 4.80:") ; MyData newPatient = new myData () { Age = 50f, Sex = -1f, Kidney = 4.80f }; MyPrediction prediction = model. Predict (newPatient) ; String result = prediction. PredictedLabels; Console. WriteLine ( "Prediction =" + result) ; Console. WriteLine ( "\nEnd ML. NET demo") ; Console. ReadLine () ; } } } Bước 5: Thực thi ứng dụng Thực thi sẽ cho kết quả: Giải thích Chúng ta tạo lớp myData bên trong lớp MyFirstMLDOTNET định nghĩa cấu trúc dữ liệu cho dữ liệu huấn luyện. Các thông tin gồm Age, Sex, Kidney và Label (survive hay die). Lưu ý rằng chúng ta dùng kiểu dữ liệu float (cho Age, Sex, Kidney) thay vì dùng double vì trong ML kiểu float là kiểu mặc định. Chúng ta cũng tạo ra lớp myPrediction để chứa thông tin về dự đoán. Chúng ta tạo mô hình ML với các lệnh sau: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Var pipeline = new LearningPipeline () ; String dataPath = ".. \\.. \\myMLData. Txt"; Pipeline. Add (new TextLoader (dataPath). CreateFrom<myData> (separator: ', ')) ; Pipeline. Add (new Dictionarizer ( "Label")) ; Pipeline. Add (new ColumnConcatenator ( "Features", "Age", "Sex", "Kidney")) ; Pipeline. Add (new LogisticRegressionBinaryClassifier ()) ; Pipeline. Add (new PredictedLabelColumnOriginalValueConverter () { PredictedLabelColumn = "PredictedLabel" }) ; Đối tượng pipeline đại diện cho mô hình ML chưa được huấn luyện kết hợp với dữ liệu dùng cho huấn luyện. Mỗi hàng dữ liệu huấn luyện chứa giá trị cuối là "survive" hay "die" là các chuỗi (kiểu String) nhưng mô hình ML chỉ đọc được giá trị số nên lớp Dictionarizer được dùng để mã hóa hai chuỗi thành các giá trị 0 hay 1. ColumnConcatenator kết hợp các cột Age, Sex, và Kidney trong một cột gọi là Features. Ở đây kỹ thuật logistic regression được sử dụng để giải quyết vấn đề phân loại nhị phân của chúng ta. Mô hình được huấn luyện và lưu lại như sau: 1 2 3 4 5 6 7 8 9 10 11 12 13 Var model = pipeline. Train<myData, myPrediction> () ; Console. WriteLine ( "\nTraining complete \n") ; String ModelPath = ".. \\.. \\myFirstMLModel. Zip"; Task. Run (async () => { Await model. WriteAsync (ModelPath) ; }). GetAwaiter (). GetResult () ; Đánh giá mô hình sau khi được huấn luyện: 1 2 3 4 5 6 7 8 9 10 Var testData = new TextLoader (dataPath). CreateFrom<myData> (separator: ', ') ; Var evaluator = new BinaryClassificationEvaluator () ; Var metrics = evaluator. Evaluate (model, testData) ; Double acc = metrics. Accuracy * 100; Console. WriteLine ( "Model accuracy =" + acc. ToString ( "F2") + "%") ; Cuối dùng là sử dụng mô hình để thực hiện dự đoán: 1 2 3 4 5 6 7 8 9 10 Console. WriteLine ( "Predict 50-year male, Kidney 4.80:") ; MyData newPatient = new myData () { Age = 50f, Sex = -1f, Kidney = 4.80f }; MyPrediction prediction = model. Predict (newPatient) ; String result = prediction. PredictedLabels; Console. WriteLine ( "Prediction =" + result) ; Lời cuối Thư viện ML. NET đang được tiếp tục hoàn thiện và phát triển, là công cụ phục vụ nghiên cứu ML rất hữu ích cho các nhà phát triển và người học. NET. Chúng ta có thể khám phá thêm về thư viện ML. NET tại đây . James McCaffrey chuyên viết về các chủ đề ML trong. NET và chúng ta có thể tìm hiểu các bài viết khác của Jamestại đây .