Skip to content

Commit ead6925

Browse files
xadupreWenbing Li
authored andcommitted
Fixes #232, documentation (#190)
* remove unnecessary print, add quote around filenames in some places * replaces as_matrix by values (pandas warnings) * changes variable name to avoid getting warnings about invalid names * better consistency for converted, allows targetted onnx version to be None * Revert "better consistency for converted, allows targetted onnx version to be None" This reverts commit e257ca1. * handle the comparison of ONNX versions in only one place * fix bug with OneHotEncoder and scikit-learn 0.20 * release the constraint on scikit-learn (0.20.0 allowed) * fix one type issue for Python 2.7 * add documentation to compare_strict_version * Fixes #151, BernouilliNB converter * Removes unused nodes in graph * Adresses issue #143, enables build with keras 2.1.2 * Revert modifications due to a wrong merge * update keras version * Disable test on keras/mobilenet as it does not work * add unit test for xception (failing) * remove duplicate install * skip unit test if not installed (tensorflow still not available on python 3.7) * Fix when keras is not available * Fix missing import * Update test_single_operator_with_cntk_backend.py * Set up CI with Azure Pipelines * Update azure pipeline * Skip a unit test if tensorflow is not installed * merge * missing import * Revert "Merge branch 'master' of https://github.com/onnx/onnxmltools" This reverts commit 178e763, reversing changes made to 1a617ef. * revert changes * Revert changes * \r * \r * documentation * Fix appveyor * fix bad merge * remove example on keras * Delete requirements-deep.txt
1 parent c2cf4dc commit ead6925

File tree

19 files changed

+700
-21
lines changed

19 files changed

+700
-21
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ tests/utils/models/coreml_OneHotEncoder_BikeSharing_new.json
2929
tests/utils/models/coreml_OneHotEncoder_BikeSharing2.onnx
3030
tests/baseline/outmodels
3131
htmlcov
32+
build
3233
coverage.xml
3334
.coverage
3435
TESTDUMP
@@ -38,3 +39,10 @@ tests_backend/*.onnx
3839
tests/*/tests/*
3940
tests/build/*
4041
tests/tests/
42+
tests/*/tests/*.pkl
43+
tests/*/tests/*.onnx
44+
tests/*/tests/*.keras
45+
docs/auto_examples/*
46+
docs/examples/dense121.onnx
47+
docs/examples/graph.dot
48+
docs/examples/graph.dot.png

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ ONNXMLTools enables you to convert models from different machine learning toolki
1010
* Apple Core ML
1111
* scikit-learn (subset of models convertible to ONNX)
1212
* Keras
13-
* LightGBM (through its scikit-learn interface)
13+
* LightGBM
14+
* libsvm
1415

1516
To convert Tensorflow models to ONNX, see [tensorflow-onnx](https://github.com/onnx/tensorflow-onnx).
1617

docs/_templates/page.html

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6+
<meta http-equiv="x-ua-compatible" content="ie=edge">
7+
8+
<title>{{title|striptags|e}}{{titlesuffix}}</title>
9+
10+
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css"/>
11+
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
12+
<link rel="stylesheet" href="{{ pathto('_static/gallery.css', 1) }}" type="text/css" />
13+
</head>
14+
<body>
15+
<div class="container">
16+
<div class="row" style="margin-top: 1rem;">
17+
<div id="sidebar" class="col-xs-12 col-sm-3">
18+
<a href="{{pathto(master_doc)}}">
19+
<img style="margin-bottom: 0.5rem;" class="img-fluid" src="{{ pathto('_static/' + logo, 1) }}"/>
20+
</a>
21+
22+
{%- if pagename != "search" and builder != "singlehtml" %}
23+
<div id="searchbox" style="display: none" role="search">
24+
<form class="form-inline" action="{{ pathto('search') }}" method="get">
25+
<div class="form-group">
26+
<label class="sr-only" for="searchInput">Search</label>
27+
<input type="text" class="form-control" name="q" id="searchInput" placeholder="Search">
28+
</div>
29+
<button type="submit" class="btn btn-secondary" style="display:none">Go</button>
30+
<input type="hidden" name="check_keywords" value="yes"/>
31+
<input type="hidden" name="area" value="default"/>
32+
</form>
33+
</div>
34+
{%- endif %}
35+
36+
<hr>
37+
38+
<div id="toc">
39+
{{ toctree(maxdepth=2, collapse=False, includehidden=True) }}
40+
</div>
41+
42+
{%- if theme_versions_url %}
43+
<hr>
44+
<div id="versions" class="card">
45+
<div class="card-block">
46+
<h6 class="card-title" style="display:inline;">Version {{release}}</h6>
47+
<a class="btn btn-secondary btn-sm pull-xs-right" data-toggle="collapse"
48+
href="#other-versions" aria-expanded="false">&#9660;</a>
49+
<ul id="other-versions" class="collapse list-inline">
50+
<li id="other-versions-text" class="list-inline-item">Other versions</li>
51+
<!-- Add <li class="list-inline-item">'s here -->
52+
</ul>
53+
</div>
54+
</div>
55+
<script>var versions_json_url = '{{theme_versions_url}}'</script>
56+
{% endif %}
57+
</div>
58+
<div class="col-xs-12 col-sm-9">
59+
{{ body }}
60+
</div>
61+
</div>
62+
</div>
63+
64+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"
65+
integrity="sha384-THPy051/pYDQGanwU6poAc/hOdQxjnOEXzbT+OuUAFqNqFjL+4IGLBgCJC3ZOShY"
66+
crossorigin="anonymous"></script>
67+
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.2.0/js/tether.min.js"
68+
integrity="sha384-Plbmg8JY28KFelvJVai01l8WyZzrYWG825m+cZ0eDDS1f7d/js6ikvy1+X+guPIB"
69+
crossorigin="anonymous"></script>
70+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.3/js/bootstrap.min.js"
71+
integrity="sha384-ux8v3A6CPtOTqOzMKiuo3d/DomGaaClxFYdCu2HPMBEkf6x2xiDyJ7gkXU0MWwaD"
72+
crossorigin="anonymous"></script>
73+
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
74+
<script src="https://cdnjs.cloudflare.com/ajax/libs/lunr.js/0.6.0/lunr.min.js"></script>
75+
<script src="{{ pathto('_static/searchtools.js', 1) }}"></script>
76+
{%- if theme_versions_url %}
77+
<script src="{{ pathto('_static/versions.js', 1) }}"></script>
78+
{% endif %}
79+
<script>$('#searchbox').show(0)</script>
80+
</body>
81+
</html>

docs/api_summary.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
===========
3+
API Summary
4+
===========
5+
6+
Summary of public functions and classes exposed
7+
in *onnxmltools*.
8+
9+
.. contents::
10+
:local:
11+
12+
Converters
13+
==========
14+
15+
.. autofunction:: onnxmltools.convert.coreml.convert
16+
17+
.. autofunction:: onnxmltools.convert.keras.convert
18+
19+
.. autofunction:: onnxmltools.convert.lightgbm.convert
20+
21+
.. autofunction:: onnxmltools.convert.sklearn.convert
22+
23+
Utils
24+
=====
25+
26+
.. autofunction:: onnxmltools.utils.visualize_model
27+
28+
.. autofunction:: onnxmltools.utils.dump_data_and_model

docs/conf.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
# -*- coding: utf-8 -*-
5+
#
6+
# Configuration file for the Sphinx documentation builder.
7+
8+
import os
9+
import sys
10+
import shutil
11+
import sphinx_gallery.gen_gallery
12+
import onnxmltools
13+
import onnxruntime
14+
import sphinx_modern_theme_modified
15+
16+
17+
# -- Project information -----------------------------------------------------
18+
19+
project = 'onnxmltools'
20+
copyright = '2018, Microsoft'
21+
author = 'Microsoft'
22+
version = onnxmltools.__version__
23+
release = version
24+
25+
# -- General configuration ---------------------------------------------------
26+
27+
extensions = [
28+
'sphinx.ext.intersphinx',
29+
'sphinx.ext.imgmath',
30+
'sphinx.ext.ifconfig',
31+
'sphinx.ext.viewcode',
32+
"sphinx.ext.autodoc",
33+
'sphinx.ext.githubpages',
34+
"sphinx_gallery.gen_gallery",
35+
'sphinx.ext.autodoc',
36+
]
37+
38+
templates_path = ['_templates']
39+
source_suffix = ['.rst']
40+
41+
master_doc = 'index'
42+
language = "en"
43+
exclude_patterns = []
44+
pygments_style = 'default'
45+
46+
# -- Options for HTML output -------------------------------------------------
47+
48+
html_theme = "sphinx_mo"
49+
html_static_path = ['_static']
50+
html_theme = "sphinx_modern_theme_modified"
51+
html_theme_path = [sphinx_modern_theme_modified.get_html_theme_path()]
52+
html_logo = "ONNXMLTools_logo_main.png"
53+
54+
# -- Options for intersphinx extension ---------------------------------------
55+
56+
# Example configuration for intersphinx: refer to the Python standard library.
57+
intersphinx_mapping = {'https://docs.python.org/': None}
58+
59+
# -- Options for Sphinx Gallery ----------------------------------------------
60+
61+
sphinx_gallery_conf = {
62+
'examples_dirs': 'examples',
63+
'gallery_dirs': 'auto_examples',
64+
}
65+
66+
# -- Setup actions -----------------------------------------------------------
67+
68+
def setup(app):
69+
# Placeholder to initialize the folder before
70+
# generating the documentation.
71+
return app
72+

docs/examples/README.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Gallery of examples
2+
===================
3+
4+
.. toctree::
5+
:maxdepth: 1

docs/examples/Sannosawa1.jpg

958 KB
Loading

docs/examples/plot_backend.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
6+
.. _l-example-backend-api:
7+
8+
ONNX Runtime Backend for ONNX
9+
=============================
10+
11+
*ONNX Runtime* extends the
12+
`onnx backend API <https://github.com/onnx/onnx/blob/master/docs/ImplementingAnOnnxBackend.md>`_
13+
to run predictions using this runtime.
14+
Let's use the API to compute the prediction
15+
of a simple logistic regression model.
16+
"""
17+
import numpy as np
18+
from onnxruntime import datasets
19+
import onnxruntime.backend as backend
20+
from onnx import load
21+
22+
name = datasets.get_example("logreg_iris.onnx")
23+
model = load(name)
24+
25+
rep = backend.prepare(model, 'CPU')
26+
x = np.array([[-1.0, -2.0]], dtype=np.float32)
27+
label, proba = rep.run(x)
28+
print("label={}".format(label))
29+
print("probabilities={}".format(proba))
30+
31+
########################################
32+
# The device depends on how the package was compiled,
33+
# GPU or CPU.
34+
from onnxruntime import get_device
35+
print(get_device())
36+
37+
########################################
38+
# The backend can also directly load the model
39+
# without using *onnx*.
40+
41+
rep = backend.prepare(name, 'CPU')
42+
x = np.array([[-1.0, -2.0]], dtype=np.float32)
43+
label, proba = rep.run(x)
44+
print("label={}".format(label))
45+
print("probabilities={}".format(proba))
46+
47+
#######################################
48+
# The backend API is implemented by other frameworks
49+
# and makes it easier to switch between multiple runtimes
50+
# with the same API.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
"""
5+
.. _l-example-simple-usage:
6+
7+
Common errors with onnxruntime
8+
==============================
9+
10+
This example looks into several common situations
11+
in which *onnxruntime* does not return the model
12+
prediction but raises an exception instead.
13+
It starts by loading the model trained in example
14+
:ref:`l-logreg-example` which produced a logistic regression
15+
trained on *Iris* datasets. The model takes
16+
a vector of dimension 2 and returns a class among three.
17+
"""
18+
import onnxruntime as rt
19+
import numpy
20+
from onnxruntime.datasets import get_example
21+
22+
example2 = get_example("logreg_iris.onnx")
23+
sess = rt.InferenceSession(example2)
24+
25+
input_name = sess.get_inputs()[0].name
26+
output_name = sess.get_outputs()[0].name
27+
28+
#############################
29+
# The first example fails due to *bad types*.
30+
# *onnxruntime* only expects single floats (4 bytes)
31+
# and cannot handle any other kind of floats.
32+
33+
try:
34+
x = numpy.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=numpy.float64)
35+
sess.run([output_name], {input_name: x})
36+
except Exception as e:
37+
print("Unexpected type")
38+
print("{0}: {1}".format(type(e), e))
39+
40+
#########################
41+
# The model fails to return an output if the name
42+
# is misspelled.
43+
44+
try:
45+
x = numpy.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=numpy.float32)
46+
sess.run(["misspelled"], {input_name: x})
47+
except Exception as e:
48+
print("Misspelled output name")
49+
print("{0}: {1}".format(type(e), e))
50+
51+
###########################
52+
# The output name is optional, it can be replaced by *None*
53+
# and *onnxruntime* will then return all the outputs.
54+
55+
x = numpy.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=numpy.float32)
56+
res = sess.run(None, {input_name: x})
57+
print("All outputs")
58+
print(res)
59+
60+
#########################
61+
# The same goes if the input name is misspelled.
62+
63+
try:
64+
x = numpy.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=numpy.float32)
65+
sess.run([output_name], {"misspelled": x})
66+
except Exception as e:
67+
print("Misspelled input name")
68+
print("{0}: {1}".format(type(e), e))
69+
70+
#########################
71+
# *onnxruntime* does not necessarily fail if the input
72+
# dimension is a multiple of the expected input dimension.
73+
74+
for x in [
75+
numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),
76+
numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),
77+
numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),
78+
numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),
79+
numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),
80+
]:
81+
r = sess.run([output_name], {input_name: x})
82+
print("Shape={0} and predicted labels={1}".format(x.shape, r))
83+
84+
for x in [
85+
numpy.array([1.0, 2.0, 3.0, 4.0], dtype=numpy.float32),
86+
numpy.array([[1.0, 2.0, 3.0, 4.0]], dtype=numpy.float32),
87+
numpy.array([[1.0, 2.0], [3.0, 4.0]], dtype=numpy.float32),
88+
numpy.array([1.0, 2.0, 3.0], dtype=numpy.float32),
89+
numpy.array([[1.0, 2.0, 3.0]], dtype=numpy.float32),
90+
]:
91+
r = sess.run(None, {input_name: x})
92+
print("Shape={0} and predicted probabilities={1}".format(x.shape, r[1]))
93+
94+
#########################
95+
# It does not fail either if the number of dimension
96+
# is higher than expects but produces a warning.
97+
98+
for x in [
99+
numpy.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=numpy.float32),
100+
numpy.array([[[1.0, 2.0, 3.0]]], dtype=numpy.float32),
101+
numpy.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=numpy.float32),
102+
]:
103+
r = sess.run([output_name], {input_name: x})
104+
print("Shape={0} and predicted labels={1}".format(x.shape, r))

0 commit comments

Comments
 (0)