We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
saving model works with binary classifier, fails with multiclass classifier
I am using Sklearn's SVC for a classifier, with TfidfVectorizer as the feature embedding method. Following #478  I am using `skl2onnx` version 1.7.1. My code is here:

```
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import SVC
import numpy as np

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


#import json
#with open('fake_data.json', 'r') as f:
#    dataset = json.load(f)
#docs = [doc for (doc, _) in dataset]
#labels = [label for (_, label) in dataset]

data = [
    ["schedule a meeting", 0],
    ["schedule a sync with the team", 0],
    ["slot in a meeting", 0],
    ["call ron", 1],
    ["make a phone call", 1],
    ["call in on the phone", 2] # changing this from 2 to 1 will allow code to successfully run
]
docs = [doc for (doc, _) in data]
labels = [label for (_, label) in data]


vectorizer = TfidfVectorizer()
vectorizer.fit_transform(docs)
embeddings = vectorizer.transform(docs)
dim = embeddings.shape[1]
#embeddings = np.vstack(embeddings)

clf = SVC()
clf.fit(embeddings, labels)

initial_type = [('float_input', FloatTensorType([1, dim]))]
onnx_model = convert_sklearn(clf, initial_types=initial_type) # this is line 37, where the crash occurs
with open('model.onnx', 'wb') as f:
    f.write(onnx_model.SerializeToString())
```

When I run the above, I get:

```
Traceback (most recent call last):
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\common\_container.py", line 536, in add_node
    node = make_node(op_type, inputs, outputs, name=name,
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\proto\onnx_helper_modified.py", line 66, in make_node
    node.attribute.extend(
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\google\protobuf\internal\containers.py", line 410, in extend
    for message in elem_seq:
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\proto\onnx_helper_modified.py", line 67, in <genexpr>
    make_attribute(key, value, dtype=_dtype, domain=domain)
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\proto\onnx_helper_modified.py", line 175, in make_attribute
    raise ValueError(
ValueError: You passed in an iterable attribute but I cannot figure out its applicable type, key='coefficients', type=<class 'numpy.matrix'>, dtype=float32, types=[<class 'numpy.matrix'>, <class 'numpy.matrix'>].

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\dust.py", line 37, in <module>
    onnx_model = convert_sklearn(clf, initial_types=initial_type)
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\convert.py", line 160, in convert_sklearn
    onnx_model = convert_topology(topology, name, doc_string, target_opset,
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\common\_topology.py", line 1069, in convert_topology
    conv(scope, operator, container)
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\common\_registration.py", line 29, in __call__
    return self._fct(*args)
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\operator_converters\support_vector_machines.py", line 214, in convert_sklearn_svm_classifier
    container.add_node(
  File "C:\Users\Stefan Larson\AppData\Local\Programs\Python\Python38\lib\site-packages\skl2onnx\common\_container.py", line 539, in add_node
    raise ValueError("Unable to create node '{}' with name='{}'."
ValueError: Unable to create node 'SVMClassifier' with name='SVMc'.
```

The code crashes at the `convert_sklearn` function call. However, when I alter the dataset to have only two classes ('1', and '0'), the code runs successfully.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `skl2onnx/proto/onnx_helper_modified.py`
Content:
```
1 # Modified file from
2 # https://github.com/onnx/onnx/blob/master/onnx/helper.py.
3 import collections
4 import numbers
5 
6 from onnx import (
7     TensorProto, AttributeProto,
8     NodeProto, GraphProto
9 )
10 from onnx.helper import (  # noqa
11     make_tensor, make_model, make_graph, _to_bytes_or_false,
12     make_tensor_value_info, ValueInfoProto
13 )
14 
15 try:
16     from onnx import SparseTensorProto
17     from onnx.helper import make_sparse_tensor # noqa
18 except ImportError:
19     # onnx is too old.
20     SparseTensorProto = None
21 
22 from onnx.numpy_helper import from_array  # noqa
23 from typing import (
24     Text, Sequence, Any, Optional,
25     List, cast
26 )
27 import numpy as np  # type: ignore
28 
29 
30 def make_node(
31         op_type,  # type: Text
32         inputs,  # type: Sequence[Text]
33         outputs,  # type: Sequence[Text]
34         name=None,  # type: Optional[Text]
35         doc_string=None,  # type: Optional[Text]
36         domain=None,  # type: Optional[Text]
37         _dtype=None,  # type: [np.float32, np.float64]
38         **kwargs  # type: Any
39         ):  # type: (...) -> NodeProto
40     """Construct a NodeProto.
41 
42     Arguments:
43         op_type (string): The name of the operator to construct
44         inputs (list of string): list of input names
45         outputs (list of string): list of output names
46         name (string, default None): optional unique identifier for NodeProto
47         doc_string (string, default None): optional documentation
48             string for NodeProto
49         dtype: dtype for double used to infer
50         domain (string, default None): optional domain for NodeProto.
51             If it's None, we will just use default domain (which is empty)
52         **kwargs (dict): the attributes of the node.  The acceptable values
53             are documented in :func:`make_attribute`.
54     """
55     node = NodeProto()
56     node.op_type = op_type
57     node.input.extend(inputs)
58     node.output.extend(outputs)
59     if name:
60         node.name = name
61     if doc_string:
62         node.doc_string = doc_string
63     if domain is not None:
64         node.domain = domain
65     if kwargs:
66         node.attribute.extend(
67             make_attribute(key, value, dtype=_dtype, domain=domain)
68             for key, value in sorted(kwargs.items()))
69     return node
70 
71 
72 def make_attribute(
73         key,  # type: Text
74         value,  # type: Any
75         dtype=None,  # type: [np.float32, np.float64]
76         domain='',  # type: Text
77         doc_string=None  # type: Optional[Text]
78         ):  # type: (...) -> AttributeProto
79     """Makes an AttributeProto based on the value type."""
80     attr = AttributeProto()
81     attr.name = key
82     if doc_string:
83         attr.doc_string = doc_string
84 
85     is_iterable = isinstance(value, collections.abc.Iterable)
86     bytes_or_false = _to_bytes_or_false(value)
87 
88     use_float64 = dtype == np.float64 and domain not in ('', 'ai.onnx.ml')
89 
90     if isinstance(value, np.float32):
91         attr.f = value
92         attr.type = AttributeProto.FLOAT
93     elif isinstance(value, (float, np.float64)):
94         if use_float64:
95             attr.type = AttributeProto.TENSOR
96             attr.t.CopyFrom(
97                 make_tensor(
98                     key, TensorProto.DOUBLE, (1, ), [value]))
99         else:
100             attr.f = value
101             attr.type = AttributeProto.FLOAT
102     elif isinstance(value, np.int32):
103         attr.i = value
104         attr.type = AttributeProto.INT
105     elif isinstance(value, np.int64):
106         attr.i = value
107         attr.type = AttributeProto.INT
108     elif isinstance(value, numbers.Integral):
109         attr.i = value
110         attr.type = AttributeProto.INT
111     # string
112     elif bytes_or_false is not False:
113         assert isinstance(bytes_or_false, bytes)
114         attr.s = bytes_or_false
115         attr.type = AttributeProto.STRING
116     elif isinstance(value, TensorProto):
117         attr.t.CopyFrom(value)
118         attr.type = AttributeProto.TENSOR
119     elif (SparseTensorProto is not None and
120             isinstance(value, SparseTensorProto)):
121         attr.sparse_tensor.CopyFrom(value)
122         attr.type = AttributeProto.SPARSE_TENSOR
123     elif isinstance(value, GraphProto):
124         attr.g.CopyFrom(value)
125         attr.type = AttributeProto.GRAPH
126     # third, iterable cases
127     elif is_iterable:
128         byte_array = [_to_bytes_or_false(v) for v in value]
129         if all(isinstance(v, np.float32) for v in value):
130             attr.floats.extend(value)
131             attr.type = AttributeProto.FLOATS
132         elif all(isinstance(v, np.float64) for v in value):
133             if use_float64:
134                 attr.type = AttributeProto.TENSOR
135                 attr.t.CopyFrom(
136                     make_tensor(
137                         key, TensorProto.DOUBLE, (len(value), ), value))
138             else:
139                 attr.floats.extend(value)
140                 attr.type = AttributeProto.FLOATS
141         elif all(isinstance(v, float) for v in value):
142             if use_float64:
143                 attr.type = AttributeProto.TENSOR
144                 attr.t.CopyFrom(
145                     make_tensor(
146                         key, TensorProto.DOUBLE, (len(value), ), value))
147             else:
148                 attr.floats.extend(value)
149                 attr.type = AttributeProto.FLOATS
150         elif all(isinstance(v, np.int32) for v in value):
151             attr.ints.extend(int(v) for v in value)
152             attr.type = AttributeProto.INTS
153         elif all(isinstance(v, np.int64) for v in value):
154             attr.ints.extend(int(v) for v in value)
155             attr.type = AttributeProto.INTS
156         elif all(isinstance(v, numbers.Integral) for v in value):
157             # Turn np.int32/64 into Python built-in int.
158             attr.ints.extend(int(v) for v in value)
159             attr.type = AttributeProto.INTS
160         elif all(map(lambda bytes_or_false: bytes_or_false is not False,
161                      byte_array)):
162             attr.strings.extend(cast(List[bytes], byte_array))
163             attr.type = AttributeProto.STRINGS
164         elif all(isinstance(v, TensorProto) for v in value):
165             attr.tensors.extend(value)
166             attr.type = AttributeProto.TENSORS
167         elif (SparseTensorProto is not None and
168                 all(isinstance(v, SparseTensorProto) for v in value)):
169             attr.sparse_tensors.extend(value)
170             attr.type = AttributeProto.SPARSE_TENSORS
171         elif all(isinstance(v, GraphProto) for v in value):
172             attr.graphs.extend(value)
173             attr.type = AttributeProto.GRAPHS
174         else:
175             raise ValueError(
176                 "You passed in an iterable attribute but I cannot figure out "
177                 "its applicable type, key='{}', type={}, dtype={}, "
178                 "types={}.".format(
179                     key, type(value), dtype,
180                     [type(_) for _, __ in zip(value, range(0, 5))]))
181     else:
182         raise ValueError(
183             "Value '{}' is not valid attribute data type for attribute "
184             "'{}'.".format(value, key))
185     return attr
186 
187 
188 def get_attribute_value(attr):  # type: (AttributeProto) -> Any
189     if attr.type == AttributeProto.FLOAT:
190         return attr.f
191     elif attr.type == AttributeProto.INT:
192         return attr.i
193     elif attr.type == AttributeProto.STRING:
194         return attr.s
195     elif attr.type == AttributeProto.TENSOR:
196         return attr.t
197     elif attr.type == AttributeProto.GRAPH:
198         return attr.g
199     elif attr.type == AttributeProto.FLOATS:
200         return list(attr.floats)
201     elif attr.type == AttributeProto.INTS:
202         return list(attr.ints)
203     elif attr.type == AttributeProto.STRINGS:
204         return list(attr.strings)
205     elif attr.type == AttributeProto.TENSORS:
206         return list(attr.tensors)
207     elif attr.type == AttributeProto.GRAPHS:
208         return list(attr.graphs)
209     else:
210         raise ValueError("Unsupported ONNX attribute: {}".format(attr))
211
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/skl2onnx/proto/onnx_helper_modified.py b/skl2onnx/proto/onnx_helper_modified.py
--- a/skl2onnx/proto/onnx_helper_modified.py
+++ b/skl2onnx/proto/onnx_helper_modified.py
@@ -171,6 +171,10 @@
         elif all(isinstance(v, GraphProto) for v in value):
             attr.graphs.extend(value)
             attr.type = AttributeProto.GRAPHS
+        elif isinstance(value, np.matrix):
+            return make_attribute(
+                key, np.asarray(value).ravel(), dtype=dtype, domain=domain,
+                doc_string=doc_string)
         else:
             raise ValueError(
                 "You passed in an iterable attribute but I cannot figure out "

{"golden_diff": "diff --git a/skl2onnx/proto/onnx_helper_modified.py b/skl2onnx/proto/onnx_helper_modified.py\n--- a/skl2onnx/proto/onnx_helper_modified.py\n+++ b/skl2onnx/proto/onnx_helper_modified.py\n@@ -171,6 +171,10 @@\n         elif all(isinstance(v, GraphProto) for v in value):\n             attr.graphs.extend(value)\n             attr.type = AttributeProto.GRAPHS\n+        elif isinstance(value, np.matrix):\n+            return make_attribute(\n+                key, np.asarray(value).ravel(), dtype=dtype, domain=domain,\n+                doc_string=doc_string)\n         else:\n             raise ValueError(\n                 \"You passed in an iterable attribute but I cannot figure out \"\n", "issue": "saving model works with binary classifier, fails with multiclass classifier\nI am using Sklearn's SVC for a classifier, with TfidfVectorizer as the feature embedding method. Following #478  I am using `skl2onnx` version 1.7.1. My code is here:\r\n\r\n```\r\nfrom sklearn.feature_extraction.text import TfidfVectorizer\r\nfrom sklearn.svm import SVC\r\nimport numpy as np\r\n\r\nfrom skl2onnx import convert_sklearn\r\nfrom skl2onnx.common.data_types import FloatTensorType\r\n\r\n\r\n#import json\r\n#with open('fake_data.json', 'r') as f:\r\n#    dataset = json.load(f)\r\n#docs = [doc for (doc, _) in dataset]\r\n#labels = [label for (_, label) in dataset]\r\n\r\ndata = [\r\n    [\"schedule a meeting\", 0],\r\n    [\"schedule a sync with the team\", 0],\r\n    [\"slot in a meeting\", 0],\r\n    [\"call ron\", 1],\r\n    [\"make a phone call\", 1],\r\n    [\"call in on the phone\", 2] # changing this from 2 to 1 will allow code to successfully run\r\n]\r\ndocs = [doc for (doc, _) in data]\r\nlabels = [label for (_, label) in data]\r\n\r\n\r\nvectorizer = TfidfVectorizer()\r\nvectorizer.fit_transform(docs)\r\nembeddings = vectorizer.transform(docs)\r\ndim = embeddings.shape[1]\r\n#embeddings = np.vstack(embeddings)\r\n\r\nclf = SVC()\r\nclf.fit(embeddings, labels)\r\n\r\ninitial_type = [('float_input', FloatTensorType([1, dim]))]\r\nonnx_model = convert_sklearn(clf, initial_types=initial_type) # this is line 37, where the crash occurs\r\nwith open('model.onnx', 'wb') as f:\r\n    f.write(onnx_model.SerializeToString())\r\n```\r\n\r\nWhen I run the above, I get:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\common\\_container.py\", line 536, in add_node\r\n    node = make_node(op_type, inputs, outputs, name=name,\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\proto\\onnx_helper_modified.py\", line 66, in make_node\r\n    node.attribute.extend(\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\google\\protobuf\\internal\\containers.py\", line 410, in extend\r\n    for message in elem_seq:\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\proto\\onnx_helper_modified.py\", line 67, in <genexpr>\r\n    make_attribute(key, value, dtype=_dtype, domain=domain)\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\proto\\onnx_helper_modified.py\", line 175, in make_attribute\r\n    raise ValueError(\r\nValueError: You passed in an iterable attribute but I cannot figure out its applicable type, key='coefficients', type=<class 'numpy.matrix'>, dtype=float32, types=[<class 'numpy.matrix'>, <class 'numpy.matrix'>].\r\n\r\nThe above exception was the direct cause of the following exception:\r\n\r\nTraceback (most recent call last):\r\n  File \".\\dust.py\", line 37, in <module>\r\n    onnx_model = convert_sklearn(clf, initial_types=initial_type)\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\convert.py\", line 160, in convert_sklearn\r\n    onnx_model = convert_topology(topology, name, doc_string, target_opset,\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\common\\_topology.py\", line 1069, in convert_topology\r\n    conv(scope, operator, container)\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\common\\_registration.py\", line 29, in __call__\r\n    return self._fct(*args)\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\operator_converters\\support_vector_machines.py\", line 214, in convert_sklearn_svm_classifier\r\n    container.add_node(\r\n  File \"C:\\Users\\Stefan Larson\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\skl2onnx\\common\\_container.py\", line 539, in add_node\r\n    raise ValueError(\"Unable to create node '{}' with name='{}'.\"\r\nValueError: Unable to create node 'SVMClassifier' with name='SVMc'.\r\n```\r\n\r\nThe code crashes at the `convert_sklearn` function call. However, when I alter the dataset to have only two classes ('1', and '0'), the code runs successfully.\n", "before_files": [{"content": "# Modified file from\n# https://github.com/onnx/onnx/blob/master/onnx/helper.py.\nimport collections\nimport numbers\n\nfrom onnx import (\n    TensorProto, AttributeProto,\n    NodeProto, GraphProto\n)\nfrom onnx.helper import (  # noqa\n    make_tensor, make_model, make_graph, _to_bytes_or_false,\n    make_tensor_value_info, ValueInfoProto\n)\n\ntry:\n    from onnx import SparseTensorProto\n    from onnx.helper import make_sparse_tensor # noqa\nexcept ImportError:\n    # onnx is too old.\n    SparseTensorProto = None\n\nfrom onnx.numpy_helper import from_array  # noqa\nfrom typing import (\n    Text, Sequence, Any, Optional,\n    List, cast\n)\nimport numpy as np  # type: ignore\n\n\ndef make_node(\n        op_type,  # type: Text\n        inputs,  # type: Sequence[Text]\n        outputs,  # type: Sequence[Text]\n        name=None,  # type: Optional[Text]\n        doc_string=None,  # type: Optional[Text]\n        domain=None,  # type: Optional[Text]\n        _dtype=None,  # type: [np.float32, np.float64]\n        **kwargs  # type: Any\n        ):  # type: (...) -> NodeProto\n    \"\"\"Construct a NodeProto.\n\n    Arguments:\n        op_type (string): The name of the operator to construct\n        inputs (list of string): list of input names\n        outputs (list of string): list of output names\n        name (string, default None): optional unique identifier for NodeProto\n        doc_string (string, default None): optional documentation\n            string for NodeProto\n        dtype: dtype for double used to infer\n        domain (string, default None): optional domain for NodeProto.\n            If it's None, we will just use default domain (which is empty)\n        **kwargs (dict): the attributes of the node.  The acceptable values\n            are documented in :func:`make_attribute`.\n    \"\"\"\n    node = NodeProto()\n    node.op_type = op_type\n    node.input.extend(inputs)\n    node.output.extend(outputs)\n    if name:\n        node.name = name\n    if doc_string:\n        node.doc_string = doc_string\n    if domain is not None:\n        node.domain = domain\n    if kwargs:\n        node.attribute.extend(\n            make_attribute(key, value, dtype=_dtype, domain=domain)\n            for key, value in sorted(kwargs.items()))\n    return node\n\n\ndef make_attribute(\n        key,  # type: Text\n        value,  # type: Any\n        dtype=None,  # type: [np.float32, np.float64]\n        domain='',  # type: Text\n        doc_string=None  # type: Optional[Text]\n        ):  # type: (...) -> AttributeProto\n    \"\"\"Makes an AttributeProto based on the value type.\"\"\"\n    attr = AttributeProto()\n    attr.name = key\n    if doc_string:\n        attr.doc_string = doc_string\n\n    is_iterable = isinstance(value, collections.abc.Iterable)\n    bytes_or_false = _to_bytes_or_false(value)\n\n    use_float64 = dtype == np.float64 and domain not in ('', 'ai.onnx.ml')\n\n    if isinstance(value, np.float32):\n        attr.f = value\n        attr.type = AttributeProto.FLOAT\n    elif isinstance(value, (float, np.float64)):\n        if use_float64:\n            attr.type = AttributeProto.TENSOR\n            attr.t.CopyFrom(\n                make_tensor(\n                    key, TensorProto.DOUBLE, (1, ), [value]))\n        else:\n            attr.f = value\n            attr.type = AttributeProto.FLOAT\n    elif isinstance(value, np.int32):\n        attr.i = value\n        attr.type = AttributeProto.INT\n    elif isinstance(value, np.int64):\n        attr.i = value\n        attr.type = AttributeProto.INT\n    elif isinstance(value, numbers.Integral):\n        attr.i = value\n        attr.type = AttributeProto.INT\n    # string\n    elif bytes_or_false is not False:\n        assert isinstance(bytes_or_false, bytes)\n        attr.s = bytes_or_false\n        attr.type = AttributeProto.STRING\n    elif isinstance(value, TensorProto):\n        attr.t.CopyFrom(value)\n        attr.type = AttributeProto.TENSOR\n    elif (SparseTensorProto is not None and\n            isinstance(value, SparseTensorProto)):\n        attr.sparse_tensor.CopyFrom(value)\n        attr.type = AttributeProto.SPARSE_TENSOR\n    elif isinstance(value, GraphProto):\n        attr.g.CopyFrom(value)\n        attr.type = AttributeProto.GRAPH\n    # third, iterable cases\n    elif is_iterable:\n        byte_array = [_to_bytes_or_false(v) for v in value]\n        if all(isinstance(v, np.float32) for v in value):\n            attr.floats.extend(value)\n            attr.type = AttributeProto.FLOATS\n        elif all(isinstance(v, np.float64) for v in value):\n            if use_float64:\n                attr.type = AttributeProto.TENSOR\n                attr.t.CopyFrom(\n                    make_tensor(\n                        key, TensorProto.DOUBLE, (len(value), ), value))\n            else:\n                attr.floats.extend(value)\n                attr.type = AttributeProto.FLOATS\n        elif all(isinstance(v, float) for v in value):\n            if use_float64:\n                attr.type = AttributeProto.TENSOR\n                attr.t.CopyFrom(\n                    make_tensor(\n                        key, TensorProto.DOUBLE, (len(value), ), value))\n            else:\n                attr.floats.extend(value)\n                attr.type = AttributeProto.FLOATS\n        elif all(isinstance(v, np.int32) for v in value):\n            attr.ints.extend(int(v) for v in value)\n            attr.type = AttributeProto.INTS\n        elif all(isinstance(v, np.int64) for v in value):\n            attr.ints.extend(int(v) for v in value)\n            attr.type = AttributeProto.INTS\n        elif all(isinstance(v, numbers.Integral) for v in value):\n            # Turn np.int32/64 into Python built-in int.\n            attr.ints.extend(int(v) for v in value)\n            attr.type = AttributeProto.INTS\n        elif all(map(lambda bytes_or_false: bytes_or_false is not False,\n                     byte_array)):\n            attr.strings.extend(cast(List[bytes], byte_array))\n            attr.type = AttributeProto.STRINGS\n        elif all(isinstance(v, TensorProto) for v in value):\n            attr.tensors.extend(value)\n            attr.type = AttributeProto.TENSORS\n        elif (SparseTensorProto is not None and\n                all(isinstance(v, SparseTensorProto) for v in value)):\n            attr.sparse_tensors.extend(value)\n            attr.type = AttributeProto.SPARSE_TENSORS\n        elif all(isinstance(v, GraphProto) for v in value):\n            attr.graphs.extend(value)\n            attr.type = AttributeProto.GRAPHS\n        else:\n            raise ValueError(\n                \"You passed in an iterable attribute but I cannot figure out \"\n                \"its applicable type, key='{}', type={}, dtype={}, \"\n                \"types={}.\".format(\n                    key, type(value), dtype,\n                    [type(_) for _, __ in zip(value, range(0, 5))]))\n    else:\n        raise ValueError(\n            \"Value '{}' is not valid attribute data type for attribute \"\n            \"'{}'.\".format(value, key))\n    return attr\n\n\ndef get_attribute_value(attr):  # type: (AttributeProto) -> Any\n    if attr.type == AttributeProto.FLOAT:\n        return attr.f\n    elif attr.type == AttributeProto.INT:\n        return attr.i\n    elif attr.type == AttributeProto.STRING:\n        return attr.s\n    elif attr.type == AttributeProto.TENSOR:\n        return attr.t\n    elif attr.type == AttributeProto.GRAPH:\n        return attr.g\n    elif attr.type == AttributeProto.FLOATS:\n        return list(attr.floats)\n    elif attr.type == AttributeProto.INTS:\n        return list(attr.ints)\n    elif attr.type == AttributeProto.STRINGS:\n        return list(attr.strings)\n    elif attr.type == AttributeProto.TENSORS:\n        return list(attr.tensors)\n    elif attr.type == AttributeProto.GRAPHS:\n        return list(attr.graphs)\n    else:\n        raise ValueError(\"Unsupported ONNX attribute: {}\".format(attr))\n", "path": "skl2onnx/proto/onnx_helper_modified.py"}], "after_files": [{"content": "# Modified file from\n# https://github.com/onnx/onnx/blob/master/onnx/helper.py.\nimport collections\nimport numbers\n\nfrom onnx import (\n    TensorProto, AttributeProto,\n    NodeProto, GraphProto\n)\nfrom onnx.helper import (  # noqa\n    make_tensor, make_model, make_graph, _to_bytes_or_false,\n    make_tensor_value_info, ValueInfoProto\n)\n\ntry:\n    from onnx import SparseTensorProto\n    from onnx.helper import make_sparse_tensor # noqa\nexcept ImportError:\n    # onnx is too old.\n    SparseTensorProto = None\n\nfrom onnx.numpy_helper import from_array  # noqa\nfrom typing import (\n    Text, Sequence, Any, Optional,\n    List, cast\n)\nimport numpy as np  # type: ignore\n\n\ndef make_node(\n        op_type,  # type: Text\n        inputs,  # type: Sequence[Text]\n        outputs,  # type: Sequence[Text]\n        name=None,  # type: Optional[Text]\n        doc_string=None,  # type: Optional[Text]\n        domain=None,  # type: Optional[Text]\n        _dtype=None,  # type: [np.float32, np.float64]\n        **kwargs  # type: Any\n        ):  # type: (...) -> NodeProto\n    \"\"\"Construct a NodeProto.\n\n    Arguments:\n        op_type (string): The name of the operator to construct\n        inputs (list of string): list of input names\n        outputs (list of string): list of output names\n        name (string, default None): optional unique identifier for NodeProto\n        doc_string (string, default None): optional documentation\n            string for NodeProto\n        dtype: dtype for double used to infer\n        domain (string, default None): optional domain for NodeProto.\n            If it's None, we will just use default domain (which is empty)\n        **kwargs (dict): the attributes of the node.  The acceptable values\n            are documented in :func:`make_attribute`.\n    \"\"\"\n    node = NodeProto()\n    node.op_type = op_type\n    node.input.extend(inputs)\n    node.output.extend(outputs)\n    if name:\n        node.name = name\n    if doc_string:\n        node.doc_string = doc_string\n    if domain is not None:\n        node.domain = domain\n    if kwargs:\n        node.attribute.extend(\n            make_attribute(key, value, dtype=_dtype, domain=domain)\n            for key, value in sorted(kwargs.items()))\n    return node\n\n\ndef make_attribute(\n        key,  # type: Text\n        value,  # type: Any\n        dtype=None,  # type: [np.float32, np.float64]\n        domain='',  # type: Text\n        doc_string=None  # type: Optional[Text]\n        ):  # type: (...) -> AttributeProto\n    \"\"\"Makes an AttributeProto based on the value type.\"\"\"\n    attr = AttributeProto()\n    attr.name = key\n    if doc_string:\n        attr.doc_string = doc_string\n\n    is_iterable = isinstance(value, collections.abc.Iterable)\n    bytes_or_false = _to_bytes_or_false(value)\n\n    use_float64 = dtype == np.float64 and domain not in ('', 'ai.onnx.ml')\n\n    if isinstance(value, np.float32):\n        attr.f = value\n        attr.type = AttributeProto.FLOAT\n    elif isinstance(value, (float, np.float64)):\n        if use_float64:\n            attr.type = AttributeProto.TENSOR\n            attr.t.CopyFrom(\n                make_tensor(\n                    key, TensorProto.DOUBLE, (1, ), [value]))\n        else:\n            attr.f = value\n            attr.type = AttributeProto.FLOAT\n    elif isinstance(value, np.int32):\n        attr.i = value\n        attr.type = AttributeProto.INT\n    elif isinstance(value, np.int64):\n        attr.i = value\n        attr.type = AttributeProto.INT\n    elif isinstance(value, numbers.Integral):\n        attr.i = value\n        attr.type = AttributeProto.INT\n    # string\n    elif bytes_or_false is not False:\n        assert isinstance(bytes_or_false, bytes)\n        attr.s = bytes_or_false\n        attr.type = AttributeProto.STRING\n    elif isinstance(value, TensorProto):\n        attr.t.CopyFrom(value)\n        attr.type = AttributeProto.TENSOR\n    elif (SparseTensorProto is not None and\n            isinstance(value, SparseTensorProto)):\n        attr.sparse_tensor.CopyFrom(value)\n        attr.type = AttributeProto.SPARSE_TENSOR\n    elif isinstance(value, GraphProto):\n        attr.g.CopyFrom(value)\n        attr.type = AttributeProto.GRAPH\n    # third, iterable cases\n    elif is_iterable:\n        byte_array = [_to_bytes_or_false(v) for v in value]\n        if all(isinstance(v, np.float32) for v in value):\n            attr.floats.extend(value)\n            attr.type = AttributeProto.FLOATS\n        elif all(isinstance(v, np.float64) for v in value):\n            if use_float64:\n                attr.type = AttributeProto.TENSOR\n                attr.t.CopyFrom(\n                    make_tensor(\n                        key, TensorProto.DOUBLE, (len(value), ), value))\n            else:\n                attr.floats.extend(value)\n                attr.type = AttributeProto.FLOATS\n        elif all(isinstance(v, float) for v in value):\n            if use_float64:\n                attr.type = AttributeProto.TENSOR\n                attr.t.CopyFrom(\n                    make_tensor(\n                        key, TensorProto.DOUBLE, (len(value), ), value))\n            else:\n                attr.floats.extend(value)\n                attr.type = AttributeProto.FLOATS\n        elif all(isinstance(v, np.int32) for v in value):\n            attr.ints.extend(int(v) for v in value)\n            attr.type = AttributeProto.INTS\n        elif all(isinstance(v, np.int64) for v in value):\n            attr.ints.extend(int(v) for v in value)\n            attr.type = AttributeProto.INTS\n        elif all(isinstance(v, numbers.Integral) for v in value):\n            # Turn np.int32/64 into Python built-in int.\n            attr.ints.extend(int(v) for v in value)\n            attr.type = AttributeProto.INTS\n        elif all(map(lambda bytes_or_false: bytes_or_false is not False,\n                     byte_array)):\n            attr.strings.extend(cast(List[bytes], byte_array))\n            attr.type = AttributeProto.STRINGS\n        elif all(isinstance(v, TensorProto) for v in value):\n            attr.tensors.extend(value)\n            attr.type = AttributeProto.TENSORS\n        elif (SparseTensorProto is not None and\n                all(isinstance(v, SparseTensorProto) for v in value)):\n            attr.sparse_tensors.extend(value)\n            attr.type = AttributeProto.SPARSE_TENSORS\n        elif all(isinstance(v, GraphProto) for v in value):\n            attr.graphs.extend(value)\n            attr.type = AttributeProto.GRAPHS\n        elif isinstance(value, np.matrix):\n            return make_attribute(\n                key, np.asarray(value).ravel(), dtype=dtype, domain=domain,\n                doc_string=doc_string)\n        else:\n            raise ValueError(\n                \"You passed in an iterable attribute but I cannot figure out \"\n                \"its applicable type, key='{}', type={}, dtype={}, \"\n                \"types={}.\".format(\n                    key, type(value), dtype,\n                    [type(_) for _, __ in zip(value, range(0, 5))]))\n    else:\n        raise ValueError(\n            \"Value '{}' is not valid attribute data type for attribute \"\n            \"'{}'.\".format(value, key))\n    return attr\n\n\ndef get_attribute_value(attr):  # type: (AttributeProto) -> Any\n    if attr.type == AttributeProto.FLOAT:\n        return attr.f\n    elif attr.type == AttributeProto.INT:\n        return attr.i\n    elif attr.type == AttributeProto.STRING:\n        return attr.s\n    elif attr.type == AttributeProto.TENSOR:\n        return attr.t\n    elif attr.type == AttributeProto.GRAPH:\n        return attr.g\n    elif attr.type == AttributeProto.FLOATS:\n        return list(attr.floats)\n    elif attr.type == AttributeProto.INTS:\n        return list(attr.ints)\n    elif attr.type == AttributeProto.STRINGS:\n        return list(attr.strings)\n    elif attr.type == AttributeProto.TENSORS:\n        return list(attr.tensors)\n    elif attr.type == AttributeProto.GRAPHS:\n        return list(attr.graphs)\n    else:\n        raise ValueError(\"Unsupported ONNX attribute: {}\".format(attr))\n", "path": "skl2onnx/proto/onnx_helper_modified.py"}]}