onnx / sklearn-onnx

Convert scikit-learn models and pipelines to ONNX
Apache License 2.0
557 stars 104 forks source link

`to_onnx` yields error when loading with onnxruntime #958

Open maoding opened 1 year ago

maoding commented 1 year ago

Here is a simple example using a regression and to_onnx.

(I manipulate one column to be of type int instead of str. - Actually this doesn't matter.)

I am able to save the model as onnx but on creating an onnxruntime.InferenceSession I get ONNXRuntimeError (see below).

import onnxruntime
from skl2onnx import to_onnx
from sklearn import datasets
from sklearn import linear_model
from sklearn import model_selection
from sklearn import pipeline
from sklearn import preprocessing

dataset = datasets.load_diabetes(as_frame=True)
X, y = dataset.data, dataset.target

# convert one float column to int
X.loc[:, "sex"] = X.loc[:, "sex"].astype(int)

X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y)
regr = pipeline.Pipeline(
    [("std", preprocessing.StandardScaler()), ("reg", linear_model.LinearRegression())]
)
regr = regr.fit(X_train, y_train)

onnx_model = to_onnx(regr, X=X_train)

with open("model.onnx", "wb") as f:
    f.write(onnx_model.SerializeToString())

# raises error
sess = onnxruntime.InferenceSession("model.onnx")
---------------------------------------------------------------------------
Fail: [ONNXRuntimeError] : 1 : FAIL : Load model from model.onnx failed:Type Error: Type parameter (T) of Optype (Sub) bound to different types (tensor(float) and tensor(double) in node (Su_Sub).

What am I doing wrong?

Used versions:

worthy7 commented 1 year ago

Is this package dead or something? I also have this error just trying to reproduce the basic sample on the readme.

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import numpy as np
iris = load_iris()
Xi, yi = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(Xi, yi)

from sklearn.linear_model import LogisticRegression
clr = LogisticRegression(max_iter=1000)
clr.fit(X_train, y_train)

from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType

initial_type = [('float_input', FloatTensorType([None, 4]))]
#onx = convert_sklearn(clr, initial_types=initial_type)
onx = to_onnx(clr, X=X_train, verbose=1)
with open("logreg_iris.onnx", "wb") as f:
    f.write(onx.SerializeToString())

import onnxruntime as rt
sess = rt.InferenceSession("logreg_iris.onnx", providers=["CPUExecutionProvider"])
input_name = sess.get_inputs()[0].name
label_name = sess.get_outputs()[0].name

pred_onx = sess.run([label_name], {input_name: X_test.astype(np.float32)})[0]
pred_onx

InvalidGraph: [ONNXRuntimeError] : 10 : INVALID_GRAPH : Load model from logreg_iris.onnx failed:This is an invalid model. Type Error: Type 'tensor(double)' of input parameter (probabilities) of operator (ZipMap) in node (ZipMap) is invalid.

xadupre commented 1 year ago

Sorry for the delay, the package is not dead. ZipMap only works with float32 not double (float64). You need to remove it to_onnx(clr, X=X_train, options={'zipmap': False}) or to switch to float32 to_onnx(clr, X=X_train.astype(np.float32), verbose=1).