onnxruntime/python/_downloads/plot_convert_pipeline_vectorizer.ipynb
2019-12-20 13:35:58 -08:00

187 lines
No EOL
6 KiB
Text

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\nTrain, convert and predict with ONNX Runtime\n============================================\n\nThis example demonstrates an end to end scenario\nstarting with the training of a scikit-learn pipeline\nwhich takes as inputs not a regular vector but a\ndictionary ``{ int: float }`` as its first step is a\n`DictVectorizer <http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.DictVectorizer.html>`_.\n\nTrain a pipeline\n++++++++++++++++\n\nThe first step consists in retrieving the boston datset.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import pandas\nfrom sklearn.datasets import load_boston\nboston = load_boston()\nX, y = boston.data, boston.target\n\nfrom sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y)\nX_train_dict = pandas.DataFrame(X_train[:,1:]).T.to_dict().values()\nX_test_dict = pandas.DataFrame(X_test[:,1:]).T.to_dict().values()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We create a pipeline.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from sklearn.pipeline import make_pipeline\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom sklearn.feature_extraction import DictVectorizer\npipe = make_pipeline(\n DictVectorizer(sparse=False),\n GradientBoostingRegressor())\n \npipe.fit(X_train_dict, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We compute the prediction on the test set\nand we show the confusion matrix.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from sklearn.metrics import r2_score\n\npred = pipe.predict(X_test_dict)\nprint(r2_score(y_test, pred))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Conversion to ONNX format\n+++++++++++++++++++++++++\n\nWe use module \n`sklearn-onnx <https://github.com/onnx/sklearn-onnx>`_\nto convert the model into ONNX format.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from skl2onnx import convert_sklearn\nfrom skl2onnx.common.data_types import FloatTensorType, Int64TensorType, DictionaryType, SequenceType\n\n# initial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]\ninitial_type = [('float_input', DictionaryType(Int64TensorType([1]), FloatTensorType([])))]\nonx = convert_sklearn(pipe, initial_types=initial_type)\nwith open(\"pipeline_vectorize.onnx\", \"wb\") as f:\n f.write(onx.SerializeToString())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We load the model with ONNX Runtime and look at\nits input and output.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import onnxruntime as rt\nfrom onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument\n\nsess = rt.InferenceSession(\"pipeline_vectorize.onnx\")\n\nimport numpy\ninp, out = sess.get_inputs()[0], sess.get_outputs()[0]\nprint(\"input name='{}' and shape={} and type={}\".format(inp.name, inp.shape, inp.type))\nprint(\"output name='{}' and shape={} and type={}\".format(out.name, out.shape, out.type))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We compute the predictions.\nWe could do that in one call:\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"try:\n pred_onx = sess.run([out.name], {inp.name: X_test_dict})[0]\nexcept (RuntimeError, InvalidArgument) as e:\n print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But it fails because, in case of a DictVectorizer,\nONNX Runtime expects one observation at a time.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"pred_onx = [sess.run([out.name], {inp.name: row})[0][0, 0] for row in X_test_dict]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We compare them to the model's ones.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"print(r2_score(pred, pred_onx))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Very similar. *ONNX Runtime* uses floats instead of doubles,\nthat explains the small discrepencies.\n\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 0
}