Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Opmerking
Voor meer functionaliteit kan PyTorch ook worden gebruikt met DirectML in Windows.
In het vorige deel van deze zelfstudie hebt u geleerd hoe u een model in ONNX-indeling bouwt en exporteert. Nu laten we u zien hoe u uw geëxporteerde model insluit in een Windows-toepassing en het lokaal uitvoert op een apparaat door WinML-API's aan te roepen.
Op het moment dat we klaar zijn, hebt u een werkende app voor afbeeldingsclassificatie.
Over de voorbeeld-app
In deze stap van de zelfstudie maakt u een app waarmee afbeeldingen kunnen worden geclassificeerd met behulp van uw ML-model. Met de basisgebruikersinterface kunt u een afbeelding van uw lokale apparaat selecteren en het CLASSIFICATIE ONNX-model gebruiken dat u in het vorige deel hebt gemaakt en getraind om deze te classificeren. De tags die door het model worden geretourneerd, worden vervolgens naast de afbeelding weergegeven.
Hier begeleiden we je door dat proces.
Opmerking
Als u ervoor kiest om het vooraf gedefinieerde codevoorbeeld te gebruiken, kunt u het oplossingsbestand klonen. Kloon de opslagplaats, navigeer naar dit voorbeeld en open het classifierPyTorch.sln-bestand met Visual Studio. Ga verder naar het onderdeel Toepassing starten van deze pagina om het in gebruik te zien.
Hieronder leert u hoe u uw app maakt en Windows ML-code toevoegt.
Een Windows ML UWP (C#) maken
Als u een werkende Windows ML-app wilt maken, moet u het volgende doen:
- Een machine learning-model laden.
- Laad een afbeelding in een vereiste indeling.
- Bind de invoer en uitvoer van het model.
- Evalueer het model en geef zinvolle resultaten weer.
U moet ook een eenvoudige gebruikersinterface maken, omdat het moeilijk is om een bevredigende app met afbeeldingen te maken in de opdrachtregelomgeving.
Een nieuw project openen in Visual Studio
- Laten we beginnen. Open Visual Studio en kies een nieuw project maken.
- Typ
UWPin de zoekbalk en selecteerBlank APP (Universal Windows). Hiermee opent u een C#-project voor een UWP-app (Universal Windows Platform) met één pagina met vooraf gedefinieerde besturingselementen of indelingen. Selecteernextdeze optie om een configuratievenster voor het project te openen.
- Ga als volgt te werk in het configuratievenster:
- Geef uw project een naam. Hier noemen we het classifierPyTorch.
- Kies de locatie van uw project.
- Als u VS2019 gebruikt, zorg er dan voor dat
Create directory for solutionis ingeschakeld. - Als u VS2017 gebruikt, controleert u of
Place solution and project in the same directorydit selectievakje is uitgeschakeld.
Druk create om uw project te maken. Het venster met de minimale doelversie kan opduiken. Zorg ervoor dat uw minimale versie is ingesteld op Windows 10, versie 1809 (10.0; build 17763) of hoger.
- Nadat het project is gemaakt, gaat u naar de projectmap, opent u het mapje
[….\classifierPyTorch \Assets]assets en kopieert u uwImageClassifier.onnxbestand naar deze locatie.
Projectoplossing verkennen
Laten we uw projectoplossing verkennen.
Visual Studio heeft automatisch verschillende cs-code-bestanden gemaakt in Solution Explorer.
MainPage.xaml bevat de XAML-code voor uw GUI en MainPage.xaml.cs bevat uw toepassingscode, ook wel de code-behind genoemd. Als u eerder een UWP-app hebt gemaakt, moeten deze bestanden u goed kennen.
De toepassings-GUI maken
Laten we eerst een eenvoudige GUI voor uw app maken.
Dubbelklik op het
MainPage.xamlcodebestand. In uw lege app is de XAML-sjabloon voor de GUI van uw app leeg, dus we moeten enkele UI-functies toevoegen.Voeg de onderstaande code toe aan
MainPage.xaml, ter vervanging van de<Grid>- en</Grid>-tags.
<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>
Voeg het model toe aan het project met behulp van Windows ML Code Generator (mlgen)
Windows Machine Learning Code Generator of mlgen is een Visual Studio-extensie om u te helpen aan de slag te gaan met WinML-API's in UWP-apps. Er wordt sjablooncode gegenereerd wanneer u een getraind ONNX-bestand toevoegt aan het UWP-project.
De codegenerator mlgen van Windows Machine Learning maakt een interface (voor C#, C++/WinRT en C++/CX) met wrapperklassen die de Windows ML-API voor u aanroepen. Hierdoor kunt u eenvoudig een model in uw project laden, binden en evalueren. We gebruiken het in deze handleiding om veel van die functies voor ons af te handelen.
Codegenerator is beschikbaar voor Visual Studio 2017 en hoger. We raden u aan Visual Studio te gebruiken. Houd er rekening mee dat mlgen in Windows 10, versie 1903 en hoger niet meer is opgenomen in de Windows 10 SDK, dus u moet de extensie downloaden en installeren. Als u deze zelfstudie vanaf de inleiding hebt gevolgd, hebt u dit al afgehandeld, maar als dat niet het geval is, moet u downloaden voor VS 2019 of VS 2017.
Opmerking
Raadpleeg de mlgen-documentatie voor meer informatie over mlgen
Als u dat nog niet hebt gedaan, installeert u mlgen.
Klik met de rechtermuisknop op de
Assetsmap in Solution Explorer in Visual Studio en selecteerAdd > Existing Item.Navigeer naar de map assets binnen
classifierPyTorch [….\classifierPyTorch \Assets], zoek het ONNX-model dat u daar eerder hebt gekopieerd en selecteeradd.Nadat u een ONNX-model hebt toegevoegd aan de map assets in Solution Explorer in VS, moet het project nu twee nieuwe bestanden hebben:
-
ImageClassifier.onnx- dit is uw model in ONNX-indeling. -
ImageClassifier.cs– automatisch gegenereerd WinML-codebestand.
- Als u ervoor wilt zorgen dat het model wordt gebouwd wanneer u onze toepassing compileert, selecteert u het
ImageClassifier.onnxbestand en kiest uProperties. SelecteerBuild ActionvoorContent.
ONNX-bestandscode
Laten we nu een nieuw gegenereerde code in het ImageClassifier.cs bestand verkennen.
De gegenereerde code bevat drie klassen:
-
ImageClassifierModel: Deze klasse bevat twee methoden voor modelinstantie en modelevaluatie. Het helpt ons om de weergave van het machine learning-model te maken, een sessie te maken op het standaardapparaat van het systeem, de specifieke invoer en uitvoer aan het model te binden en het model asynchroon te evalueren. -
ImageClassifierInput: Met deze klasse worden de invoertypen geïnitialiseerd die het model verwacht. De modelinvoer is afhankelijk van de modelvereisten voor invoergegevens. -
ImageClassifierOutput: Met deze klasse worden de typen geïnitialiseerd die door het model worden uitgevoerd. De modeluitvoer is afhankelijk van hoe het wordt gedefinieerd door het model.
In deze tutorial willen we ons niet bezighouden met tensorisatie. We brengen een kleine wijziging aan in de ImageClassifierInput klasse, om het invoergegevenstype te wijzigen en ons leven gemakkelijker te maken.
- Breng de volgende wijzigingen aan in het
ImageClassifier.csbestand:
Wijzig de input variabele van een TensorFloat in een ImageFeatureValue.
public sealed class ImageClassifierInput
{
public ImageFeatureValue input; // shape(-1,3,32,32)
}
Het model laden
Dubbelklik op het
MainPage.xaml.csbestand om de code achter de app te openen.Vervang de instructies 'using' door het volgende te volgen om toegang te krijgen tot alle API's die u nodig hebt:
// 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;
- Voeg de volgende variabeledeclaraties toe binnen uw
MainPageklasse, boven depublic MainPage()functie.
// 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 gaat u de LoadModel methode implementeren. De methode opent het ONNX-model en slaat het op in het geheugen. Vervolgens gebruikt u de CreateFromStreamAsync methode om het model te instantiëren als een LearningModel object. De LearningModel klasse vertegenwoordigt een getraind machine learning-model. Zodra er een instantie is gemaakt, is het LearningModel het eerste object dat u gebruikt om te communiceren met Windows ML.
Als u het model wilt laden, kunt u verschillende statische methoden in de LearningModel klasse gebruiken. In dit geval gebruikt u de CreateFromStreamAsync methode.
De CreateFromStreamAsync methode is automatisch gemaakt met mlgen, dus u hoeft deze methode niet te implementeren. U kunt deze methode controleren door te dubbelklikken op het classifier.cs bestand dat is gegenereerd door mlgen.
Opmerking
Raadpleeg de LearningModel voor meer informatie over de klas. Raadpleeg de documentatie over een model laden voor meer informatie over aanvullende manieren om het model te laden
- Voeg een aanroep van een
loadModel-methode toe aan de constructor van de hoofdklasse.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
- Voeg de implementatie van de
loadModelmethode toe, binnen dieMainPageklasse.
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);
}
De afbeelding laden
- We moeten een klik-gebeurtenis definiëren om de reeks vier methode-aanroepen voor modeluitvoering te initiëren: conversie, binding en evaluatie, uitvoerextractie en weergave van de resultaten. Voeg de volgende methode toe aan uw
MainPage.xaml.cscodebestand in deMainPageklasse.
// 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 gaat u de
getImage()methode implementeren. Met deze methode selecteert u een invoerafbeeldingsbestand en slaat u het op in het geheugen. Voeg de volgende methode toe aan uwMainPage.xaml.cscodebestand in deMainPageklasse.
// 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;
}
Vervolgens implementeert u een afbeeldingsmethode Bind() om de weergave van het bestand in de bitmap BGRA8-indeling op te halen. Maar eerst maakt u een helperklasse om het formaat van de afbeelding te wijzigen.
- Als u een helperbestand wilt maken, klikt u met de rechtermuisknop op de naam van de oplossing (
ClassifierPyTorch) en kiest uAdd a new item. SelecteerClassen geef deze een naam op in het geopende venster. Hier noemen we hetHelper.
- Er wordt een nieuw klassebestand weergegeven in uw project. Open deze klasse en voeg de volgende code toe:
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 gaan we de afbeelding omzetten naar de juiste indeling.
De ImageClassifierInput klasse initialiseert de invoertypen die het model verwacht. In ons geval hebben we onze code zo ingesteld dat deze een ImageFeatureValue verwacht.
De ImageFeatureValue klasse beschrijft de eigenschappen van de afbeelding die wordt gebruikt om door te geven aan een model. Als u een ImageFeatureValuewilt maken, gebruikt u de CreateFromVideoFrame methode. Zie de documentatie van de klasse ImageFeatureValue voor meer specifieke informatie over waarom dit het geval is en hoe deze klassen en methoden werken
Opmerking
In deze zelfstudie gebruiken we de ImageFeatureValue klasse in plaats van een tensor. Als Window ML de kleurindeling van uw model niet ondersteunt, is dit geen optie. Zie het voorbeeld van aangepaste tensorisatie voor een voorbeeld van hoe te werken met afbeeldingsconversies en tensorisatie.
- Voeg de implementatie van de
convert()methode toe aan uwMainPage.xaml.cscodebestand in de klasse MainPage. Met de conversiemethode krijgen we een weergave van het invoerbestand in een BGRA8-indeling.
// 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)
{
}
}
Het model binden en evalueren
Vervolgens maakt u een sessie op basis van het model, verbindt u de invoer en uitvoer van de sessie en evalueert u het model.
Maak een sessie om het model te binden:
Als u een sessie wilt maken, gebruikt u de LearningModelSession klasse. Deze klasse wordt gebruikt om machine learning-modellen te evalueren en verbindt het model met een apparaat dat vervolgens het model uitvoert en evalueert. U kunt een apparaat selecteren wanneer u een sessie maakt om uw model uit te voeren op een specifiek apparaat van uw computer. Het standaardapparaat is de CPU.
Opmerking
Raadpleeg de documentatie een sessie maken voor meer informatie over het kiezen van een apparaat.
Modelinvoer en -uitvoer binden:
Als u invoer en uitvoer wilt binden, gebruikt u de LearningModelBinding klasse. Een machine learning-model heeft invoer- en uitvoerfuncties, die informatie doorgeven aan en uit het model. Houd er rekening mee dat de vereiste functies moeten worden ondersteund door de Windows ML-API's. De LearningModelBinding klasse wordt toegepast op een LearningModelSession om waarden te binden aan benoemde invoer- en uitvoerfuncties.
De implementatie van de binding wordt automatisch gegenereerd door mlgen, dus u hoeft er niet voor te zorgen. De binding wordt geïmplementeerd door de vooraf gedefinieerde methoden van de LearningModelBinding klasse aan te roepen. In ons geval wordt de Bind methode gebruikt om een waarde te binden aan het benoemde functietype.
Evalueer het model:
Nadat u een sessie hebt gemaakt om het model en de gebonden waarden te binden aan de invoer en uitvoer van een model, kunt u de invoer van het model evalueren en de voorspellingen ervan ophalen. Als u de uitvoering van het model wilt uitvoeren, moet u een van de vooraf gedefinieerde evaluatiemethoden aanroepen op de LearningModelSession. In ons geval gebruiken we de EvaluateAsync methode.
CreateFromStreamAsyncNet als bij , is de EvaluateAsync methode ook automatisch gegenereerd door WinML Code Generator, dus u hoeft deze methode niet te implementeren. U kunt deze methode bekijken in het ImageClassifier.cs bestand.
De EvaluateAsync methode evalueert het machine learning-model asynchroon met behulp van de functiewaarden die al in bindingen zijn gebonden. Hiermee maakt u een sessie met LearningModelSession, verbindt u de invoer en uitvoer met LearningModelBinding, voert u de modelevaluatie uit en haalt u de uitvoerfuncties van het model op met behulp van de LearningModelEvaluationResult klasse.
Opmerking
Als u meer wilt weten over andere evaluatiemethoden om het model uit te voeren, controleert u welke methoden op de LearningModelSession-klasse kunnen worden geïmplementeerd door de documentatie van de LearningModelSession-klasse te bekijken.
- Voeg de volgende methode toe aan uw
MainPage.xaml.cscodebestand in de Klasse MainPage om een sessie te maken, het model te binden en te evalueren.
// A method to evaluate the model
private async Task evaluate()
{
results = await modelGen.EvaluateAsync(image);
}
De resultaten extraheren en weergeven
U moet nu de modeluitvoer extraheren en het juiste resultaat weergeven, wat u doet door de extractResult en displayResult methoden te implementeren. Je moet de hoogste waarschijnlijkheid vinden om het juiste label terug te geven.
- Voeg de
extractResultmethode toe aan uwMainPage.xaml.cscodebestand in deMainPageklasse.
// 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();
}
- Voeg de
displayResultmethode toe aan uwMainPage.xaml.cscodebestand in deMainPageklasse.
private async Task displayResult()
{
displayOutput.Text = label;
}
Dat is het! U hebt de Windows Machine Learning-app gemaakt met een basis-GUI om ons classificatiemodel te testen. De volgende stap is het starten van de toepassing en het lokaal uitvoeren op uw Windows-apparaat.
De toepassing starten
Nadat u de toepassingsinterface hebt voltooid, het model hebt toegevoegd en de Windows ML-code hebt gegenereerd, kunt u de toepassing testen.
Schakel de ontwikkelaarsmodus in en test uw toepassing vanuit Visual Studio. Zorg ervoor dat de vervolgkeuzelijsten in de bovenste werkbalk zijn ingesteld op Debug. Wijzig het Solution Platform in x64 om het project uit te voeren op uw lokale computer als uw apparaat 64-bits is of x86 als het 32-bits is.
Ons model is getraind om de volgende afbeeldingen te classificeren: vliegtuig, auto, vogel, kat, herten, hond, kikker, paard, schip, vrachtwagen. Om onze app te testen, gebruikt u de afbeelding van de Lego auto die voor dit project is gebouwd. Laten we eens kijken hoe de app de inhoud van de afbeelding classificeert.
Sla deze afbeelding op uw lokale apparaat op om de app te testen. Wijzig de afbeeldingsindeling in
.jpgindien nodig. U kunt ook elke andere relevante afbeelding van uw lokale apparaat in een .jpg- of .png-indeling.Als u het project wilt uitvoeren, selecteert u de
Start Debuggingknop op de werkbalk of drukt u opF5.Wanneer de toepassing wordt gestart, drukt u op Afbeelding kiezen en selecteert u de afbeelding op uw lokale apparaat.
Het resultaat wordt direct op het scherm weergegeven. Zoals u kunt zien, heeft onze Windows ML-app de afbeelding geclassificeerd als een auto.
Samenvatting
U hebt zojuist uw eerste Windows Machine Learning-app gemaakt, van het maken van modellen tot een geslaagde uitvoering.
Aanvullende informatiebronnen
Ga naar de volgende bronnen voor meer informatie over onderwerpen die in deze zelfstudie worden genoemd:
- Windows ML-hulpprogramma's: meer informatie over hulpprogramma's zoals het Windows ML-dashboard, WinMLRunner en de mglen Windows ML-codegenerator.
- ONNX-model: meer informatie over de ONNX-indeling.
- Windows ML-prestaties en -geheugen: meer informatie over het beheren van app-prestaties met Windows ML.
- Naslaginformatie over de Windows Machine Learning-API: meer informatie over drie gebieden van Windows ML-API's.