Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieses kurze Lernprogramm führt Sie durch die Verwendung von Windows ML zum Ausführen des ResNet-50-Imageklassifizierungsmodells unter Windows, zum Detailieren von Modellerwerbs- und Vorverarbeitungsschritten. Die Implementierung umfasst die dynamische Auswahl von Ausführungsanbietern für eine optimierte Ableitungsleistung.
Das ResNet-50-Modell ist ein PyTorch-Modell, das für die Bildklassifizierung vorgesehen ist.
In diesem Lernprogramm erwerben Sie das ResNet-50-Modell von Hugging Face und konvertieren es mithilfe des AI Toolkits in das QDQ ONNX-Format.
Anschließend laden Sie das Modell, bereiten Eingabe-Tensoren vor und führen eine Ableitung mithilfe der Windows ML-APIs aus, einschließlich der Nachbearbeitungsschritte zum Anwenden von Softmax und Abrufen der wichtigsten Vorhersagen.
Abrufen des Modells und Vorverarbeitung
Sie können ResNet-50 von Hugging Face (der Plattform, auf der die ML-Community an Modellen, Datasets und Apps zusammenarbeitet) erwerben. Sie konvertieren ResNet-50 mithilfe des AI Toolkits in das QDQ ONNX-Format (weitere Informationen finden Sie unter Konvertieren von Modellen in das ONNX-Format ).
Ziel dieses Beispielcodes ist es, die Windows ML-Runtime zu nutzen, um die schwierigen Aufgaben zu erledigen.
Die Windows ML-Runtime wird Folgendes tun:
- Laden Sie das Modell.
- Wählen Sie dynamisch den bevorzugten vom IHV bereitgestellten Ausführungsanbieter (EP) für das Modell aus, und laden Sie das EP aus dem Microsoft Store bei Bedarf herunter.
- Führen Sie die Ableitung für das Modell mithilfe des EP aus.
Api-Referenz finden Sie unter OrtSessionOptions und Microsoft::Windows::AI::MachineLearning::Infrastructure class.
// Create a new instance of EnvironmentCreationOptions
EnvironmentCreationOptions envOptions = new()
{
logId = "ResnetDemo",
logLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_ERROR
};
// Pass the options by reference to CreateInstanceWithOptions
OrtEnv ortEnv = OrtEnv.CreateInstanceWithOptions(ref envOptions);
// Use WinML to download and register Execution Providers
Microsoft.Windows.AI.MachineLearning.Infrastructure infrastructure = new();
Console.WriteLine("Ensure EPs are downloaded ...");
await infrastructure.DownloadPackagesAsync();
await infrastructure.RegisterExecutionProviderLibrariesAsync();
//Create Onnx session
Console.WriteLine("Creating session ...");
var sessionOptions = new SessionOptions();
// Set EP Selection Policy
sessionOptions.SetEpSelectionPolicy(ExecutionProviderDevicePolicy.MIN_OVERALL_POWER);
EP-Kompilation
Wenn Ihr Modell noch nicht für das EP kompiliert ist (was je nach Gerät variieren kann), muss das Modell zuerst gegen dieses EP kompiliert werden. Dies ist ein einmaliger Prozess. Der folgende Beispielcode behandelt es, indem das Modell bei der ersten Ausführung kompiliert und dann lokal gespeichert wird. Nachfolgende Ausführungen des Codes übernehmen die kompilierte Version und führen diese aus, was zu optimierten, schnellen Inferenzprozessen führt.
Api-Referenz finden Sie unter Ort::ModelCompilationOptions-Struktur, Ort::Status-Struktur und Ort::CompileModel.
// Prepare paths
string executableFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)!;
string labelsPath = Path.Combine(executableFolder, "ResNet50Labels.txt");
string imagePath = Path.Combine(executableFolder, "dog.jpg");
// TODO: Please use AITK Model Conversion tool to download and convert Resnet, and paste the converted path here
string modelPath = @"";
string compiledModelPath = @"";
// Compile the model if not already compiled
bool isCompiled = File.Exists(compiledModelPath);
if (!isCompiled)
{
Console.WriteLine("No compiled model found. Compiling model ...");
using (var compileOptions = new OrtModelCompilationOptions(sessionOptions))
{
compileOptions.SetInputModelPath(modelPath);
compileOptions.SetOutputModelPath(compiledModelPath);
compileOptions.CompileModel();
isCompiled = File.Exists(compiledModelPath);
if (isCompiled)
{
Console.WriteLine("Model compiled successfully!");
}
else
{
Console.WriteLine("Failed to compile the model. Will use original model.");
}
}
}
else
{
Console.WriteLine("Found precompiled model.");
}
var modelPathToUse = isCompiled ? compiledModelPath : modelPath;
Ausführen der Ableitung
Das Eingabebild wird in das Tensor-Datenformat konvertiert und anschließend wird die Inferenz darauf ausgeführt. Dies ist zwar typisch für jeden Code, der die ONNX Runtime verwendet, aber in diesem Fall besteht der Unterschied darin, dass es sich um eine ONNX Runtime direkt durch Windows ML handelt. Die einzige Anforderung ist das Hinzufügen #include <win_onnxruntime_cxx_api.h>
zum Code.
Siehe auch "Konvertieren eines Modells mit AI Toolkit für VS Code"
Api-Referenz finden Sie unter Ort::Session struct, Ort::MemoryInfo struct, Ort::Value struct, Ort::AllocatorWithDefaultOptions struct, Ort::RunOptions struct.
using var session = new InferenceSession(modelPathToUse, sessionOptions);
Console.WriteLine("Preparing input ...");
// Load and preprocess image
var input = await PreprocessImageAsync(await LoadImageFileAsync(imagePath));
// Prepare input tensor
var inputName = session.InputMetadata.First().Key;
var inputTensor = new DenseTensor<float>(
input.ToArray(), // Use the DenseTensor<float> directly
new[] { 1, 3, 224, 224 }, // Shape of the tensor
false // isReversedStride should be explicitly set to false
);
// Bind inputs and run inference
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor(inputName, inputTensor)
};
Console.WriteLine("Running inference ...");
var results = session.Run(inputs);
for (int i = 0; i < 40; i++)
{
results = session.Run(inputs);
}
// Extract output tensor
var outputName = session.OutputMetadata.First().Key;
var resultTensor = results.First(r => r.Name == outputName).AsEnumerable<float>().ToArray();
// Load labels and print results
var labels = LoadLabels(labelsPath);
PrintResults(labels, resultTensor);
Nachbearbeitung
Die Softmax-Funktion wird auf die zurückgegebene Rohausgabe angewendet, und Etikettendaten werden verwendet, um die Namen mit den fünf höchsten Wahrscheinlichkeiten zuzuordnen und zu drucken.
private static void PrintResults(IList<string> labels, IReadOnlyList<float> results)
{
// Apply softmax to the results
float maxLogit = results.Max();
var expScores = results.Select(r => MathF.Exp(r - maxLogit)).ToList(); // stability with maxLogit
float sumExp = expScores.Sum();
var softmaxResults = expScores.Select(e => e / sumExp).ToList();
// Get top 5 results
IEnumerable<(int Index, float Confidence)> topResults = softmaxResults
.Select((value, index) => (Index: index, Confidence: value))
.OrderByDescending(x => x.Confidence)
.Take(5);
// Display results
Console.WriteLine("Top Predictions:");
Console.WriteLine("-------------------------------------------");
Console.WriteLine("{0,-32} {1,10}", "Label", "Confidence");
Console.WriteLine("-------------------------------------------");
foreach (var result in topResults)
{
Console.WriteLine("{0,-32} {1,10:P2}", labels[result.Index], result.Confidence);
}
Console.WriteLine("-------------------------------------------");
}
Ausgabe
Hier ist ein Beispiel für die Art von Ausgabe, die zu erwarten ist.
285, Egyptian cat with confidence of 0.904274
281, tabby with confidence of 0.0620204
282, tiger cat with confidence of 0.0223081
287, lynx with confidence of 0.00119624
761, remote control with confidence of 0.000487919
Vollständige Codebeispiele
Die vollständigen Codebeispiele sind hier im GitHub-Repository verfügbar.