注意
转到结尾 下载完整的示例代码
转换时的黑名单操作符¶
某些运行时没有为 ONNX 中每个可用的操作符实现运行时。转换器不知道这一点,但可以将某些操作符列入黑名单。大多数转换器不会更改其行为,如果它们使用黑名单中的操作符,则会失败,其中一些会生成不同的 ONNX 图。
高斯混合模型¶
第一个根据操作符黑名单更改其行为的转换器是用于模型 高斯混合模型 的转换器。
from timeit import timeit
import numpy
from onnxruntime import InferenceSession
from sklearn.mixture import GaussianMixture
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from skl2onnx import to_onnx
data = load_iris()
X_train, X_test = train_test_split(data.data)
model = GaussianMixture()
model.fit(X_train)
默认转换¶
model_onnx = to_onnx(
model,
X_train[:1].astype(numpy.float32),
options={id(model): {"score_samples": True}},
target_opset=12,
)
sess = InferenceSession(
model_onnx.SerializeToString(), providers=["CPUExecutionProvider"]
)
xt = X_test[:5].astype(numpy.float32)
print(model.score_samples(xt))
print(sess.run(None, {"X": xt})[2])
[-1.87252497 -1.34625882 -3.3789712 -2.51747032 -2.11219732]
[[-1.8725252]
[-1.3462601]
[-3.3789716]
[-2.51747 ]
[-2.112197 ]]
不使用 ReduceLogSumExp 的转换¶
参数 black_op 用于告诉转换器不要使用此操作符。让我们看看在这种情况下转换器会产生什么。
model_onnx2 = to_onnx(
model,
X_train[:1].astype(numpy.float32),
options={id(model): {"score_samples": True}},
black_op={"ReduceLogSumExp"},
target_opset=12,
)
sess2 = InferenceSession(
model_onnx2.SerializeToString(), providers=["CPUExecutionProvider"]
)
xt = X_test[:5].astype(numpy.float32)
print(model.score_samples(xt))
print(sess2.run(None, {"X": xt})[2])
[-1.87252497 -1.34625882 -3.3789712 -2.51747032 -2.11219732]
[[-1.8725252]
[-1.3462601]
[-3.3789716]
[-2.51747 ]
[-2.112197 ]]
处理时间¶
0.5201874999997926
0.4130731999998716
使用 ReduceLogSumExp 的模型速度快得多。
如果转换器无法在不...¶
许多转换器不考虑操作符的白名单和黑名单。如果转换器无法在不使用黑名单操作符(或仅使用白名单操作符)的情况下进行转换,则 skl2onnx 会引发错误。
try:
to_onnx(
model,
X_train[:1].astype(numpy.float32),
options={id(model): {"score_samples": True}},
black_op={"ReduceLogSumExp", "Add"},
target_opset=12,
)
except RuntimeError as e:
print("Error:", e)
Error: Operator 'Add' is black listed.
脚本的总运行时间:(0 分钟 1.122 秒)