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.
In het vorige deel van deze zelfstudie hebt u geleerd hoe u een ML.NET model in ONNX-indeling bouwt en exporteert. Nu u dat model hebt, kunt u het insluiten in een Windows-toepassing en lokaal uitvoeren op een apparaat door WinML-API's aan te roepen.
Zodra we klaar zijn, hebt u een werkende Afbeeldingsclassificatie WinML UWP-app (C#).
Over de voorbeeld-app
Met behulp van ons model maken we een app waarmee afbeeldingen van voedsel kunnen worden geclassificeerd. Hiermee kunt u een afbeelding van uw lokale apparaat selecteren en verwerken door een lokaal opgeslagen CLASSIFICATIE ONNX-model dat u in het vorige deel hebt gemaakt en getraind. De geretourneerde tags worden naast de afbeelding weergegeven, evenals de betrouwbaarheidskans van de classificatie.
Als u deze zelfstudie tot nu toe hebt gevolgd, moet u al beschikken over de vereiste vereisten voor app-ontwikkeling. Als u een opfrisser nodig hebt, raadpleegt u het eerste deel van deze zelfstudie.
Opmerking
Als u liever de volledige voorbeeldcode downloadt, kunt u het oplossingsbestand klonen. Kloon de opslagplaats, navigeer naar dit voorbeeld en open het classifierMLNETModel.sln bestand met Visual Studio. Vervolgens kunt u doorgaan naar de stap [De toepassing starten](#Launch de toepassing).
Een WinML UWP (C#) maken
Hieronder ziet u hoe u uw app en WinML-code helemaal zelf kunt maken. U leert het volgende:
- Een machine learning-model laden.
- Laad een afbeelding in de vereiste indeling.
- Bind de invoer en uitvoer van het model.
- Evalueer het model en geef zinvolle resultaten weer.
U gebruikt ook basic XAML om een eenvoudige GUI te maken, zodat u de afbeeldingsclassificatie kunt testen.
De app maken
- Open Visual Studio en kies
create a new project.
- Typ
UWPen selecteerBlank APP (Universal Windowsvervolgens in de zoekbalk ). Hiermee opent u een nieuw C#-project voor een UWP-app (Universal Windows Platform) met één pagina die geen vooraf gedefinieerde besturingselementen of indeling heeft. SelecteerNextdeze optie om een configuratievenster voor het project te openen.
- In het configuratievenster:
- Kies een naam voor uw project. Hier gebruiken we classifierMLNETModel.
- Kies de locatie van uw project.
- Als u VS 2019 gebruikt, controleert u of
Place solution and project in the same directorydit selectievakje is uitgeschakeld. - Als u VS 2017 gebruikt, zorg ervoor dat
Create directory for solutionis aangevinkt.
Druk create om uw project te maken. Het venster met de minimale doelversie kan worden weergegeven. Zorg ervoor dat uw minimale versie is ingesteld op Windows 10 build 17763 of hoger.
Als u een app wilt maken en een model wilt implementeren met een WinML-app, hebt u het volgende nodig:
- Nadat het project is aangemaakt, gaat u naar de projectmap, opent u de map assets [....\\classifierMLNETModel\\Assets], en kopieert u uw
bestModel.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. 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.xamlbestand. In uw lege app is de XAML-sjabloon voor de GUI van uw app leeg, dus we moeten enkele UI-functies toevoegen.Vervang de code van
MainPage.xamldoor het volgende.
<Page
x:Class="classifierMLNETModel.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:classifierMLNETModel"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<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>
<!--Dispaly 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>
</Page>
Het model toevoegen aan het project met behulp van Windows Machine Learning Code Generator
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 zullen deze in de tutorial gebruiken om veel van de functies voor ons af te handelen.
Codegenerator is beschikbaar voor Visual Studio 2017 en hoger. 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, dan hebt u dit al gedaan. Zo niet, dan 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
ImageClassifierAppUWP [….\ImageClassifierAppUWP\Assets], zoek het ONNX-model dat u daar eerder hebt gekopieerd, en selecteeradd.Nadat u een ONNX-model (naam: 'classifier') hebt toegevoegd aan de map assets in Solution Explorer in VS, moet het project nu twee nieuwe bestanden hebben.
-
bestModel.onnx- dit is uw model in ONNX-indeling. -
bestModel.cs– automatisch gegenereerd WinML-codebestand.
- Als u ervoor wilt zorgen dat het model wordt gebouwd wanneer u onze toepassing compileert, selecteert u het
bestModel.onnxbestand en kiest uProperties. SelecteerBuild ActionvoorContent.
Laten we nu de zojuist gegenereerde code in het bestModel.cs bestand verkennen.
De gegenereerde code bevat drie klassen:
-
bestModelModel: 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. -
bestModelInput: Met deze klasse worden de invoertypen geïnitialiseerd die het model verwacht. De modelinvoer is afhankelijk van de modelvereisten voor invoergegevens. -
bestModelOutput: 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.
U gebruikt deze klassen nu om het model in ons project te laden, te binden en te evalueren.
Tensor-conversie
Wijzig de klasse van invoer TensorFloat naar ImageFeatureValue om tensorisatie te vergemakkelijken.
- Breng de volgende wijzigingen aan in het
bestModel.csbestand:
De code:
public sealed class bestModelInput
{
public TensorFloat input; // shape(-1,3,32,32)
}
Wordt:
public sealed class bestModelInput
{
public ImageFeatureValue input; // shape(-1,3,32,32)
}
Het model en de invoer laden
Het model laden
Dubbelklik op het
MainPage.xaml.cscodebestand om de toepassingscode te openen.Vervang de instructies 'using' door het volgende 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 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;
- Voeg de volgende variabeledeclaraties toe na de using-instructies in uw
MainPageklasse, onder de naamruimteclassifierMLNETModel.
// All the required fields declaration
private bestModelModel modelGen;
private bestModelInput image = new bestModelInput();
private bestModelOutput results;
private StorageFile selectedStorageFile;
private string label = "";
private float probability = 0;
private Helper helper = new Helper();
public enum Labels
{
desert,
soup,
vegetable_fruit,
}
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 LearningModel is geïnstantieerd, is het 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 bestModel.cs bestand dat is gegenereerd door mlgen.
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
- Laten we de hoofdmethode definiëren.
// The main page to initialize and execute the model.
public MainPage()
{
this.InitializeComponent();
loadModel();
}
- Voeg de implementatie van de
loadModelmethode toe aan uwMainPage.xaml.cscodebestand in deMainPageklasse.
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/bestModel.onnx"));
// Instantiate the model.
modelGen = await bestModelModel.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 het juiste formaat.
De bestModelInput klasse initialiseert de invoertypen die het model verwacht. In ons geval hebben we onze code geconfigureerd om een ImageFeatureValue te verwachten.
De ImageFeatureValue klasse beschrijft de eigenschappen van de afbeelding die wordt gebruikt om door te geven aan een model. Als u eenImageFeatureValue wilt 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 voor aangepaste tensorisatie voor een voorbeeld van het 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 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);
// Resize the image size to 224x224
inputImage=await helper.CropAndDisplayInputImageAsync(inputImage);
// Bind the model input with image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
image.input1 = 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 bestModel.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. U 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.
Laten we de onderstaande afbeelding van soep gebruiken om onze app te testen. 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 andere relevante afbeeldingen van uw lokale apparaat toevoegen 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
Pick Imageen selecteert u de afbeelding op uw lokale apparaat.
Het resultaat wordt direct op het scherm weergegeven. Zoals u ziet, heeft onze Windows ML-app de afbeelding geclassificeerd als een soep.
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.