onnx/sklearn-onnx

Problem with Classifier models to onnx format

Opened this issue · 3 comments

Background

I am trying to convert a python sklearn classifier model to onnx format to use in C#. I have made multiple different dev/test environments using windows and Mac, also used multiple different classifier models from logistic, random forest, and decision tree. Every time I use a trained sklearn2onnx model in C# I get the below error. Regression models trained on the same data (with a different Y value of course) work just fine in C#, it is only classifier models that do not work. I am not sure if this has to do something with the conversion or how C# onnxruntime is interpreting the classifier models. Any kind of help would be appreciated.

error

Code

The simple source code that I used to recreate this error over and over is below. I have tried installing different versions and inspecting the models on net for anything looking out of the ordinary.

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnx

iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = RandomForestClassifier(n_estimators=10, random_state=42)
model.fit(X_train, y_train)

accuracy = model.score(X_test, y_test)
print(f"Model Accuracy: {accuracy * 100:.2f}%")

initial_type = [('float_input', FloatTensorType([None, X.shape[1]]))]

onnx_model = convert_sklearn(model, initial_types=initial_type, target_opset=12, options={id(model): {'zipmap': False}})
onnx_model_path = "iris_classifier_new.onnx"
with open(onnx_model_path, "wb") as f:
    f.write(onnx_model.SerializeToString())

print(f"ONNX model saved to {onnx_model_path}")
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
class Program
{
    static string ONNX_MODEL_PATH = "iris_classifier_new.onnx";

    static void Main(string[] args)
    {
        var session = new InferenceSession(ONNX_MODEL_PATH);
        var dataPoint = new float[] { 5.1f, 3.5f, 1.4f, 0.2f };

        var inputTensor = new DenseTensor(dataPoint, new int[] { 1, dataPoint.Length });
        // Determine input name dynamically
        string inputName = session.InputMetadata.Keys.First();
        Console.WriteLine($"Using input name: {inputName}");

        // Create named ONNX value
        var inputs = new List
        {
            NamedOnnxValue.CreateFromTensor(inputName, inputTensor)
        };
        
        using var results = session.Run(inputs);

        // Retrieve and display the prediction result
        var output = results.First().AsEnumerable().ToArray();
        Console.WriteLine("Prediction:");
        foreach (var value in output)
        {
            Console.WriteLine(value);
        }
    }
}

I don't see any obvious reason why it would fail. Did you try a logistic regression? Did you check the model was running with onnxruntime in Python to make sure the error is in C#?

Yeah I didn't see any problems either the code looks correct. The error doesn't happen in python I already checked that, and all regression models work just fine it is only the classification models. I tried a bunch of different classification models and all had that error. I targeted it down to a possibility that the model in C# is not being loaded at all or it is being loaded incorrectly. The exact location where it throws the error is right below.

 
using var results = session.Run(inputs);

var output = results.First().AsEnumerable().ToArray();

The output variable is actual the line that throws the error but it is caused by the session.Run(inputs) because it produces no output at all. I am not sure if this is a Microsoft onnx issue or a conversion issue.

Maybe you can try with zipmap=True. Otherwise, I suggest raising the issue on onnxruntime. It seems to be an issue with onnxruntime.