Menyebarkan model di aplikasi Windows dengan Windows ML API
Di bagian sebelumnya dari tutorial ini, Anda mempelajari cara membangun dan mengekspor model dalam format ONNX. Sekarang, kami akan menunjukkan kepada Anda cara menyematkan model yang diekspor ke dalam aplikasi Windows, dan menjalankannya secara lokal di perangkat dengan memanggil API WinML.
Pada saat kami selesai, Anda akan memiliki aplikasi klasifikasi gambar yang berfungsi.
Tentang aplikasi sampel
Dalam langkah tutorial ini, Anda akan membuat aplikasi yang dapat mengklasifikasikan gambar menggunakan model ML Anda. UI dasarnya memungkinkan Anda memilih gambar dari perangkat lokal Anda, dan menggunakan model ONNX klasifikasi yang Anda buat dan latih di bagian sebelumnya untuk mengklasifikasikannya. Tag yang dikembalikan oleh model kemudian ditampilkan di samping gambar.
Di sini, kami akan memandul Anda melalui proses itu.
Catatan
Jika Anda memilih untuk menggunakan sampel kode yang telah ditentukan sebelumnya, Anda dapat mengkloning file solusi. Kloning repositori, navigasikan ke sampel ini, dan buka classifierPyTorch.sln
file dengan Visual Studio.Lewati ke Luncurkan bagian Aplikasi dari halaman ini untuk melihatnya digunakan.
Di bawah ini, kami akan memandu Anda cara membuat aplikasi dan menambahkan kode Windows ML.
Membuat Windows ML UWP (C#)
Untuk membuat aplikasi Windows ML yang berfungsi, Anda harus melakukan hal berikut:
- Muat model pembelajaran mesin.
- Muat gambar dalam format yang diperlukan.
- Ikat input dan output model.
- Mengevaluasi model dan menampilkan hasil yang bermakna.
Anda juga harus membuat UI dasar, karena sulit untuk membuat aplikasi berbasis gambar yang memuaskan di baris perintah.
Membuka proyek baru dalam Visual Studio
- Mari kita mulai. Buka Visual Studio dan pilih buat proyek baru.
- Di bilah pencarian, ketik
UWP
, lalu pilihBlank APP (Universal Windows)
. Ini membuka proyek C# untuk aplikasi Platform Windows Universal satu halaman (UWP) dengan kontrol atau tata letak yang telah ditentukan sebelumnya. Pilihnext
untuk membuka jendela konfigurasi untuk proyek.
- Di jendela konfigurasi, lakukan hal berikut:
- Beri nama proyek Anda. Di sini, kami menyebutnya pengklasifikasiPyTorch.
- Pilih lokasi proyek Anda.
- Jika Anda menggunakan VS2019, pastikan
Create directory for solution
dicentang. - Jika Anda menggunakan VS2017, pastikan
Place solution and project in the same directory
tidak dicentang.
Tekan create
untuk membuat proyek Anda. Jendela versi target minimum dapat muncul. Pastikan versi minimum Anda diatur ke Windows 10, versi 1809 (10.0; build 17763) atau yang lebih tinggi.
- Setelah proyek dibuat, navigasikan ke folder proyek, buka folder aset , dan salin file Anda
ImageClassifier.onnx
[….\classifierPyTorch \Assets]
ke lokasi ini.
Menjelajahi solusi proyek
Mari kita jelajahi solusi proyek Anda.
Visual Studio secara otomatis membuat beberapa file kode cs di dalam Penjelajah Solusi. MainPage.xaml
berisi kode XAML untuk GUI Anda, dan MainPage.xaml.cs
berisi kode aplikasi Anda, juga dikenal sebagai kode di belakang. Jika Anda telah membuat aplikasi UWP sebelumnya, file-file ini harus sangat akrab bagi Anda.
Membuat GUI Aplikasi
Pertama, mari kita buat GUI sederhana untuk aplikasi Anda.
Klik dua kali pada
MainPage.xaml
file kode. Di aplikasi kosong Anda, templat XAML untuk GUI aplikasi Anda kosong, jadi kita harus menambahkan beberapa fitur UI.Tambahkan kode di bawah ini ke
MainPage.xaml
, menggantikan<Grid>
tag dan</Grid>
.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="1,0,-1,0">
<TextBlock x:Name="Menu"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="10,0,0,0"
Text="Image Classification"/>
<TextBlock Name="space" />
<Button Name="recognizeButton"
Content="Pick Image"
Click="OpenFileButton_Click"
Width="110"
Height="40"
IsEnabled="True"
HorizontalAlignment="Left"/>
<TextBlock Name="space3" />
<Button Name="Output"
Content="Result is:"
Width="110"
Height="40"
IsEnabled="True"
HorizontalAlignment="Left"
VerticalAlignment="Top">
</Button>
<!--Display the Result-->
<TextBlock Name="displayOutput"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="25,0,0,0"
Text="" Width="1471" />
<TextBlock Name="space2" />
<!--Image preview -->
<Image Name="UIPreviewImage" Stretch="Uniform" MaxWidth="300" MaxHeight="300"/>
</StackPanel>
</Grid>
Menambahkan model ke proyek menggunakan Windows ML Code Generator (mlgen)
Windows Pembelajaran Mesin Code Generator, atau mlgen, adalah ekstensi Visual Studio untuk membantu Anda mulai menggunakan API WinML di aplikasi UWP. Ini menghasilkan kode templat saat Anda menambahkan file ONNX terlatih ke dalam proyek UWP.
Mlgen generator kode Windows Pembelajaran Mesin membuat antarmuka (untuk C#, C++/WinRT, dan C++/CX) dengan kelas pembungkus yang memanggil Windows ML API untuk Anda. Ini memungkinkan Anda untuk dengan mudah memuat, mengikat, dan mengevaluasi model dalam proyek Anda. Kita akan menggunakannya dalam tutorial ini untuk menangani banyak fungsi tersebut bagi kita.
Generator kode tersedia untuk Visual Studio 2017 dan yang lebih baru. Sebaiknya gunakan Visual Studio. Perlu diketahui bahwa di Windows 10, versi 1903 dan yang lebih baru, mlgen tidak lagi disertakan dalam Windows 10 SDK, sehingga Anda harus mengunduh dan menginstal ekstensi. Jika Anda telah mengikuti tutorial ini dari pengantar, Anda akan telah menangani ini, tetapi jika tidak, Anda harus mengunduh untuk VS 2019 atau untuk VS 2017.
Catatan
Untuk mempelajari lebih lanjut tentang mlgen, silakan lihat dokumentasi mlgen
Jika Anda belum melakukannya, instal mlgen.
Klik kanan pada
Assets
folder di Penjelajah Solusi di Visual studio, dan pilihAdd > Existing Item
.Navigasi ke folder aset di dalam
classifierPyTorch [….\classifierPyTorch \Assets]
, temukan model ONNX yang sebelumnya Anda salin di sana, dan pilihadd
.Setelah Anda menambahkan model ONNX ke folder aset di penjelajah solusi di VS, proyek sekarang harus memiliki dua file baru:
ImageClassifier.onnx
- ini adalah model Anda dalam format ONNX.ImageClassifier.cs
– file kode WinML yang dihasilkan secara otomatis.
- Untuk memastikan model dibuat saat Anda mengkompilasi aplikasi kami, pilih
ImageClassifier.onnx
file dan pilihProperties
. UntukBuild Action
, pilihContent
.
Kode file ONNX
Sekarang, mari kita jelajahi kode yang baru dibuat dalam ImageClassifier.cs
file.
Kode yang dihasilkan mencakup tiga kelas:
ImageClassifierModel
: Kelas ini mencakup dua metode untuk instansiasi model dan evaluasi model. Ini akan membantu kami membuat representasi model pembelajaran mesin, membuat sesi pada perangkat default sistem, mengikat input dan output tertentu ke model, dan mengevaluasi model secara asinkron.ImageClassifierInput
: Kelas ini menginisialisasi jenis input yang diharapkan model. Input model tergantung pada persyaratan model untuk data input.ImageClassifierOutput
: Kelas ini menginisialisasi jenis yang akan dihasilkan model. Output model tergantung pada bagaimana output didefinisikan oleh model.
Dalam tutorial ini, kita tidak ingin berurusan dengan tensorisasi. Kita akan membuat sedikit perubahan pada ImageClassifierInput
kelas, untuk mengubah jenis data input dan membuat hidup kita lebih mudah.
- Buat perubahan berikut dalam
ImageClassifier.cs
file:
input
Ubah variabel dari menjadi TensorFloat
ImageFeatureValue
.
public sealed class ImageClassifierInput
{
public ImageFeatureValue input; // shape(-1,3,32,32)
}
Muat Model
Klik dua kali pada
MainPage.xaml.cs
file untuk membuka code-behind untuk aplikasi.Ganti pernyataan "menggunakan" dengan mengikuti, untuk mendapatkan akses ke semua API yang akan Anda butuhkan:
// Specify all the using statements which give us the access to all the APIs that we'll need
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Graphics.Imaging;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
- Tambahkan deklarasi variabel berikut di dalam kelas Anda
MainPage
, di ataspublic MainPage()
fungsi .
// All the required fields declaration
private ImageClassifierModel modelGen;
private ImageClassifierInput image = new ImageClassifierInput();
private ImageClassifierOutput results;
private StorageFile selectedStorageFile;
private string label = "";
private float probability = 0;
private Helper helper = new Helper();
public enum Labels
{
plane,
car,
bird,
cat,
deer,
dog,
frog,
horse,
ship,
truck
}
Sekarang, Anda akan menerapkan metode .LoadModel
Metode ini akan mengakses model ONNX dan menyimpannya dalam memori. Kemudian, Anda akan menggunakan CreateFromStreamAsync
metode untuk membuat instans model sebagai LearningModel
objek. Kelas mewakili LearningModel
model pembelajaran mesin terlatih. Setelah dibuat, LearningModel
adalah objek awal yang Anda gunakan untuk berinteraksi dengan Windows ML.
Untuk memuat model, Anda dapat menggunakan beberapa metode statis di LearningModel
kelas . Dalam hal ini, Anda akan menggunakan metode .CreateFromStreamAsync
Metode CreateFromStreamAsync
ini secara otomatis dibuat dengan mlgen, sehingga Anda tidak perlu menerapkan metode ini. Anda dapat meninjau metode ini dengan mengklik dua kali pada classifier.cs
file yang dihasilkan oleh mlgen.
Catatan
Untuk mempelajari lebih lanjut tentang LearningModel
kelas, silakan tinjau dokumentasi Kelas Pembelajaran Model. Untuk mempelajari selengkapnya tentang cara memuat model tambahan, silakan tinjau dokumentasi Muat model
- Tambahkan panggilan ke
loadModel
metode ke konstruktor kelas utama.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
- Tambahkan implementasi metode , di dalam kelas itu
loadModel
MainPage
.
private async Task loadModel()
{
// Get an access the ONNX model and save it in memory.
StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/ImageClassifier.onnx"));
// Instantiate the model.
modelGen = await ImageClassifierModel.CreateFromStreamAsync(modelFile);
}
Muat Gambar
- Kita perlu menentukan peristiwa klik untuk memulai urutan empat panggilan metode untuk eksekusi model - konversi, pengikatan dan evaluasi, ekstraksi output, dan menampilkan hasilnya. Tambahkan metode berikut ke file kode Anda
MainPage.xaml.cs
diMainPage
dalam kelas .
// Waiting for a click event to select a file
private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
{
if (!await getImage())
{
return;
}
// After the click event happened and an input selected, begin the model execution.
// Bind the model input
await imageBind();
// Model evaluation
await evaluate();
// Extract the results
extractResult();
// Display the results
await displayResult();
}
- Sekarang, Anda akan menerapkan metode .
getImage()
Metode ini akan memilih file gambar input dan menyimpannya dalam memori. Tambahkan metode berikut ke file kode AndaMainPage.xaml.cs
diMainPage
dalam kelas .
// A method to select an input image file
private async Task<bool> getImage()
{
try
{
// Trigger file picker to select an image file
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
selectedStorageFile = await fileOpenPicker.PickSingleFileAsync();
if (selectedStorageFile == null)
{
return false;
}
}
catch (Exception)
{
return false;
}
return true;
}
Selanjutnya, Anda akan menerapkan metode gambar Bind()
untuk mendapatkan representasi file dalam format bitmap BGRA8. Tetapi pertama-tama, Anda akan membuat kelas pembantu untuk mengubah ukuran gambar.
- Untuk membuat file pembantu, klik kanan pada nama solusi (
ClassifierPyTorch
), lalu pilihAdd a new item
. Di jendela yang terbuka, pilihClass
dan beri nama. Di sini, kami menyebutnyaHelper
.
- File kelas baru akan muncul dalam proyek Anda. Buka kelas ini, dan tambahkan kode berikut:
using System;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Media;
namespace classifierPyTorch
{
public class Helper
{
private const int SIZE = 32;
VideoFrame cropped_vf = null;
public async Task<VideoFrame> CropAndDisplayInputImageAsync(VideoFrame inputVideoFrame)
{
bool useDX = inputVideoFrame.SoftwareBitmap == null;
BitmapBounds cropBounds = new BitmapBounds();
uint h = SIZE;
uint w = SIZE;
var frameHeight = useDX ? inputVideoFrame.Direct3DSurface.Description.Height : inputVideoFrame.SoftwareBitmap.PixelHeight;
var frameWidth = useDX ? inputVideoFrame.Direct3DSurface.Description.Width : inputVideoFrame.SoftwareBitmap.PixelWidth;
var requiredAR = ((float)SIZE / SIZE);
w = Math.Min((uint)(requiredAR * frameHeight), (uint)frameWidth);
h = Math.Min((uint)(frameWidth / requiredAR), (uint)frameHeight);
cropBounds.X = (uint)((frameWidth - w) / 2);
cropBounds.Y = 0;
cropBounds.Width = w;
cropBounds.Height = h;
cropped_vf = new VideoFrame(BitmapPixelFormat.Bgra8, SIZE, SIZE, BitmapAlphaMode.Ignore);
await inputVideoFrame.CopyToAsync(cropped_vf, cropBounds, null);
return cropped_vf;
}
}
}
Sekarang, mari kita konversi gambar ke format yang sesuai.
Kelas ImageClassifierInput
menginisialisasi jenis input yang diharapkan model. Dalam kasus kami, kami mengonfigurasi kode kami untuk mengharapkan ImageFeatureValue
.
Kelas menjelaskan ImageFeatureValue
properti gambar yang digunakan untuk meneruskan ke model. Untuk membuat ImageFeatureValue
, Anda menggunakan CreateFromVideoFrame
metode . Untuk detail yang lebih spesifik tentang mengapa hal ini terjadi dan cara kerja kelas dan metode ini, lihat dokumentasi kelas ImageFeatureValue
Catatan
Dalam tutorial ini, kita menggunakan ImageFeatureValue
kelas alih-alih tensor. Jika Window ML tidak mendukung format warna model Anda, ini tidak akan menjadi opsi. Untuk contoh cara bekerja dengan konversi gambar dan tensorisasi, lihat Sampel Tensorisasi Kustom.
- Tambahkan implementasi metode ke
convert()
file kode AndaMainPage.xaml.cs
di dalam kelas MainPage. Metode konversi akan memberi kita representasi file input dalam format BGRA8.
// A method to convert and bide the input image.
private async Task imageBind ()
{
UIPreviewImage.Source = null;
try
{
SoftwareBitmap softwareBitmap;
using (IRandomAccessStream stream = await selectedStorageFile.OpenAsync(FileAccessMode.Read))
{
// Create the decoder from the stream
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
// Get the SoftwareBitmap representation of the file in BGRA8 format
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
// Display the image
SoftwareBitmapSource imageSource = new SoftwareBitmapSource();
await imageSource.SetBitmapAsync(softwareBitmap);
UIPreviewImage.Source = imageSource;
// Encapsulate the image within a VideoFrame to be bound and evaluated
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
// Resize the image size to 32x32
inputImage=await helper.CropAndDisplayInputImageAsync(inputImage);
// Bind the model input with image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
image.modelInput = imageTensor;
// Encapsulate the image within a VideoFrame to be bound and evaluated
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
// bind the input image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
image.modelInput = imageTensor;
}
catch (Exception e)
{
}
}
Mengikat dan Mengevaluasi model
Selanjutnya, Anda akan membuat sesi berdasarkan model, mengikat input dan output dari sesi, dan mengevaluasi model.
Buat sesi untuk mengikat model:
Untuk membuat sesi, Anda menggunakan LearningModelSession
kelas . Kelas ini digunakan untuk mengevaluasi model pembelajaran mesin, dan mengikat model ke perangkat yang kemudian menjalankan dan mengevaluasi model. Anda dapat memilih perangkat saat membuat sesi untuk menjalankan model pada perangkat tertentu dari komputer Anda. Perangkat default adalah CPU.
Catatan
Untuk mempelajari selengkapnya tentang cara memilih perangkat, tinjau dokumentasi Buat sesi .
Mengikat input dan output model:
Untuk mengikat input dan output, Anda menggunakan LearningModelBinding
kelas . Model pembelajaran mesin memiliki fitur input dan output, yang meneruskan informasi ke dalam dan ke luar model. Ketahuilah bahwa fitur yang diperlukan harus didukung oleh API Window ML. Kelas LearningModelBinding
diterapkan pada nilai yang LearningModelSession
mengikat ke fitur input dan output bernama.
Implementasi pengikatan secara otomatis dihasilkan oleh mlgen, sehingga Anda tidak perlu mengurusnya. Pengikatan diimplementasikan dengan memanggil metode kelas yang LearningModelBinding
telah ditentukan sebelumnya. Dalam kasus kami, metode ini menggunakan Bind
metode untuk mengikat nilai ke jenis fitur bernama.
Mengevaluasi model:
Setelah Membuat sesi untuk mengikat model dan nilai terikat ke input dan output model, Anda dapat mengevaluasi input model dan mendapatkan prediksinya. Untuk menjalankan eksekusi model, Anda harus memanggil salah satu metode evaluasi yang telah ditentukan sebelumnya pada Pembelajaran ModelSession. Dalam kasus kami, kami akan menggunakan metode .EvaluateAsync
Mirip CreateFromStreamAsync
dengan , EvaluateAsync
metode ini juga secara otomatis dihasilkan oleh WinML Code Generator, sehingga Anda tidak perlu menerapkan metode ini. Anda dapat meninjau metode ini dalam ImageClassifier.cs
file.
Metode ini EvaluateAsync
akan mengevaluasi model pembelajaran mesin secara asinkron menggunakan nilai fitur yang sudah terikat dalam pengikatan. Ini akan membuat sesi dengan LearningModelSession
, mengikat input dan output dengan LearningModelBinding
, menjalankan evaluasi model, dan mendapatkan fitur output model menggunakan LearningModelEvaluationResult
kelas .
Catatan
Untuk mempelajari tentang metode evaluasi lain untuk menjalankan model, silakan periksa metode mana yang dapat diimplementasikan pada Pembelajaran ModelSession dengan meninjau dokumentasi Kelas Pembelajaran ModelSession.
- Tambahkan metode berikut ke file kode Anda
MainPage.xaml.cs
di dalam kelas MainPage untuk membuat sesi, mengikat, dan mengevaluasi model.
// A method to evaluate the model
private async Task evaluate()
{
results = await modelGen.EvaluateAsync(image);
}
Mengekstrak dan menampilkan hasilnya
Anda sekarang perlu mengekstrak output model dan menampilkan hasil yang tepat, yang akan Anda lakukan dengan menerapkan extractResult
metode dan displayResult
. Anda harus menemukan probabilitas tertinggi untuk mengembalikan label yang benar.
- Tambahkan metode ke
extractResult
file kode AndaMainPage.xaml.cs
diMainPage
dalam kelas .
// A method to extract output from the model
private void extractResult()
{
// Retrieve the results of evaluation
var mResult = results.modelOutput as TensorFloat;
// convert the result to vector format
var resultVector = mResult.GetAsVectorView();
probability = 0;
int index = 0;
// find the maximum probability
for(int i=0; i<resultVector.Count; i++)
{
var elementProbability=resultVector[i];
if (elementProbability > probability)
{
index = i;
}
}
label = ((Labels)index).ToString();
}
- Tambahkan metode ke
displayResult
file kode AndaMainPage.xaml.cs
diMainPage
dalam kelas .
private async Task displayResult()
{
displayOutput.Text = label;
}
Itu saja! Anda telah berhasil membuat aplikasi pembelajaran mesin Windows dengan GUI dasar untuk menguji model klasifikasi kami. Langkah selanjutnya adalah meluncurkan aplikasi dan menjalankannya secara lokal di perangkat Windows Anda.
Luncurkan aplikasi tersebut
Setelah Anda menyelesaikan antarmuka aplikasi, menambahkan model, dan menghasilkan kode Windows ML, Anda dapat menguji aplikasi!
Aktifkan mode pengembang dan uji aplikasi Anda dari Visual Studio. Pastikan menu dropdown di toolbar atas diatur ke Debug
. Ubah Platform Solusi ke x64 untuk menjalankan proyek di komputer lokal Anda jika perangkat Anda 64-bit, atau x86 jika 32-bit.
Model kami dilatih untuk mengklasifikasikan gambar berikut: pesawat, mobil, burung, kucing, rusa, anjing, katak, kuda, kapal, truk. Untuk menguji aplikasi kami, Anda akan menggunakan gambar mobil Lego yang dibangun untuk proyek ini. Mari kita lihat bagaimana aplikasi kita mengklasifikasikan konten gambar.
Simpan gambar ini di perangkat lokal Anda untuk menguji aplikasi. Ubah format gambar menjadi
.jpg
jika diperlukan. Anda juga dapat menggunakan gambar lain yang relevan dari perangkat lokal Anda dalam format .jpg atau .png.Untuk menjalankan proyek, pilih tombol
Start Debugging
pada toolbar, atau tekanF5
.Saat aplikasi dimulai, tekan Pilih Gambar dan pilih gambar dari perangkat lokal Anda.
Hasilnya akan langsung muncul di layar. Seperti yang Anda lihat, aplikasi Windows ML kami berhasil mengklasifikasikan gambar sebagai mobil.
Ringkasan
Anda baru saja membuat aplikasi Windows Pembelajaran Mesin pertama Anda, dari pembuatan model hingga keberhasilan eksekusi.
Sumber Tambahan
Untuk mempelajari selengkapnya tentang topik yang disebutkan dalam tutorial ini, kunjungi sumber daya berikut:
- Alat Windows ML: Pelajari lebih lanjut alat seperti Dasbor Windows ML, WinMLRunner, dan generator kode ML Windows mglen .
- Model ONNX: Pelajari selengkapnya tentang format ONNX.
- Performa dan memori Windows ML: Pelajari selengkapnya cara mengelola performa aplikasi dengan Windows ML.
- Referensi WINDOWS Pembelajaran Mesin API: Pelajari selengkapnya tentang tiga area API Windows ML.