rockchip-linux / rknn-toolkit

BSD 3-Clause "New" or "Revised" License
832 stars 175 forks source link

Does rknn-toolkit support model conversion from sklearn to rknn ? #247

Open serkanpeldek opened 2 years ago

serkanpeldek commented 2 years ago

I am trying to convert sklearn model to rknn. For conversion I follow sklearn -> ONNX -> RKNN exchage. my code is here:

import numpy as np
import os

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import metrics
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as rt
from rknn.api import RKNN
from sklearn.ensemble import RandomForestClassifier
QUANTIZE_ON = False
DATASET = 'dataset.txt'

if __name__  ==  '__main__':
    iris = load_iris()
    X, y = iris.data, iris.target
    X_train, X_test, y_train, y_test = train_test_split(X, y)

    clf = RandomForestClassifier()
    clf.fit(X_train, y_train)
    y_test_pred = clf.predict(X_test)

    onnx_model = "{}.onnx".format(clf.__class__.__name__)
    initial_type = [('float_input', FloatTensorType([1, 4]))]
    onx = convert_sklearn(clf, initial_types=initial_type)

    with open(onnx_model, "wb") as f:
        f.write(onx.SerializeToString())

    sess = rt.InferenceSession(onnx_model)
    input_name = sess.get_inputs()[0].name
    outut_name = sess.get_outputs()[0].name
    print("input_name:", input_name, " outut_name:", outut_name)

    pred_onx = list()
    for test_sample in X_test:
        pred = sess.run([outut_name], {input_name: [test_sample.astype(np.float32)]})[0]
        pred_onx.append(pred)

    clf_name = clf.__class__.__name__
    print(f"{clf_name} sklearn acc:", metrics.accuracy_score(y_test, y_test_pred))
    print("onnx acc:", metrics.accuracy_score(y_test, pred_onx))

    rknn = RKNN()

    if not os.path.exists(onnx_model):
        print('model not exist')
        exit(-1)

    # pre-process config
    print('--> Config model')
    rknn.config(
                target_platform = 'rv1126'
                quantize_input_node=QUANTIZE_ON)
    print('done')

    # Load ONNX model
    print('--> Loading model')
    ret = rknn.load_onnx(model=onnx_model,outputs=["output_label"])
    if ret != 0:
        print(f'Load {clf_name} failed!')
        exit(ret)
    print('done')

    # Build model
    print('--> Building model')
    ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET)
    if ret != 0:
        print(f'Build {clf_name} failed!')
        exit(ret)
    print('done')

    rknn_model = onnx_model.replace(".onnx", ".rknn")
    # Export RKNN model
    print('--> Export RKNN model')
    ret = rknn.export_rknn(rknn_model)
    if ret != 0:
        print(f'Export {clf_name} rknn failed!')
        exit(ret)
    print('done')

Error output: input_name: float_input outut_name: output_label RandomForestClassifier sklearn acc: 0.9210526315789473 onnx acc: 0.9210526315789473

/home/user/.local/lib/python3.6/site-packages/requests/init.py:91: RequestsDependencyWarning: urllib3 (1.26.8) or chardet (4.0.0) doesn't match a supported version! RequestsDependencyWarning) --> Config model done --> Loading model E Calc node TreeEnsembleClassifier : TreeEnsembleClassifier output shape fail E Catch exception when loading onnx model: RandomForestClassifier.onnx! E Traceback (most recent call last): E File "rknn/base/RKNNlib/onnx_ir/onnx_numpy_backend/shape_inference.py", line 65, in rknn.base.RKNNlib.onnx_ir.onnx_numpy_backend.shape_inference.infer_shape E KeyError: 'TreeEnsembleClassifier' E During handling of the above exception, another exception occurred: E Traceback (most recent call last): E File "rknn/base/RKNNlib/app/importer/import_onnx.py", line 118, in rknn.base.RKNNlib.app.importer.import_onnx.Importonnx.run E File "rknn/base/RKNNlib/converter/convert_onnx.py", line 112, in rknn.base.RKNNlib.converter.convert_onnx.convert_onnx.init E File "rknn/base/RKNNlib/converter/convert_onnx.py", line 1062, in rknn.base.RKNNlib.converter.convert_onnx.convert_onnx._shape_inference E File "rknn/base/RKNNlib/onnx_ir/onnx_numpy_backend/shape_inference.py", line 70, in rknn.base.RKNNlib.onnx_ir.onnx_numpy_backend.shape_inference.infer_shape E File "rknn/api/rknn_log.py", line 323, in rknn.api.rknn_log.RKNNLog.e E ValueError: Calc node TreeEnsembleClassifier : TreeEnsembleClassifier output shape fail ... Load RandomForestClassifier failed!

log_feedback_to_the_rknn_toolkit_dev_team.log

@Caesar-github @JeffyCN

serkanpeldek commented 2 years ago

@shaojun do you have suggestions?

marty1885 commented 1 year ago

I know this is an old issue. But I have made a toolkit to solve this exact issue. It's for rknn-toolkit2 though. You might need to adapt it.

https://github.com/marty1885/scirknn