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.
Windows ML ondersteunt krachtige belasting en uitvoering van modelketens door het GPU-pad zorgvuldig te optimaliseren. Modelketens worden gedefinieerd door twee of meer modellen die opeenvolgend worden uitgevoerd, waarbij de uitvoer van één model de invoer wordt voor het volgende model in de keten.
Om uit te leggen hoe u modellen efficiënt kunt koppelen met Windows ML, gebruiken we een FNS-Candy Style Transfer ONNX-model als voorbeeld. U vindt dit type model in de map FNS-Candy Style Transfer in onze GitHub.
Stel dat we een keten willen uitvoeren die bestaat uit twee exemplaren van hetzelfde FNS-Candy model, hier mozaïek.onnx genoemd. De toepassingscode geeft een afbeelding door aan het eerste model in de keten, laat het de uitvoer berekenen en vervolgens die getransformeerde afbeelding doorgeven aan een ander exemplaar van FNS-Candy, waardoor een definitieve afbeelding wordt geproduceerd.
De volgende stappen laten zien hoe u dit kunt doen met Behulp van Windows ML.
Opmerking
In een echt woordscenario zou u waarschijnlijk twee verschillende modellen gebruiken, maar dit moet voldoende zijn om de concepten te illustreren.
- Laten we eerst het mozaïek.onnx-model laden, zodat we het kunnen gebruiken.
std::wstring filePath = L"path\\to\\mosaic.onnx";
LearningModel model = LearningModel::LoadFromFilePath(filePath);
string filePath = "path\\to\\mosaic.onnx";
LearningModel model = LearningModel.LoadFromFilePath(filePath);
- Laten we vervolgens twee identieke sessies maken op de standaard GPU van het apparaat met hetzelfde model als de invoerparameter.
LearningModelSession session1(model, LearningModelDevice(LearningModelDeviceKind::DirectX));
LearningModelSession session2(model, LearningModelDevice(LearningModelDeviceKind::DirectX));
LearningModelSession session1 =
new LearningModelSession(model, new LearningModelDevice(LearningModelDeviceKind.DirectX));
LearningModelSession session2 =
new LearningModelSession(model, new LearningModelDevice(LearningModelDeviceKind.DirectX));
Opmerking
Als u de prestatievoordelen van het koppelen wilt behalen, moet u identieke GPU-sessies maken voor al uw modellen. Als u dit niet doet, leidt dit tot extra gegevensverplaatsing van de GPU en naar de CPU, wat de prestaties zou verminderen.
- Met de volgende regels code worden bindingen gemaakt voor elke sessie:
LearningModelBinding binding1(session1);
LearningModelBinding binding2(session2);
LearningModelBinding binding1 = new LearningModelBinding(session1);
LearningModelBinding binding2 = new LearningModelBinding(session2);
- Vervolgens binden we een invoer voor ons eerste model. We plaatsen een afbeelding die zich in hetzelfde bestandspad bevindt als ons model. In dit voorbeeld wordt de afbeelding 'fish_720.png' genoemd.
//get the input descriptor
ILearningModelFeatureDescriptor input = model.InputFeatures().GetAt(0);
//load a SoftwareBitmap
hstring imagePath = L"path\\to\\fish_720.png";
// Get the image and bind it to the model's input
try
{
StorageFile file = StorageFile::GetFileFromPathAsync(imagePath).get();
IRandomAccessStream stream = file.OpenAsync(FileAccessMode::Read).get();
BitmapDecoder decoder = BitmapDecoder::CreateAsync(stream).get();
SoftwareBitmap softwareBitmap = decoder.GetSoftwareBitmapAsync().get();
VideoFrame videoFrame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
ImageFeatureValue image = ImageFeatureValue::CreateFromVideoFrame(videoFrame);
binding1.Bind(input.Name(), image);
}
catch (...)
{
printf("Failed to load/bind image\n");
}
//get the input descriptor
ILearningModelFeatureDescriptor input = model.InputFeatures[0];
//load a SoftwareBitmap
string imagePath = "path\\to\\fish_720.png";
// Get the image and bind it to the model's input
try
{
StorageFile file = await StorageFile.GetFileFromPathAsync(imagePath);
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
VideoFrame videoFrame = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
ImageFeatureValue image = ImageFeatureValue.CreateFromVideoFrame(videoFrame);
binding1.Bind(input.Name, image);
}
catch
{
Console.WriteLine("Failed to load/bind image");
}
- Om voor het volgende model in de keten de uitvoer van de evaluatie van het eerste model te kunnen gebruiken, moeten we een lege uitvoertenor maken en de uitvoer binden, zodat we een markering hebben om mee te koppelen:
//get the output descriptor
ILearningModelFeatureDescriptor output = model.OutputFeatures().GetAt(0);
//create an empty output tensor
std::vector<int64_t> shape = {1, 3, 720, 720};
TensorFloat outputValue = TensorFloat::Create(shape);
//bind the (empty) output
binding1.Bind(output.Name(), outputValue);
//get the output descriptor
ILearningModelFeatureDescriptor output = model.OutputFeatures[0];
//create an empty output tensor
List<long> shape = new List<long> { 1, 3, 720, 720 };
TensorFloat outputValue = TensorFloat.Create(shape);
//bind the (empty) output
binding1.Bind(output.Name, outputValue);
Opmerking
U moet het tensorFloat-gegevenstype gebruiken bij het binden van de uitvoer. Hierdoor voorkomt u dat de-tensorisatie plaatsvindt zodra de evaluatie voor het eerste model is voltooid, waardoor er ook geen extra GPU-wachtrijen worden gebruikt voor belasting- en bindbewerkingen voor het tweede model.
- Nu voeren we de evaluatie van het eerste model uit en binden we de uitvoer ervan aan de invoer van het volgende model:
//run session1 evaluation
session1.EvaluateAsync(binding1, L"");
//bind the output to the next model input
binding2.Bind(input.Name(), outputValue);
//run session2 evaluation
auto session2AsyncOp = session2.EvaluateAsync(binding2, L"");
//run session1 evaluation
await session1.EvaluateAsync(binding1, "");
//bind the output to the next model input
binding2.Bind(input.Name, outputValue);
//run session2 evaluation
LearningModelEvaluationResult results = await session2.EvaluateAsync(binding2, "");
- Ten slotte gaan we de uiteindelijke uitvoer ophalen die wordt geproduceerd nadat beide modellen zijn uitgevoerd met behulp van de volgende coderegel.
auto finalOutput = session2AsyncOp.get().Outputs().First().Current().Value();
var finalOutput = results.Outputs.First().Value;
Dat is het! Beide modellen kunnen nu opeenvolgend worden uitgevoerd door het meeste uit de beschikbare GPU-resources te halen.
Opmerking
Gebruik de volgende bronnen voor hulp bij Windows ML:
- Als u technische vragen over Windows ML wilt stellen of beantwoorden, gebruikt u de tag windows-machine learning op Stack Overflow.
- Als u een fout wilt melden, kunt u een ticket aanmaken op onze GitHub-pagina .