Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Anmärkning
För större funktioner kan PyTorch också användas med DirectML i Windows.
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 ska vi visa dig hur du bäddar in din exporterade modell i ett Windows-program och kör den lokalt på en enhet genom att anropa WinML-API:er.
När vi är klara har du en fungerande bildklassificeringsapp.
Om exempelappen
I det här steget i självstudien skapar du en app som kan klassificera bilder med hjälp av ML-modellen. Med det grundläggande användargränssnittet kan du välja en avbildning från din lokala enhet och använda den ONNX-klassificeringsmodell som du skapade och tränade i föregående del för att klassificera den. Taggarna som returneras av modellen visas sedan bredvid bilden.
Här går vi igenom den processen.
Anmärkning
Om du väljer att använda det fördefinierade kodexemplet kan du klona lösningsfilen. Klona förvaret, gå till det här exemplet och öppna filen classifierPyTorch.sln med Visual Studio. Hoppa till delen Starta programmet för att se den i användning.
Nedan visar vi hur du skapar din app och lägger till Windows ML-kod.
Skapa en Windows ML UWP (C#)
Om du vill skapa en fungerande Windows ML-app måste du göra följande:
- Läs in en maskininlärningsmodell.
- Läs in en bild i ett obligatoriskt format.
- Binda modellens indata och utdata.
- Utvärdera modellen och visa meningsfulla resultat.
Du måste också skapa ett grundläggande användargränssnitt eftersom det är svårt att skapa en tillfredsställande bildbaserad app på kommandoraden.
Öppna ett nytt projekt i Visual Studio
- Nu ska vi komma igång. Öppna Visual Studio och välj skapa ett nytt projekt.
- I sökfältet skriver du
UWPoch väljerBlank APP (Universal Windows)sedan . Då öppnas ett C#-projekt för en enkelsidig UWP-app (Universal Windows Platform) med fördefinierade kontroller eller layout. Väljnextför att öppna ett konfigurationsfönster för projektet.
- Gör följande i konfigurationsfönstret:
- Ge projektet ett namn. Här kallar vi det classifierPyTorch.
- Välj platsen för projektet.
- Om du använder VS2019 kontrollerar du att
Create directory for solutionär markerad. - Om du använder VS2017, se till att
Place solution and project in the same directoryär avmarkerad.
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, version 1809 (10.0; build 17763) eller senare.
- När projektet har skapats navigerar du till projektmappen, öppnar mappen
[….\classifierPyTorch \Assets]och kopierarImageClassifier.onnxfilen till den här platsen.
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, även kallad code-behind. 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.xamlkodfilen. 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
MainPage.xamloch ersätt taggarna<Grid>och</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>
Lägg till modellen i projektet med hjälp av Windows ML Code Generator (mlgen)
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. Vi rekommenderar att du använder Visual Studio. 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
classifierPyTorch [….\classifierPyTorch \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 i mappen assets i Solution Explorer i VS bör projektet nu ha två nya filer:
-
ImageClassifier.onnx– det här är din modell i ONNX-format. -
ImageClassifier.cs– Automatiskt genererad WinML-kodfil.
- För att se till att modellen byggs när du kompilerar vårt program väljer du
ImageClassifier.onnxfilen och väljerProperties. FörBuild Actionväljer duContent.
ONNX-filkod
Nu ska vi utforska en nygenererad kod i ImageClassifier.cs filen.
Den genererade koden innehåller tre klasser:
-
ImageClassifierModel: 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. -
ImageClassifierInput: Den här klassen initierar de indatatyper som modellen förväntar sig. Modellindata beror på modellkraven för indata. -
ImageClassifierOutput: Den här klassen initierar de typer som modellen ska mata ut. Modellutdata beror på hur den definieras av modellen.
I den här handledningen vill vi inte bekymra oss om tensorisering. Vi gör en liten ändring i ImageClassifierInput klassen för att ändra indatatypen och göra vårt liv enklare.
- Gör följande ändringar i
ImageClassifier.csfilen:
Ändra variabeln input från en TensorFloat till en ImageFeatureValue.
public sealed class ImageClassifierInput
{
public ImageFeatureValue input; // shape(-1,3,32,32)
}
Läs in modellen
Dubbelklicka på
MainPage.xaml.csfilen för att öppna koden bakom för appen.Ersätt "using"-instruktionerna genom att följa 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 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;
- Lägg till följande variabeldeklarationer i
MainPageklassen ovanförpublic MainPage()funktionen.
// 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
}
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.
Anmärkning
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 ett anrop till en
loadModelmetod i konstruktorn för huvudklassen.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
- Lägg till implementeringen av
loadModel-metoden iMainPage-klassen.
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);
}
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;
}
Därefter implementerar du en bildmetod Bind() för att hämta representationen av filen i bitmappens BGRA8-format. Men först skapar du en hjälpklass för att ändra storlek på avbildningen.
- För att skapa en hjälpfil, högerklicka på lösningsnamnet (
ClassifierPyTorch), välj sedanAdd a new item. I det öppna fönstret väljer duClassoch ger det ett namn. Här kallar vi detHelper.
- En ny klassfil visas i projektet. Öppna den här klassen och lägg till följande kod:
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;
}
}
}
Nu ska vi konvertera bilden till rätt format.
Klassen ImageClassifierInput initierar de indatatyper som modellen förväntar sig. I vårt fall konfigurerade vi vår kod för att förvänta oss en ImageFeatureValue.
Klassen ImageFeatureValue beskriver egenskaperna för den bild som används för att överföra till en modell. För att skapa en ImageFeatureValue använder du CreateFromVideoFrame-metoden. Mer detaljerad information om varför detta är fallet och hur dessa klasser och metoder fungerar finns i dokumentationen för Klassen ImageFeatureValue
Anmärkning
I den här självstudien använder vi ImageFeatureValue-klassen istället för en tensor. Om Window ML inte stöder modellens färgformat är detta inte ett alternativ. Ett exempel på hur du arbetar med bildkonverteringar och tensorization finns i Exemplet på anpassad tensorisering.
- 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 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)
{
}
}
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.
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 ImageClassifier.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ärdera metoder för att köra modellen kontrollerar du 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()
{
results = await modelGen.EvaluateAsync(image);
}
Extrahera och visa resultatet
Nu måste du extrahera modellutdata och visa rätt resultat, vilket du gör genom att implementera extractResult metoderna och displayResult . Du måste hitta den högsta sannolikheten för att returnera rätt etikett.
- Lägg till metoden
extractResultiMainPage.xaml.cskodfilen iMainPageklassen.
// 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();
}
- Lägg till metoden
displayResultiMainPage.xaml.cskodfilen iMainPageklassen.
private async Task displayResult()
{
displayOutput.Text = label;
}
Det var allt. Du har skapat Windows maskininlärningsapp 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 Windows ML-koden kan du testa programmet!
Aktivera utvecklarläge och testa ditt program från Visual Studio. Kontrollera att de nedrullningsbara menyerna i det övre verktygsfältet är inställda på Debug. Ändra Solution Platform till x64 för att köra projektet på den lokala datorn om enheten är 64-bitars eller x86 om den är 32-bitars.
Vår modell tränades för att klassificera följande bilder: plan, bil, fågel, katt, hjort, hund, groda, häst, skepp, lastbil. För att testa vår app använder du bilden av Lego-bilen som skapats för det här projektet. 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
.jpgom det behövs. Du kan också ladda upp eller välja alla andra relevanta bilder från din lokala enhet i .jpg- eller .png-formatet.Om du vill köra projektet väljer du
Start Debuggingknappen i verktygsfältet eller trycker påF5.När programmet startar trycker du på Välj bild och väljer bilden från den lokala enheten.
Resultatet visas på skärmen direkt. Som du ser har vår Windows ML-app klassificerat avbildningen som en bil.
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.