onnxruntime/python/sources/auto_examples/plot_convert_pipeline_vectorizer.rst.txt

264 lines
5.7 KiB
Text
Raw Normal View History

2020-08-13 02:12:50 +00:00
.. only:: html
.. note::
:class: sphx-glr-download-link-note
2020-08-13 02:12:50 +00:00
Click :ref:`here <sphx_glr_download_auto_examples_plot_convert_pipeline_vectorizer.py>` to download the full example code
.. rst-class:: sphx-glr-example-title
2020-08-13 02:12:50 +00:00
.. _sphx_glr_auto_examples_plot_convert_pipeline_vectorizer.py:
Train, convert and predict with ONNX Runtime
============================================
This example demonstrates an end to end scenario
starting with the training of a scikit-learn pipeline
which takes as inputs not a regular vector but a
dictionary ``{ int: float }`` as its first step is a
`DictVectorizer <http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.DictVectorizer.html>`_.
.. contents::
:local:
Train a pipeline
++++++++++++++++
The first step consists in retrieving the boston datset.
2020-08-13 02:12:50 +00:00
.. code-block:: default
import pandas
from sklearn.datasets import load_boston
boston = load_boston()
X, y = boston.data, boston.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
X_train_dict = pandas.DataFrame(X_train[:,1:]).T.to_dict().values()
X_test_dict = pandas.DataFrame(X_test[:,1:]).T.to_dict().values()
2020-08-13 02:12:50 +00:00
We create a pipeline.
2020-08-13 02:12:50 +00:00
.. code-block:: default
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.feature_extraction import DictVectorizer
pipe = make_pipeline(
DictVectorizer(sparse=False),
GradientBoostingRegressor())
pipe.fit(X_train_dict, y_train)
2020-08-13 02:12:50 +00:00
.. rst-class:: sphx-glr-script-out
Out:
.. code-block:: none
Pipeline(steps=[('dictvectorizer', DictVectorizer(sparse=False)),
('gradientboostingregressor', GradientBoostingRegressor())])
We compute the prediction on the test set
and we show the confusion matrix.
2020-08-13 02:12:50 +00:00
.. code-block:: default
from sklearn.metrics import r2_score
pred = pipe.predict(X_test_dict)
print(r2_score(y_test, pred))
.. rst-class:: sphx-glr-script-out
Out:
.. code-block:: none
0.910393699497388
2020-08-13 02:12:50 +00:00
Conversion to ONNX format
+++++++++++++++++++++++++
We use module
`sklearn-onnx <https://github.com/onnx/sklearn-onnx>`_
to convert the model into ONNX format.
2020-08-13 02:12:50 +00:00
.. code-block:: default
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType, Int64TensorType, DictionaryType, SequenceType
# initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]
initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]
onx = convert_sklearn(pipe, initial_types=initial_type)
with open("pipeline_vectorize.onnx", "wb") as f:
f.write(onx.SerializeToString())
2020-08-13 02:12:50 +00:00
We load the model with ONNX Runtime and look at
its input and output.
2020-08-13 02:12:50 +00:00
.. code-block:: default
import onnxruntime as rt
from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument
sess = rt.InferenceSession("pipeline_vectorize.onnx")
import numpy
inp, out = sess.get_inputs()[0], sess.get_outputs()[0]
print("input name='{}' and shape={} and type={}".format(inp.name, inp.shape, inp.type))
print("output name='{}' and shape={} and type={}".format(out.name, out.shape, out.type))
.. rst-class:: sphx-glr-script-out
Out:
.. code-block:: none
input name='float_input' and shape=[] and type=map(int64,tensor(float))
output name='variable' and shape=[None, 1] and type=tensor(float)
2020-08-13 02:12:50 +00:00
We compute the predictions.
We could do that in one call:
2020-08-13 02:12:50 +00:00
.. code-block:: default
try:
pred_onx = sess.run([out.name], {inp.name: X_test_dict})[0]
except (RuntimeError, InvalidArgument) as e:
print(e)
.. rst-class:: sphx-glr-script-out
Out:
.. code-block:: none
[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Unexpected input data type. Actual: (class onnxruntime::SequenceType<class std::vector<class std::map<__int64,float,struct std::less<__int64>,class std::allocator<struct std::pair<__int64 const ,float> > >,class std::allocator<class std::map<__int64,float,struct std::less<__int64>,class std::allocator<struct std::pair<__int64 const ,float> > > > > >) , expected: (class onnxruntime::MapType<class std::map<__int64,float,struct std::less<__int64>,class std::allocator<struct std::pair<__int64 const ,float> > > >)
2020-08-13 02:12:50 +00:00
But it fails because, in case of a DictVectorizer,
ONNX Runtime expects one observation at a time.
2020-08-13 02:12:50 +00:00
.. code-block:: default
pred_onx = [sess.run([out.name], {inp.name: row})[0][0, 0] for row in X_test_dict]
2020-08-13 02:12:50 +00:00
We compare them to the model's ones.
2020-08-13 02:12:50 +00:00
.. code-block:: default
print(r2_score(pred, pred_onx))
.. rst-class:: sphx-glr-script-out
Out:
.. code-block:: none
0.9999999999999488
2020-08-13 02:12:50 +00:00
Very similar. *ONNX Runtime* uses floats instead of doubles,
that explains the small discrepencies.
2020-08-13 02:12:50 +00:00
.. rst-class:: sphx-glr-timing
**Total running time of the script:** ( 0 minutes 2.272 seconds)
.. _sphx_glr_download_auto_examples_plot_convert_pipeline_vectorizer.py:
.. only :: html
.. container:: sphx-glr-footer
:class: sphx-glr-footer-example
2020-08-13 02:12:50 +00:00
.. container:: sphx-glr-download sphx-glr-download-python
:download:`Download Python source code: plot_convert_pipeline_vectorizer.py <plot_convert_pipeline_vectorizer.py>`
2020-08-13 02:12:50 +00:00
.. container:: sphx-glr-download sphx-glr-download-jupyter
:download:`Download Jupyter notebook: plot_convert_pipeline_vectorizer.ipynb <plot_convert_pipeline_vectorizer.ipynb>`
.. only:: html
.. rst-class:: sphx-glr-signature
2020-08-13 02:12:50 +00:00
`Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_