Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I föregående del av den här självstudien lärde du dig hur du skapar och exporterar en modell i ONNX-format. Nu när du har den modellen kan du bädda in den i ett Windows-program och köra den lokalt på en enhet genom att anropa WinML-API:er.
När vi är klara har du en fungerande WinML UWP-app för bildklassificerare (C#).
Om exempelappen
Med hjälp av vår modell skapar vi en app som kan klassificera bilder av mat. Med den kan du välja en bild från din lokala enhet och bearbeta den med en lokalt lagrad ONNX-klassificeringsmodell som du skapade och tränade i föregående del. Taggarna som returneras visas bredvid bilden samt klassificeringens sannolikhet för konfidens.
Om du har följt den här självstudien hittills bör du redan ha de nödvändiga förutsättningarna för apputveckling på plats. Om du behöver en uppdatering kan du läsa den första delen av den här självstudien.
Anmärkning
Om du föredrar att ladda ned den fullständiga exempelkoden kan du klona lösningsfilen. Klona förvaret, gå till det här exemplet och öppna sedan ImageClassifierAppUWP.sln-filen med Visual Studio. Sedan kan du gå vidare till steget [Starta programmet](#Launch the application).
Skapa en WinML UWP (C#)
Nedan visar vi hur du skapar din app och WinML-kod från grunden. Du får lära dig att:
- Läs in en maskininlärningsmodell.
- Läs in en bild i det format som krävs.
- Binda modellens indata och utdata.
- Utvärdera modellen och visa meningsfulla resultat.
Du använder också grundläggande XAML för att skapa ett enkelt GUI, så att du kan testa bildklassificeraren.
Skapa appen
- Öppna Visual Studio och välj
create a new project.
- I sökfältet skriver du
UWPoch väljerBlank APP (Universal Windowssedan ). Detta öppnar ett nytt C#-projekt för en enkelsidig UWP-app (Universal Windows Platform) som inte har några fördefinierade kontroller eller layout. VäljNextför att öppna ett konfigurationsfönster för projektet.
- I konfigurationsfönstret:
- Välj ett namn för projektet. Här använder vi ImageClassifierAppUWP.
- Välj platsen för projektet.
- Om du använder VS 2019, kontrollera att
Place solution and project in the same directoryär avmarkerad. - Om du använder VS 2017 kontrollerar du att
Create directory for solutionär markerad.
Tryck create för att skapa projektet. Det lägsta målversionsfönstret kan dyka upp. Kontrollera att din lägsta version är inställd på Windows 10 build 17763 eller senare.
Om du vill skapa en app och distribuera en modell med en WinML-app behöver du följande:
När projektet har skapats går du till projektmappen, öppnar mappen assets [....\ImageClassifierAppUWP\Assets] och kopierar din modell till den här platsen.
Ändra modellnamnet från
model.onnxtillclassifier.onnx. Detta gör saker och ting lite tydligare och anpassar det till tutorialens format.
Utforska din modell
Nu ska vi bekanta oss med strukturen i modellfilen.
Öppna modellfilen
classifier.onnxmed Netron.Tryck
Dataför att öppna modellegenskaperna.
Som du kan se kräver modellen ett 32-bitars Tensor-flyttalobjekt (flerdimensionell matris) som indata och returnerar två utdata: det första namnet classLabel är tensor med strängar och det andra namnet loss är en sekvens med sträng-till-flyttal-kartor som beskriver sannolikheten för varje märkt klassificering. Du behöver den här informationen för att kunna visa modellutdata i din Windows-app.
Utforska projektlösning
Nu ska vi utforska din projektlösning.
Visual Studio skapade automatiskt flera cs-code-filer i Solution Explorer.
MainPage.xaml innehåller XAML-koden för ditt GUI och MainPage.xaml.cs innehåller programkoden. Om du har skapat en UWP-app tidigare bör dessa filer vara mycket bekanta för dig.
Skapa program-GUI
Först ska vi skapa ett enkelt GUI för din app.
Dubbelklicka på
MainPage.xamlfilen. I den tomma appen är XAML-mallen för appens GUI tom, så vi måste lägga till några gränssnittsfunktioner.Lägg till koden nedan i huvudtexten i
MainPage.xaml.
<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="30,0,0,0"
Text="" Width="1471" />
<Button Name="ProbabilityResult"
Content="Probability is:"
Width="110"
Height="40"
IsEnabled="True"
HorizontalAlignment="Left"/>
<!--Display the Result-->
<TextBlock Name="displayProbability"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="30,0,0,0"
Text="" Width="1471" />
<TextBlock Name="space2" />
<!--Image preview -->
<Image Name="UIPreviewImage" Stretch="Uniform" MaxWidth="300" MaxHeight="300"/>
</StackPanel>
</Grid>
Kodgenerator för Windows Machine Learning
Windows Machine Learning Code Generator, eller mlgen, är ett Visual Studio-tillägg som hjälper dig att komma igång med WinML-API:er i UWP-appar. Den genererar mallkod när du lägger till en tränad ONNX-fil i UWP-projektet.
Windows Machine Learnings kodgenerator mlgen skapar ett gränssnitt (för C#, C++/WinRT och C++/CX) med omslutningsklasser som anropar Windows ML API åt dig. På så sätt kan du enkelt läsa in, binda och utvärdera en modell i projektet. Vi använder den i den här handledningen för att hantera många av dessa funktioner åt oss.
Kodgeneratorn är tillgänglig för Visual Studio 2017 och senare. Tänk på att mlgen i Windows 10 version 1903 och senare inte längre ingår i Windows 10 SDK, så du måste ladda ned och installera tillägget. Om du har följt den här handledningen från början har du redan hanterat det, men om du inte har gjort det borde du ladda ner VS 2019 eller VS 2017.
Anmärkning
Mer information om mlgen finns i mlgen-dokumentationen
Om du inte redan har gjort det installerar du mlgen.
Högerklicka på
Assetsmappen i Solution Explorer i Visual Studio och väljAdd > Existing Item.Gå till mappen assets i
ImageClassifierAppUWP [….\ImageClassifierAppUWP\Assets], leta reda på DEN ONNX-modell som du tidigare kopierade där och väljadd.När du har lagt till en ONNX-modell (namn: "klassificerare") i mappen assets i Solution Explorer i VS bör projektet nu ha två nya filer:
-
classifier.onnx– det här är din modell i ONNX-format. -
classifier.cs– Automatiskt genererad WinML-kodfil.
- För att se till att modellen byggs när du kompilerar vårt program väljer du
classifier.onnxfilen och väljerProperties. FörBuild Actionväljer duContent.
Nu ska vi utforska den nyligen genererade koden i filen classifier.cs.
Den genererade koden innehåller tre klasser:
-
classifierModel: Den här klassen innehåller två metoder för modellinstansiering och modellutvärdering. Det hjälper oss att skapa maskininlärningsmodellens representation, skapa en session på systemets standardenhet, binda specifika indata och utdata till modellen och utvärdera modellen asynkront. -
classifierInput: Den här klassen initierar de indatatyper som modellen förväntar sig. Modellindata beror på modellkraven för indata. I vårt fall förväntar sig indata en ImageFeatureValue, en klass som beskriver egenskaperna för den bild som används för att skicka till en modell. -
classifierOutput: Den här klassen initierar de typer som modellen ska mata ut. Modellutdata beror på hur den definieras av modellen. I vårt fall kommer utdata vara en sekvens av mappar (ordböcker) av typen Sträng och TensorFloat (Float32) som kallas loss.
Nu ska du använda dessa klasser för att läsa in, binda och utvärdera modellen i vårt projekt.
Läs in modellen och indata
Läs in modellen
Dubbelklicka på
MainPage.xaml.cskodfilen för att öppna programkoden.Ersätt "using"-uttrycken med följande för att få åtkomst till alla API:er som du behöver.
// Specify all the using statements which give us the access to all the APIs that you'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;
- Lägg till följande variabeldeklarationer efter användningsinstruktionerna i
MainPageklassen under namnområdetImageClassifierAppUWP.
// All the required variable declaration
private classifierModel modelGen;
private classifierInput input = new classifierModelInput();
private classifierOutput output;
private StorageFile selectedStorageFile;
private string result = "";
private float resultProbability = 0;
Resultatet ser ut så här.
// 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;
namespace ImageClassifierAppUWP
{
public sealed partial class MainPage : Page
{
// All the required fields declaration
private classifierModel modelGen;
private classifierInput input = new classifierInput();
private classifierOutput output;
private StorageFile selectedStorageFile;
private string result = "";
private float resultProbability = 0;
Nu ska du implementera LoadModel metoden. Metoden kommer att komma åt ONNX-modellen och lagra den i minnet. Sedan använder CreateFromStreamAsync du metoden för att instansiera modellen som ett LearningModel objekt. Klassen LearningModel representerar en tränad maskininlärningsmodell. När du har instansierat LearningModel är det det första objektet som du använder för att interagera med Windows ML.
Om du vill läsa in modellen kan du använda flera statiska metoder i LearningModel klassen. I det här fallet kommer du att använda CreateFromStreamAsync-metoden.
Metoden CreateFromStreamAsync skapades automatiskt med mlgen, så du behöver inte implementera den här metoden. Du kan granska den här metoden genom att dubbelklicka på filen classifier.cs som genereras av mlgen.
Mer information om LearningModel klassen finns i dokumentationen om LearningModel-klassen.
Mer information om ytterligare sätt att läsa in modellen finns i dokumentationen Läsa in en modell
- Lägg till en
loadModelmetod iMainPage.xaml.cskodfilen iMainPageklassen.
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/classifier.onnx"));
// Instantiate the model.
modelGen = await classifierModel.CreateFromStreamAsync(modelFile);
}
- Lägg nu till ett anrop till den nya metoden i konstruktorn för klassen.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
Resultatet ser ut så här.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
// A method to load a machine learning model.
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/classifier.onnx"));
// Instantiate the model.
modelGen = await classifierModel.CreateFromStreamAsync(modelFile);
}
Läs in avbildningen
- Vi måste definiera en klickhändelse för att initiera sekvensen med fyra metodanrop för modellkörning – konvertering, bindning och utvärdering, extrahering av utdata och visning av resultaten. Lägg till följande metod i
MainPage.xaml.cskodfilen iMainPageklassen.
// 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();
}
- Nu ska du implementera
getImage()metoden. Den här metoden väljer en indatabildfil och sparar den i minnet. Lägg till följande metod iMainPage.xaml.cskodfilen iMainPageklassen.
// 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;
}
Nu implementerar du en bildmetod Bind() för att hämta representationen av filen i bitmappens BGRA8-format.
- Lägg till implementeringen av metoden
convert()till kodfilen förMainPage.xaml.csi klassen MainPage. Konverteringsmetoden ger oss en representation av indatafilen i ett BGRA8-format.
// A method to convert and bind 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);
// bind the input image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
input.data = imageTensor;
}
catch (Exception e)
{
}
}
Resultatet av det arbete som utförs i det här avsnittet ser ut så här.
// 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, we begin the model execution.
// Bind the model input
await imageBind();
// Model evaluation
await evaluate();
// Extract the results
extractResult();
// Display the results
await displayResult();
}
// 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;
}
// A method to convert and bind 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);
// bind the input image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
input.data = imageTensor;
}
catch (Exception e)
{
}
}
Binda och utvärdera modellen
Därefter skapar du en session baserat på modellen, binder indata och utdata från sessionen och utvärderar modellen.
Skapa en session för att binda modellen:
Om du vill skapa en session använder LearningModelSession du klassen . Den här klassen används för att utvärdera maskininlärningsmodeller och binder modellen till en enhet som sedan kör och utvärderar modellen. Du kan välja en enhet när du skapar en session för att köra din modell på en specifik enhet på datorn. Standardenheten är processorn.
Anmärkning
Mer information om hur du väljer en enhet finns i dokumentationen skapa en session .
Bind modellindata och utdata:
Om du vill binda indata och utdata använder LearningModelBinding du klassen . En maskininlärningsmodell har indata- och utdatafunktioner som skickar information till och från modellen. Tänk på att nödvändiga funktioner måste stödjas av WINDOWS ML-API:er. Klassen LearningModelBinding tillämpas på en LearningModelSession för att binda värden till namngivna indata- och utdatafunktioner.
Implementeringen av bindningen genereras automatiskt av mlgen, så du behöver inte ta hand om den. Bindningen implementeras genom att anropa de fördefinierade metoderna för LearningModelBinding klassen. I vårt fall använder den Bind metoden för att binda ett värde till den namngivna funktionstypen.
Windows ML stöder för närvarande alla ONNX-funktionstyper som Tensors (flerdimensionella matriser), sekvenser (värdevektorer), Karta (värdepar med information) och Bilder (specifika format). Alla bilder visas i Windows ML i tensorformat. Tensorkonvertering är processen att omvandla en bild till en tensor och sker vid bindning.
Som tur är behöver du inte ta hand om tensoriseringskonvertering. Den ImageFeatureValue metod som du använde i föregående del tar hand om både konvertering och tensorisering, så bilderna matchar modellens nödvändiga bildformat.
Anmärkning
Mer information om hur du binder en LearningModel och om typer av funktioner som stöds av WinML finns i dokumentationen om bindning av en modell .
Utvärdera modellen:
När du har skapat en session för att binda modellen och avgränsade värden till en modells indata och utdata kan du utvärdera modellens indata och få dess förutsägelser. Om du vill köra modellen bör du anropa någon av de fördefinierade utvärderingsmetoderna i LearningModelSession. I vårt fall använder EvaluateAsync vi metoden.
CreateFromStreamAsync
EvaluateAsync På samma sätt genererades metoden också automatiskt av WinML Code Generator, så du behöver inte implementera den här metoden. Du kan granska den här metoden i classifier.cs filen.
Metoden EvaluateAsync utvärderar asynkront maskininlärningsmodellen med hjälp av de funktionsvärden som redan är bundna i bindningar. Den skapar en session med LearningModelSession, binder indata och utdata med LearningModelBinding, kör modellutvärderingen och hämtar utdatafunktionerna i modellen med hjälp av LearningModelEvaluationResult klassen .
Anmärkning
Om du vill veta mer om andra utvärderingsmetoder för att köra modellen kan du kontrollera vilka metoder som kan implementeras på LearningModelSession genom att läsa dokumentationen om LearningModelSession Class.
- Lägg till följande metod i
MainPage.xaml.cskodfilen i klassen MainPage för att skapa en session, binda och utvärdera modellen.
// A method to evaluate the model
private async Task evaluate()
{
output = await modelGen.EvaluateAsync(input);
}
Extrahera och visa resultatet
Nu måste du extrahera modellutdata och visa rätt resultat. Du gör det genom att implementera extractResult metoderna och displayResult .
Som du utforskade tidigare returnerar modellen två utdata: den första, namngiven classLabel, är en tensor av strängar och den andra, namngiven förlustvärde, är en sekvens av kartor från strängar till flyttal som beskriver sannolikheten för varje märkt klassificering. Så för att visa resultatet och sannolikheten behöver vi bara extrahera utdata från förlustutdata. Vi måste hitta den högsta sannolikheten för att returnera rätt resultat.
- Lägg till metoden
extractResultiMainPage.xaml.cskodfilen iMainPageklassen.
private void extractResult()
{
// A method to extract output (result and a probability) from the "loss" output of the model
var collection = output.loss;
float maxProbability = 0;
string keyOfMax = "";
foreach (var dictionary in collection)
{
foreach (var key in dictionary.Keys)
{
if (dictionary[key] > maxProbability)
{
maxProbability = dictionary[key];
keyOfMax = key;
}
}
}
result = keyOfMax;
resultProbability = maxProbability;
}
- Lägg till metoden
displayResultiMainPage.xaml.cskodfilen iMainPageklassen.
// A method to display the results
private async Task displayResult()
{
displayOutput.Text = result.ToString();
displayProbability.Text = resultProbability.ToString();
}
Resultatet av Bindning och Utvärdera och Extrahera och visa resultatdelarna i WinML-koden i vår app ser ut så här.
// A method to evaluate the model
private async Task evaluate()
{
output = await modelGen.EvaluateAsync(input);
}
// A method to extract output (string and a probability) from the "loss" output of the model
private void extractResult()
{
var collection = output.loss;
float maxProbability = 0;
string keyOfMax = "";
foreach (var dictionary in collection)
{
foreach (var key in dictionary.Keys)
{
if (dictionary[key] > maxProbability)
{
maxProbability = dictionary[key];
keyOfMax = key;
}
}
}
result = keyOfMax;
resultProbability = maxProbability;
}
// A method to display the results
private async Task displayResult()
{
displayOutput.Text = result.ToString();
displayProbability.Text = resultProbability.ToString();
}
Det var allt. Du har skapat Windows-maskininlärningsappen med ett grundläggande GUI för att testa vår klassificeringsmodell. Nästa steg är att starta programmet och köra det lokalt på din Windows-enhet.
Starta programmet
När du har slutfört programgränssnittet, lagt till modellen och genererat WinML-koden kan du testa programmet. Kontrollera att listrutorna i det övre verktygsfältet är inställda på Debug. Ändra Solution Platform till x64 för att köra projektet på din lokala maskin om enheten är 64-bitars, eller x86 om den är 32-bitars.
För att testa vår app använder du bilden nedan av frukter. Nu ska vi se hur vår app klassificerar innehållet i bilden.
Spara den här avbildningen på din lokala enhet för att testa appen. Ändra bildformatet till jpg om det behövs. Du kan också lägga till andra relevanta avbildningar från din lokala enhet i lämpligt format – .jpg, .png, .bmpeller .gif format.
Om du vill köra projektet trycker du
Start Debuggingpå knappen i verktygsfältet eller trycker påF5.När programmet startar trycker du på
Pick Imageoch väljer avbildningen från den lokala enheten.
Resultatet visas på skärmen direkt. Som du ser klassificerade vår WinML-app bilden som frukt eller grönsaker, med 99,9% förtroendeklassificering.
Sammanfattning
Du har precis gjort din första Windows Machine Learning-app, från att skapa modellen till att köra den framgångsrikt.
Ytterligare resurser
Mer information om ämnen som nämns i den här självstudien finns i följande resurser:
- Windows ML-verktyg: Läs mer om verktyg som Windows ML-instrumentpanelen, WinMLRunner och mglen Windows ML-kodgeneratorn.
- ONNX-modell: Läs mer om ONNX-formatet.
- Prestanda och minne för Windows ML: Läs mer om hur du hanterar appprestanda med Windows ML.
- Referens för Windows Machine Learning API: Läs mer om tre områden i Windows ML-API:er.