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.
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.