Aracılığıyla paylaş


Windows ML kılavuzu

Bu kısa öğretici, Windows'da ResNet-50 görüntü sınıflandırma modelini çalıştırmak için Windows ML'yi kullanma, model alma ve ön işleme adımlarını ayrıntılı olarak açıklar. Uygulama, iyileştirilmiş çıkarım performansı için yürütme sağlayıcılarının dinamik olarak seçilmesini içerir.

ResNet-50 modeli, görüntü sınıflandırması için tasarlanmış bir PyTorch modelidir.

Bu öğreticide, Hugging Face'ten ResNet-50 modelini edinecek ve AI Toolkit'i kullanarak QDQ ONNX biçimine dönüştüreceksiniz.

Ardından modeli yükleyip giriş tensorlarını hazırlayacak ve softmax uygulamak ve en iyi tahminleri almak için işlem sonrası adımlar da dahil olmak üzere Windows ML API'lerini kullanarak çıkarım çalıştıracaksınız.

Modeli alma ve ön işleme

ResNet-50'yi Sarılma Yüzü'nden (ML topluluğunun modeller, veri kümeleri ve uygulamalar üzerinde işbirliği yaptığı platform) edinebilirsiniz. AI Toolkit'i kullanarak ResNet-50'yi QDQ ONNX biçimine dönüştüreceksiniz (daha fazla bilgi için bkz. modelleri ONNX biçimine dönüştürme ).

Bu örnek kodun amacı, ağır işi yapmak için Windows ML çalışma zamanından yararlanmaktır.

Windows ML çalışma zamanı şunları yapacak:

  • Modeli yükleyin.
  • Model için tercih edilen IHV tarafından sağlanan yürütme sağlayıcısını (EP) dinamik olarak seçin ve isteğe bağlı olarak EP'sini Microsoft Store'dan indirin.
  • EP kullanarak modelde çıkarım çalıştırın.

API başvurusu için bkz. OrtSessionOptions ve ExecutionProviderCatalog sınıfı.

// 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 Windows ML to download and register Execution Providers
var catalog = Microsoft.Windows.AI.MachineLearning.ExecutionProviderCatalog.GetDefault();
Console.WriteLine("Ensuring and registering execution providers...");
await catalog.EnsureAndRegisterCertifiedAsync();

//Create Onnx session
Console.WriteLine("Creating session ...");
var sessionOptions = new SessionOptions();
// Set EP Selection Policy
sessionOptions.SetEpSelectionPolicy(ExecutionProviderDevicePolicy.MIN_OVERALL_POWER);

EP toplaması

Modeliniz EP için henüz derlenmemişse (cihaza bağlı olarak değişiklik gösterebilir), modelin önce bu EP'ye göre derlenmesi gerekir. Bu tek seferlik bir işlemdir. Aşağıdaki örnek kod, modeli ilk çalıştırmada derleyip yerel olarak depolayarak bu kodu işler. Kodun sonraki çalıştırmaları derlenmiş sürümü alır ve bunu çalıştırır; en iyi duruma getirilmiş hızlı çıkarımlar elde eder.

API başvurusu için bkz Ort::ModelCompilationOptions yapısı, Ort::Status yapısı ve 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;

Çıkarım sürecini çalıştırma

Giriş görüntüsü tensor veri biçimine dönüştürülür ve ardından üzerinde çıkarım gerçekleştirilir. Bu, ONNX Çalışma Zamanı kullanan tüm kodlar için tipik olsa da, bu örnekteki fark, doğrudan Windows ML aracılığıyla ONNX Çalışma Zamanı olmasıdır. Tek gereksinim koda eklemektir #include <winml/onnxruntime_cxx_api.h> .

Ayrıca bkz . VS Code için AI Toolkit ile modeli dönüştürme

API başvurusu için bkz. Ort::Session yapısı, Ort::MemoryInfo yapısı, Ort::Value yapısı, Ort::AllocatorWithDefaultOptions yapısı, Ort::RunOptions yapısı.

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);

Son işleme

Softmax işlevi döndürülen ham çıkışa uygulanır ve adları en yüksek beş olasılığa sahip eşlemek ve yazdırmak için etiket verileri kullanılır.

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("-------------------------------------------");
}

Çıktı

Aşağıda, beklenecek çıkış türüne bir örnek verilmişti.

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

Tam kod örnekleri

Tam kod örnekleri WindowsAppSDK-Samples GitHub deposunda bulunur. Bkz. WindowsML.