Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Important
Windows ML Çalışma Zamanı API'leri şu anda deneyseldir ve üretim ortamlarında kullanılmak üzere desteklenmemektedir. Bu API'leri deneyen uygulamalar Microsoft Store'da yayımlanmamalıdır.
Bu öğreticide, uygulamanızın modeli nasıl edineceğini veya paketleyeceğini belirtmeden standart Çalışma Zamanı API'sinin sırası gösterilir. Model, uygulamanızın okuyabileceği her yerde olabilir; LoadModelFromFile için mutlak veya göreli bir yol geçirin.
Aşağıdaki yardımcı, tek bir sabit şekilli FLOAT32 girişe sahip bir modeli kasıtlı olarak kabul eder. Bu, tensor ayırma kodunu Çalışma Zamanı API'sine odaklı tutar ve bir ürün sınırlaması değildir. Uygulamanız serbest boyutlar kullanıyorsa, her çalıştırma için somut tensor boyutları bağlayın; başka veri türleri kullanıyorsa eşleşen giriş depolama alanı oluşturun.
Başlamadan önce
Tamamlayın Windows ML Çalışma Zamanı API'si için C++ projesi ayarlama. Girdi sözleşmesini anladığınız bir ONNX modeline de ihtiyacınız vardır.
Model çalıştırma yardımcısı ekle
Projenize bu başlıkları ve RunModel yardımcısını ekleyin:
// Copyright (C) Microsoft Corporation. All rights reserved.
#include <Windows.h>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include <winrt/base.h>
#include <WinMLRuntime.h>
#pragma comment(lib, "windowsapp.lib")
void RunModel(std::wstring const& modelPath)
{
winrt::com_ptr<IWinMLRuntime> runtime;
winrt::check_hresult(WinMLCreateRuntime(
__uuidof(IWinMLRuntime),
runtime.put_void()));
winrt::com_ptr<IWinMLModel> model;
winrt::check_hresult(runtime->LoadModelFromFile(
modelPath.c_str(),
nullptr,
nullptr,
model.put()));
winrt::com_ptr<IWinMLExecutionTarget> target;
winrt::check_hresult(runtime->CreateCpuExecutionTarget(target.put()));
winrt::com_ptr<IWinMLPipelineBuilder> builder;
winrt::check_hresult(runtime->CreatePipelineBuilder(builder.put()));
winrt::com_ptr<IWinMLStage> stage;
winrt::check_hresult(builder->AddModelStage(
model.get(),
target.get(),
L"model",
stage.put()));
winrt::com_ptr<IWinMLPipeline> pipeline;
winrt::check_hresult(builder->Build(pipeline.put()));
winrt::com_ptr<IWinMLModelSchema> schema;
winrt::check_hresult(model->QueryInterface(
__uuidof(IWinMLModelSchema),
schema.put_void()));
WINML_TENSOR_SCHEMA_DESC inputSchema = {};
winrt::check_hresult(schema->GetInputTensorDesc(0, &inputSchema));
if (inputSchema.dataType != WINML_TENSOR_DATA_TYPE_FLOAT32 ||
(inputSchema.dimensionCount > 0 &&
inputSchema.dimensions == nullptr))
{
winrt::throw_hresult(E_INVALIDARG);
}
UINT64 elementCount = 1;
for (UINT32 i = 0; i < inputSchema.dimensionCount; ++i)
{
const UINT64 dimension = inputSchema.dimensions[i];
if (dimension == 0 ||
dimension == UINT64_MAX ||
elementCount > UINT64_MAX / dimension)
{
winrt::throw_hresult(E_INVALIDARG);
}
elementCount *= dimension;
}
if (elementCount > SIZE_MAX)
{
winrt::throw_hresult(E_BOUNDS);
}
std::vector<float> inputData(
static_cast<size_t>(elementCount),
0.5f);
WINML_TENSOR_DESC inputDesc = {};
inputDesc.dataType = inputSchema.dataType;
inputDesc.dimensionCount = inputSchema.dimensionCount;
inputDesc.dimensions = inputSchema.dimensions;
winrt::com_ptr<IWinMLRawTensorFactory> tensorFactory;
winrt::check_hresult(target->QueryInterface(
__uuidof(IWinMLRawTensorFactory),
tensorFactory.put_void()));
winrt::com_ptr<IWinMLTensor> inputTensor;
winrt::check_hresult(tensorFactory->CreateTensor(
&inputDesc,
inputData.data(),
inputData.size() * sizeof(float),
inputTensor.put()));
winrt::check_hresult(stage->BindInput(0, inputTensor.get()));
winrt::check_hresult(pipeline->Run());
winrt::com_ptr<IWinMLTensor> outputTensor;
winrt::check_hresult(stage->GetOutput(0, outputTensor.put()));
winrt::com_ptr<IWinMLTensorDataLock> outputLock;
winrt::check_hresult(outputTensor->Lock(
WINML_TENSOR_LOCK_MODE_READ,
WINML_TENSOR_LOCK_FLAG_NONE,
outputLock.put()));
BYTE* outputBytes = nullptr;
UINT64 outputSizeInBytes = 0;
winrt::check_hresult(outputLock->GetData(
&outputBytes,
&outputSizeInBytes));
(void)outputBytes;
std::wcout << L"Output bytes: " << outputSizeInBytes << L'\n';
}
Yürütme hedefini hem AddModelStage öğesine hem de tensor fabrikasına geçirerek model hazırlığı ve tensor yerleşimini aynı hedefte tutun.
Lock çıkış tensor'u için bir CPU erişim penceresi oluşturur. Gerekli eşlemeyi veya eşitlemeyi gerçekleştirir ve GetData tarafından döndürülen işaretçi yalnızca outputLock var olduğu sürece geçerli kalır.
Yardımcıyı arayın
RunModel öğesini model yolu ile çağırın. Örneğin, aşağıdaki wmain komut satırındaki yolu kabul eder:
int wmain(int argc, wchar_t** argv)
{
if (argc != 2)
{
std::wcerr << L"Usage: RuntimeApp.exe <model-path>\n";
return 1;
}
RunModel(argv[1]);
return 0;
}
Uygulamayı derleme ve çalıştırma:
.\x64\Release\RuntimeApp.exe C:\models\model.onnx
Yolun yerine modelinizi koyun. Döndürülen tensörü modelin çıkış şemasına göre yorumla; sınıflandırma etiketleri, belirteç örnekleme, görüntü ön işleme ve modele özgü diğer davranışlar uygulamanıza aittir.