Khi nói tới Machine Learning (ML) chúng ta thường nghĩ tới ngôn ngữ Python hay R và các thư viện liên quan như TensorFlow, Keras, Scikit-Learn, v.v. Nhưng những người chuyên sử dụng các ngôn ngữ của Microsoft như C# hay F# cũng không quá lo lắng vì Microsoft đã có những động thái rất tích cực trong việc tham gia vào sự phát triển của AI nói chung hay Machine Learning nói riêng. Trong lĩnh vực ML, các thư viện không ngừng được tạo ra, dùng làm chiếc cầu nối giữa những nhà phát triển .NET và các thư viện ML phổ biến khác. ML.NET và Infer.NET là những ví dụ. Tôi đã có một bài viết giới thiệu về ML.NET và trong bài này tôi sẽ giới thiệu thư viện Infer.NET.
Infer.NET
Nếu bạn đang học hay làm việc trong lĩnh vực ML thì các vấn đề liên quan đến xác suất sẽ không thể tránh khỏi mà còn rất phổ biến như vấn đề phân loại, hệ thống đề xuất, hay việc rút trích thông tin từ những văn bản phi cấu trúc. Microsoft đã phát triển thư viện Infer.NET để giúp cho việc xây dựng các hệ thống xác suất được dễ dàng hơn. Thư viện này hỗ trợ hai ngôn ngữ là C# và F#.
Bài viết này sẽ hướng dẫn cách cài đặt thư viện Infer.NET trong Visual Studio 2017 Community và cũng minh họa một chương trình C# Console đơn giản sử dụng thư viện Infer.NET để xử lý các vấn đề xác suất trong cuộc sống.
Tạo một chương trình C# Console và cài đặt thư viện Infer.NET trong VS 2017 Community
Tạo một chương trình C# Console App (.NET Framework) tên InferDotNetDemo và chọn phiên bản .NET Framework 4.7 trở lên (Nếu chưa cài đặt thì có thể xem lại bài giới thiệu về thư viện ML.NET)
Khi dự án được tạo, trong cửa sổ Solution Explorer đổi tên tập tin Program.cs thành InferDotNetDemo.cs
Lúc này chúng ta có thể cài đặt thư viện Infer.NET đến dự án để có thể sử dụng bằng cách nhấn chuột phải vào tên dự án trong cửa sổ Solution Explorer và chọn Manage NuGet Packages:
Trong cửa sổ NuGet, chọn tab Browse, gõ cụm từ ‘infer.net’ trong ô tìm kiếm và gõ Enter. Chọn gói Microsoft.ML.Probabilistic.Compiler và nhấn nút Install bên phải:
Nhấn OK trong Preview Changes và nhấn I Accept trong License Acceptance. Nếu thành công, VS sẽ hiển thị thông điệp đến cửa sổ Output:
Ok, như vậy là chúng ta đã sẵn sàng viết một chương trình Infer.NET đầu tiên.
Chương trình Infer.NET đầu tiên
Khi đã cài đặt thành công thư viện Infer.NET, các namespace sau đây phải được đưa vào chương trình InferDotNetDemo:
using Microsoft.ML.Probabilistic.Models; using Microsoft.ML.Probabilistic.Algorithms; using Microsoft.ML.Probabilistic.Distributions;
Bài toán hai đồng xu
Trong bài viết này tôi sẽ sử dụng bài toán hai đồng xu để minh họa chương trình đầu tiên của chúng ta. Bài toán này được tham khảo từ thư viện Infer.NET và có thể tham khảo tại đây.
Giả sử chúng ta có hai đồng xu giống nhau, đồng chất. Mỗi đồng xu gồm hai mặt tạm gọi là mặt sấp và mặt ngửa. Khi chúng ta tung một đồng xu ngẫu nhiên và đồng xu rơi xuống mặt đất, có hai khả năng có thể xảy ra: đồng xu xuất hiện với mặt ngửa hay đồng xu xuất hiện với mặt sấp. Trong trường hợp này, chúng ta nói rằng xác suất đồng xu mặt sấp và mặt ngửa là như nhau và bằng 0.5 hay 50%.
Bây giờ nếu chúng ta tung cùng lúc hai đồng xu. Xác suất để hai đồng xu rơi xuống đất cùng là mặt ngửa là bao nhiêu? Nếu chúng ta vận dụng một ít kiến thức về xác suất thống kê thì kết quả sẽ là 0.5 X 0.5 = 0.25.
Biến ngẫu nhiên (hay biến nói chung) và phân phối xác suất là những khái niệm nền tảng trong xác suất thống kê và chúng cũng là các khái niệm cơ bản trong thư viện Infer.NET. Xét trong phép thử tung đồng xu ở trên, mỗi đồng xu sẽ được định nghĩa như một biến có hai giá trị là true nếu đồng xu rơi xuống là mặt ngửa và có giá trị là false nếu đồng xu rơi xuống là mặt sắp. Vì chúng ta không biết trước là đồng xu sẽ rơi mặt sấp hay mặt ngửa, nên biến này là biến ngẫu nhiên. Một biến ngẫu nhiên chỉ có hai khả năng xảy ra có thể định nghĩa qua phân phối Bernoulli. Gọi biến ngẫu nhiên đại diện cho đồng xu thứ nhất là firstCoin và biến ngẫu nhiên đại diện cho đồng xu thứ hai là secondCoin. Trong Infer.NET chúng ta có thể định nghĩa hai biến này dùng Variable<bool> qua phân phối xác suất Bernoulli với xác suất mặt ngửa là 0.5 như sau:
Variable<bool> firstCoin = Variable.Bernoulli(0.5); Variable<bool> secondCoin = Variable.Bernoulli(0.5);
Một cách khác để định nghĩa biến ngẫu nhiên trong Infer.NET là kết hợp các biến ngẫu nhiên có sẵn. Ví dụ chúng ta định nghĩa biến bothHeads đại diện cho trường hợp hai đồng xu được tung đồng thời và cùng có mặt ngửa khi rơi xuống đất, bothHeads có thể định nghĩa như sau:
Variable<bool> bothHeads = firstCoin & secondCoin;
bothHeads chỉ nhận giá trị true khi cả firstCoin và secondCoin cùng nhận giá trị true. Quá trình định nghĩa các biến ngẫu nhiên như trên được gọi là quá trình định nghĩa mô hình xác suất trong một chương trình Infer.NET.
Để tính xác suất của bothHeads chúng ta cần định nghĩa cỗ máy suy diễn với lớp InferenceEngine và sử dụng phương thức Infer() của lớp này để thực hiện truy vấn kết quả. Đoạn mã sau định nghĩa một cỗ máy suy diễn sử dụng thuật toán mặc định và phương thức Infer() để tính xác suất của bothHeads:
InferenceEngine engine = new InferenceEngine(); Console.WriteLine("Xác suất cả hai đồng xu là mặt ngửa: "+engine.Infer(bothHeads));
Tóm lại, một chương trình Infer.NET sẽ gồm 3 bước cơ bản sau:
- Định nghĩa mô hình xác suất
- Định nghĩa cỗ máy suy diễn
- Thực thi truy vấn dùng phương thức Infer()
Chương trình hoàn chỉnh tính xác suất hai đồng xu cùng mặt ngửa như sau:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.ML.Probabilistic.Models; using Microsoft.ML.Probabilistic.Algorithms; using Microsoft.ML.Probabilistic.Distributions; namespace ConsoleApp1 { class InferDemoProgram { static void Main(string[] args) { //**************Bước 1: Định nghĩa mô hình xác suất************************* Variable<bool> firstCoin = Variable.Bernoulli(0.5); Variable<bool> secondCoin = Variable.Bernoulli(0.5); Variable<bool> bothReds = firstPicking & secondPicking; //**************Bước 2: tạo một cỗ máy suy diễn************************* InferenceEngine ie = new InferenceEngine(); //**************Bước 3: Thực thi truy vấn************************* //Dùng thuật toán mặc định Expectation Propagation if (!(ie.Algorithm is VariationalMessagePassing)) { Console.WriteLine("Xác suất cả hai đồng xu là mặt ngửa: "+engine.Infer(bothHeads)); } else Console.WriteLine("Không chạy với thuật toán Variational Message Passing!"); Console.ReadKey(); } } }
Trên đây chỉ là một giới thiệu cơ bản và một chương trình vô cùng đơn giản về thư viện Infer.NET. Để hiểu sâu hơn về cách sử dụng thư viện này, chúng ta có thể tham khảo tại Infer.NET User Guide hay các bài viết Machine Learning Through Probabilistic Programming của Yordan Zaykov và Rating Competitors Using Infer.NET của James McCaffrey.
Ý kiến bài viết