Bagikan melalui


Tutorial: Membuat aplikasi Windows Pembelajaran Mesin UWP (C#)

Dalam tutorial ini, kita akan membangun aplikasi Platform Windows Universal sederhana yang menggunakan model pembelajaran mesin terlatih untuk mengenali digit numerik yang digambar oleh pengguna. Tutorial ini terutama berfokus pada cara memuat dan menggunakan Windows ML di aplikasi UWP Anda.

Video berikut memandu sampel yang didasarkan pada tutorial ini.


Jika Anda lebih suka hanya melihat kode tutorial yang sudah selesai, Anda dapat menemukannya di repositori WinML GitHub. Ini juga tersedia di C++/CX.

Prasyarat

  • Windows 10 (Versi 1809 atau lebih tinggi)
  • Windows 10 SDK (Build 17763 atau lebih tinggi)
  • Visual Studio 2019 (atau Visual Studio 2017, versi 15.7.4 atau yang lebih baru)
  • Ekstensi Windows Pembelajaran Mesin Code Generator untuk Visual Studio 2019 atau 2017
  • Beberapa pengetahuan dasar UWP dan C#

1. Buka proyek di Visual Studio

Setelah Anda mengunduh proyek dari GitHub, luncurkan Visual Studio dan buka file MNIST_Demo.sln (seharusnya terletak di <Jalur ke repo>\Windows-Machine-Pembelajaran\Samples\MNIST\Tutorial\cs). Jika solusi ditampilkan sebagai tidak tersedia, Anda harus mengklik kanan proyek di Penjelajah Solusi dan memilih Muat Ulang Proyek.

Kami telah menyediakan templat dengan kontrol dan peristiwa XAML yang diimplementasikan, termasuk:

  • InkCanvas untuk menggambar digit.
  • Tombol untuk menafsirkan digit dan menghapus kanvas.
  • Rutinitas pembantu untuk mengonversi output InkCanvas ke VideoFrame.

Di dalam Penjelajah Solusi, proyek memiliki tiga file kode utama:

  • MainPage.xaml - Semua kode XAML kami untuk membuat UI untuk InkCanvas, tombol, dan label.
  • MainPage.xaml.cs - Tempat kode aplikasi kita berada.
  • Helper.cs - Pembantu rutinitas untuk memotong dan mengonversi format gambar.

Visual Studio solution explorer with project files

2. Bangun dan jalankan proyek

Di toolbar Visual Studio, ubah Platform Solusi ke x64 untuk menjalankan proyek di komputer lokal Anda jika perangkat Anda 64-bit, atau x86 jika 32-bit. (Anda dapat memeriksa di aplikasi Windows Pengaturan: Sistem > Tentang > Spesifikasi > perangkat Jenis sistem.)

Untuk menjalankan proyek, klik tombol Mulai Penelusuran Kesalahan pada toolbar, atau tekan F5. Aplikasi harus menampilkan InkCanvas tempat pengguna dapat menulis digit, tombol Kenali untuk menginterpretasikan angka, bidang label kosong tempat digit yang ditafsirkan akan ditampilkan sebagai teks, dan tombol Hapus Digit untuk menghapus InkCanvas.

Application screenshot

Catatan

Jika proyek tidak akan dibuat, Anda mungkin perlu mengubah versi target penyebaran proyek. Klik kanan proyek di Penjelajah Solusi dan pilih Properti. Di tab Aplikasi, atur versi Target dan versi Min agar sesuai dengan OS dan SDK Anda.

Catatan

Jika Anda mendapatkan peringatan bahwa aplikasi sudah diinstal, cukup pilih Ya untuk melanjutkan penyebaran. Anda mungkin perlu menutup Visual Studio dan membuka kembali jika masih tidak berfungsi.

3. Unduh model

Selanjutnya, mari kita dapatkan model pembelajaran mesin untuk ditambahkan ke aplikasi kita. Untuk tutorial ini, kita akan menggunakan model MNIST yang telah dilatih sebelumnya yang dilatih dengan Microsoft Cognitive Toolkit (CNTK) dan diekspor ke format ONNX.

Model MNIST telah disertakan dalam folder Aset Anda, dan Anda harus menambahkannya ke aplikasi Anda sebagai item yang ada. Anda juga dapat mengunduh model yang telah dilatih sebelumnya dari ONNX Model Zoo di GitHub.

4. Tambahkan model

Klik kanan pada folder Aset di Penjelajah Solusi, dan pilih Tambahkan>Item yang Ada. Arahkan pemilih file ke lokasi model ONNX Anda, dan klik Tambahkan.

Proyek sekarang harus memiliki dua file baru:

  • mnist.onnx - Model terlatih Anda.
  • mnist.cs - Kode yang dihasilkan Windows ML.

Solution explorer with new files

Untuk memastikan model dibuat saat kami mengkompilasi aplikasi kami, klik kanan pada file mnist.onnx , dan pilih Properti. Untuk Tindakan Build, pilih Konten.

Sekarang, mari kita lihat kode yang baru dibuat dalam file mnist.cs . Kami memiliki tiga kelas:

  • mnistModel membuat representasi model pembelajaran mesin, membuat sesi pada perangkat default sistem, mengikat input dan output tertentu ke model, dan mengevaluasi model secara asinkron.
  • mnistInput menginisialisasi jenis input yang diharapkan model. Dalam hal ini, input mengharapkan ImageFeatureValue.
  • mnistOutput menginisialisasi jenis yang akan dihasilkan model. Dalam hal ini, output akan menjadi daftar yang disebut Plus214_Output_0 jenis TensorFloat.

Kita sekarang akan menggunakan kelas-kelas ini untuk memuat, mengikat, dan mengevaluasi model dalam proyek kita.

5. Muat, ikat, dan evaluasi model

Untuk aplikasi Windows ML, pola yang ingin kita ikuti adalah: Load > Bind > Evaluate.

  1. Muat model pembelajaran mesin.
  2. Ikat input dan output ke model.
  3. Evaluasi model dan lihat hasilnya.

Kami akan menggunakan kode antarmuka yang dihasilkan dalam mnist.cs untuk memuat, mengikat, dan mengevaluasi model dalam aplikasi kami.

Pertama, di MainPage.xaml.cs, mari kita instans model, input, dan output. Tambahkan variabel anggota berikut ke kelas MainPage :

private mnistModel ModelGen;
private mnistInput ModelInput = new mnistInput();
private mnistOutput ModelOutput;

Kemudian, di LoadModelAsync, kita akan memuat model. Metode ini harus dipanggil sebelum kita menggunakan salah satu metode model (yaitu, pada peristiwa Dimuat MainPage, pada penimpaan OnNavigatedTo, atau di mana saja sebelum recognizeButton_Click dipanggil). Kelas mnistModel mewakili model MNIST dan membuat sesi pada perangkat default sistem. Untuk memuat model, kami memanggil metode CreateFromStreamAsync , meneruskan file ONNX sebagai parameter .

private async Task LoadModelAsync()
{
    // Load a machine learning model
    StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/mnist.onnx"));
    ModelGen = await mnistModel.CreateFromStreamAsync(modelFile as IRandomAccessStreamReference);
}

Catatan

Jika Anda mendapatkan garis bawah merah di bawah IRandomAccessStreamReference, Anda perlu menyertakan namespace layanannya. Letakkan kursor Anda di atasnya, tekan Ctrl + . dan pilih menggunakan Windows.Storage.Aliran dari menu drop-down.

Selanjutnya, kita ingin mengikat input dan output ke model. Kode yang dihasilkan juga mencakup kelas pembungkus mnistInput dan mnistOutput . Kelas mnistInput mewakili input model yang diharapkan, dan kelas mnistOutput mewakili output model yang diharapkan.

Untuk menginisialisasi objek input model, panggil konstruktor kelas mnistInput , teruskan data aplikasi Anda, dan pastikan data input Anda cocok dengan jenis input yang diharapkan model Anda. Kelas mnistInput mengharapkan ImageFeatureValue, jadi kami menggunakan metode pembantu untuk mendapatkan ImageFeatureValue untuk input.

Dengan menggunakan fungsi pembantu yang disertakan di helper.cs, kami akan menyalin konten InkCanvas, mengonversinya ke jenis ImageFeatureValue, dan mengikatnya ke model kami.

private async void recognizeButton_Click(object sender, RoutedEventArgs e)
{
    // Bind model input with contents from InkCanvas
    VideoFrame vf = await helper.GetHandWrittenImage(inkGrid);
    ModelInput.Input3 = ImageFeatureValue.CreateFromVideoFrame(vf);
}

Untuk output, kita cukup memanggil EvaluateAsync dengan input yang ditentukan. Setelah input Anda diinisialisasi, panggil metode EvaluateAsync model untuk mengevaluasi model Anda pada data input. EvaluateAsync mengikat input dan output Anda ke objek model dan mengevaluasi model pada input.

Karena model mengembalikan tensor output, pertama-tama kita ingin mengonversinya menjadi jenis data yang ramah, lalu mengurai daftar yang dikembalikan untuk menentukan digit mana yang memiliki probabilitas tertinggi dan menampilkannya.

private async void recognizeButton_Click(object sender, RoutedEventArgs e)
{
    // Bind model input with contents from InkCanvas
    VideoFrame vf = await helper.GetHandWrittenImage(inkGrid);
    ModelInput.Input3 = ImageFeatureValue.CreateFromVideoFrame(vf);

    // Evaluate the model
    ModelOutput = await ModelGen.EvaluateAsync(ModelInput);

    // Convert output to datatype
    IReadOnlyList<float> vectorImage = ModelOutput.Plus214_Output_0.GetAsVectorView();
    IList<float> imageList = vectorImage.ToList();

    // Query to check for highest probability digit
    var maxIndex = imageList.IndexOf(imageList.Max());

    // Display the results
    numberLabel.Text = maxIndex.ToString();
}

Terakhir, kita ingin menghapus InkCanvas untuk memungkinkan pengguna menggambar nomor lain.

private void clearButton_Click(object sender, RoutedEventArgs e)
{
    inkCanvas.InkPresenter.StrokeContainer.Clear();
    numberLabel.Text = "";
}

6. Luncurkan aplikasi

Setelah membuat dan meluncurkan aplikasi (tekan F5), kita akan dapat mengenali angka yang digambar pada InkCanvas.

complete application

Itu saja - Anda telah membuat aplikasi Windows ML pertama Anda! Untuk sampel lebih lanjut yang menunjukkan cara menggunakan Windows ML, lihat repositori Windows-Machine-Pembelajaran kami di GitHub.

Catatan

Gunakan sumber daya berikut untuk bantuan dengan Windows ML:

  • Untuk mengajukan atau menjawab pertanyaan teknis tentang Windows ML, silakan gunakan tag windows-machine-learning di Stack Overflow.
  • Untuk melaporkan bug, silakan ajukan masalah di GitHub kami.