If a converted ONNX model produces different results than the original scikit-learn model, use skl2onnx.helpers.collect_intermediate_steps to isolate the source of the error.
This function modifies the pipeline to keep intermediate inputs and outputs. You can then iterate through each operator, run the corresponding ONNX sub-graph using onnxruntime, and compare the results against the scikit-learn component's debug outputs using compare_objects.
import numpy
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import onnxruntime
from skl2onnx.helpers import collect_intermediate_steps, compare_objects
from skl2onnx.common.data_types import FloatTensorType
# 1. Setup and fit model
data = numpy.array([[0, 0], [0, 0], [2, 1], [2, 1]], dtype=numpy.float32)
model = Pipeline([("scaler1", StandardScaler()), ("scaler2", StandardScaler())])
model.fit(data)
# 2. Collect intermediate steps
operators = collect_intermediate_steps(model, "pipeline", [("input", FloatTensorType([None, 2]))])
# 3. Trigger transform to populate debug info
model.transform(data)
# 4. Iterate and compare
for op in operators:
onnx_step = op['onnx_step']
sess = onnxruntime.InferenceSession(onnx_step.SerializeToString(), providers=["CPUExecutionProvider"])
onnx_outputs = sess.run(None, {'input': data})
onnx_output = onnx_outputs[0]
skl_outputs = op['model']._debug.outputs['transform']
# Compare outputs
compare_objects(onnx_output, skl_outputs)