0

我正在尝试将 sklearn SVC 模型转换/存储为 .onnx 文件,但出现我不理解的运行时错误。我已经能够通过 sklearn 随机森林分类器和 sklearn k-NN 分类器有效地使用相同的代码而不会出错。我收到一个奇怪的 onnx 运行时错误,我不明白。对此错误的任何帮助表示赞赏。

下面我首先发布了运行我的文件 svm_time.py 的输出,然后在下面发布了包含在 svm_time.py 文件中的代码。

谢谢。

python3 svm_time.py 
'train_model'  4809.58 ms
train score is:  0.8765468473777254
val Accuracy is:  0.7037037037037037
Traceback (most recent call last):
  File "svm_time.py", line 97, in <module>
    main()
  File "svm_time.py", line 91, in main
    onx = convert_sklearn(clf, initial_types=initial_type)
  File "/home/matt/anaconda3/envs/venv/lib/python3.7/site-packages/skl2onnx/convert.py", line 154, in convert_sklearn
    dtype=dtype, options=options)
  File "/home/matt/anaconda3/envs/venv/lib/python3.7/site-packages/skl2onnx/common/_topology.py", line 1054, in convert_topology
    conv(scope, operator, container)
  File "/home/matt/anaconda3/envs/venv/lib/python3.7/site-packages/skl2onnx/common/_registration.py", line 29, in __call__
    return self._fct(*args)
  File "/home/matt/anaconda3/envs/venv/lib/python3.7/site-packages/skl2onnx/operator_converters/support_vector_machines.py", line 221, in convert_sklearn_svm_classifier
    "Classes different from first n integers are not supported "
RuntimeError: Classes different from first n integers are not supported in SVC converter.

from sklearn.preprocessing import StandardScaler
import pandas as pd
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
import numpy as np
from sklearn.model_selection import train_test_split

import time
import math
import numpy as np

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


#https://medium.com/pythonhive/python-decorator-to-measure-the-execution-time-of-methods-fa04cb6bb36d
def timeit(method):
    def timed(*args, **kw):
        ts = time.time()
        result = method(*args, **kw)
        te = time.time()

        if 'log_time' in kw:
            name = kw.get('log_name', method.__name__.upper())
            kw['log_time'][name] = int((te - ts) * 1000)
        else:
            print('%r  %2.2f ms' %
                  (method.__name__, (te - ts) * 1000))
        return result

    return timed



clf = SVC(kernel='rbf', gamma=0.001, C=10)



@timeit
def train_model(in_data,in_labels):

    clf.fit(in_data,in_labels)


def main():

    data = pd.read_csv('fall_data.csv', header=None)

    labels = pd.read_csv('fall_labels.csv', header=None)

    data = data.to_numpy()

    data_labels = labels[0]

    train_set, test_set, train_label, test_label = train_test_split(
    data, data_labels, test_size=0.1, random_state=42)

    train_set2, val_set, train_label2, val_label = train_test_split(
    train_set, train_label, test_size=0.1, random_state=42)

    scaler = StandardScaler().fit(train_set2)

    X_train = scaler.transform(train_set2)

    X_val = scaler.transform(val_set)

    train_model(X_train,train_label2)

    tpred = clf.predict(X_train)

    ts = accuracy_score(train_label2, tpred)

    print('train score is: ', ts)

    pred = clf.predict(X_val)
    s = accuracy_score(val_label, pred)

    print('val Accuracy is: ', s)


    initial_type = [('float_input', FloatTensorType([None, 453]))]
    onx = convert_sklearn(clf, initial_types=initial_type)
    with open("svmrbf_unimib_f8.onnx", "wb") as f:
        f.write(onx.SerializeToString())


if __name__ == '__main__':
    main()

4

1 回答 1

0

在我看来,这可能是与 Onnx 和 sklearn 的兼容性问题。

1)。https://github.com/onnx/sklearn-onnx/issues/302 2)。https://github.com/onnx/sklearn-onnx/blob/master/skl2onnx/operator_converters/support_vector_machines.py#L17

基于这两个来源,我更改了我的代码以包含 OVO 决策函数形状而不是 OVR,现在,至少当我运行我的 svm_time.py 文件时,保存了一个 .onnx 文件。


clf = SVC(kernel='rbf', gamma=0.001, C=10, decision_function_shape='ovo')

于 2020-08-19T22:53:50.110 回答