microsoft / Windows-Machine-Learning

Samples and Tools for Windows ML.
https://docs.microsoft.com/en-us/windows/ai/
MIT License
1.03k stars 445 forks source link

Loading model - C++ memory error #265

Closed vuk119 closed 5 years ago

vuk119 commented 5 years ago

I'm submitting a…

Bug report (I searched for similar issues and did not find one)

Current behavior

I am trying to run a model created by Keras backed by Tensorflow using WindowsML. I followed this tutorial https://docs.microsoft.com/en-us/windows/ai/windows-ml/get-started-desktop and It worked fine. The thing is that when try to write my own model and when I include a pooling layer and save my model as .onnx I get error like this when I try to load it using WindowsML in C++.

Exception thrown at 0x76B83442 in test1.exe: Microsoft C++ exception: winrt::hresult_error at memory location 0x005BF2A4.

When I do not have pooling layer everything works fine!

Minimal reproduction of the problem with instructions

Code for generating model:

from tensorflow import keras
import keras2onnx
import onnxmltools

model=keras.Sequential([
    keras.layers.Conv2D(filters=64,kernel_size=[3,3],strides=2,activation='relu',padding='valid', name='conv1', input_shape=(104, 104,1)),
    # keras.layers.Conv2D(filters=64,kernel_size=[3,3],strides=2,activation='relu',padding='valid', name='conv2'),
    # keras.layers.MaxPool2D(pool_size=[2,2],strides=2,padding='valid',name='pool1'),
    keras.layers.Flatten(),
    keras.layers.Activation('relu'),
    keras.layers.Dense(units=1024,activation='relu',kernel_regularizer=keras.regularizers.l2(0)) ,
    keras.layers.Dense(units=512,activation='relu',kernel_regularizer=keras.regularizers.l2(0)) ,
    keras.layers.Dense(units=297, activation='softmax')
])

onnx_model = keras2onnx.convert_keras(model, 'Test')
# Save as protobuf
onnxmltools.utils.save_model(onnx_model, 'modelConv2.onnx')

Code for loading the model:

#include "pch.h"

using namespace winrt;
using namespace Windows::Foundation;

using namespace Windows::AI::MachineLearning;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Imaging;
using namespace Windows::Media;
using namespace Windows::Storage;

using namespace std;

// Global variables
hstring modelPath = L"D:\\WindowsML\\TestApp\\modelPool.onnx";
string deviceName = "default";
LearningModel model = nullptr;
LearningModelDeviceKind deviceKind = LearningModelDeviceKind::Default;

void LoadModel()
{
    // load the model
    printf("Loading modelfile '%ws' on the '%s' device\n", modelPath.c_str(), deviceName.c_str());
    DWORD ticks = GetTickCount();
    model = LearningModel::LoadFromFilePath(modelPath);
    ticks = GetTickCount() - ticks;
    printf("model file loaded in %d ticks\n", ticks);
}

int main()
{
    LoadModel();
}

Environment

Windows Build Number: 18362.239

App min and target version: both 17763

OS Version (Server, IoT Core, Desktop, etc): Desktop

Visual Studio

riaz commented 5 years ago

The onnx model has to be using opset 7 i.e onnx 1.2.1/1.2/1.2.2 model. You can go to https://github.com/onnx/models and try the models that mention opset 7 / or onnx 1.2.1 or onnx 1.2 they should be working.

riaz commented 5 years ago

Can you try to create your model using onnx_model = onnxmltools.convert_keras(model, target_opset=7) onnxmltools.utils.save_model(onnx_model, 'modelConv2.onnx')

In order to check if the opset saved was indeed 7, run the following. (Note: Target 17763 can only load onnx model based on opset 7)

opset_version = onnx_model.opset_import[0].version

ngeisler11 commented 5 years ago

As Riaz mentioned, you'll want to ensure you are using a supported opset in your model. If you are still seeing issues after trying the conversion steps that Riaz provided, please reactivate and provide any new information.