0

I am trying to convert / store a sklearn SVC model as a .onnx file and I am getting a runtime error I do not understand. I have been able to use this same code effectively without error with a sklearn random forest classifier and a sklearn k-NN classifier. I am getting a strange onnx runtime error that I do not understand. Any help with this error is appreciated.

Below I first posted the output of running my file svm_time.py and then below that included the code that is included in the svm_time.py file.

Thanks.

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()

Matt Ward
  • 85
  • 1
  • 9

1 Answers1

0

It seems to me that this may be a compatibility issue with Onnx and 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

Based on these two sources I changed my code to include the OVO decision function shape instead of OVR and now, at-least when I run my svm_time.py file an .onnx file is saved.


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

Matt Ward
  • 85
  • 1
  • 9