注意
前往結尾以下載完整的範例程式碼
onnxruntime 的錯誤¶
使用 onnxruntime 可能會發生許多錯誤。此範例探討了幾個常見情況,在這些情況下,onnxruntime 不會傳回模型預測,而是引發例外。它首先載入一個模型(請參閱 訓練、轉換和預測模型),該模型產生在 Iris 資料集上訓練的邏輯迴歸。該模型採用 2 維向量,並在三個類別中傳回一個類別。
import skl2onnx
import onnx
import sklearn
import onnxruntime as rt
import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
try:
from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument
except ImportError:
# onnxruntime <= 0.5
InvalidArgument = RuntimeError
data = load_iris()
clr = LogisticRegression().fit(data.data[:, :2], data.target)
with open("logreg_iris.onnx", "wb") as f:
f.write(
skl2onnx.to_onnx(
clr, data.data[:, :2].astype(np.float32), target_opset=12
).SerializeToString()
)
example2 = "logreg_iris.onnx"
sess = rt.InferenceSession(example2, providers=["CPUExecutionProvider"])
input_name = sess.get_inputs()[0].name
output_name = sess.get_outputs()[0].name
第一個範例因 錯誤的類型 而失敗。onnxruntime 只預期單精度浮點數(4 個位元組),無法處理任何其他類型的浮點數。
try:
x = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]], dtype=np.float64)
sess.run([output_name], {input_name: x})
except Exception as e:
print("Unexpected type")
print("{0}: {1}".format(type(e), e))
Unexpected type
<class 'onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument'>: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Unexpected input data type. Actual: (tensor(double)) , expected: (tensor(float))
如果名稱拼寫錯誤,則模型無法傳回輸出。
try:
x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
sess.run(["misspelled"], {input_name: x})
except Exception as e:
print("Misspelled output name")
print("{0}: {1}".format(type(e), e))
Misspelled output name
<class 'onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument'>: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid Output Name:misspelled
輸出名稱是可選的,可以用 None 取代,onnxruntime 接著會傳回所有輸出。
x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
res = sess.run(None, {input_name: x})
print("All outputs")
print(res)
All outputs
[array([0, 0, 0], dtype=int64), [{0: 0.9999734163284302, 1: 2.656836477399338e-05, 2: 5.484377840758725e-09}, {0: 0.9999914169311523, 1: 8.446793799521402e-06, 2: 1.7366836857490853e-07}, {0: 0.9999918341636658, 1: 2.6854097541217925e-06, 2: 5.499288818100467e-06}]]
如果輸入名稱拼寫錯誤,也是一樣的情況。
try:
x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
sess.run([output_name], {"misspelled": x})
except Exception as e:
print("Misspelled input name")
print("{0}: {1}".format(type(e), e))
Misspelled input name
<class 'ValueError'>: Required inputs (['X']) are missing from input feed (['misspelled']).
如果輸入維度是預期輸入維度的倍數,onnxruntime 不一定會失敗。
for x in [
np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32),
np.array([[1.0, 2.0, 3.0, 4.0]], dtype=np.float32),
np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32),
np.array([1.0, 2.0, 3.0], dtype=np.float32),
np.array([[1.0, 2.0, 3.0]], dtype=np.float32),
]:
try:
r = sess.run([output_name], {input_name: x})
print("Shape={0} and predicted labels={1}".format(x.shape, r))
except (RuntimeError, InvalidArgument) as e:
print("Shape={0} and error={1}".format(x.shape, e))
for x in [
np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32),
np.array([[1.0, 2.0, 3.0, 4.0]], dtype=np.float32),
np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32),
np.array([1.0, 2.0, 3.0], dtype=np.float32),
np.array([[1.0, 2.0, 3.0]], dtype=np.float32),
]:
try:
r = sess.run(None, {input_name: x})
print("Shape={0} and predicted probabilities={1}".format(x.shape, r[1]))
except (RuntimeError, InvalidArgument) as e:
print("Shape={0} and error={1}".format(x.shape, e))
Shape=(4,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 4) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
index: 1 Got: 4 Expected: 2
Please fix either the inputs or the model.
Shape=(2, 2) and predicted labels=[array([0, 0], dtype=int64)]
Shape=(3,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 3) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
index: 1 Got: 3 Expected: 2
Please fix either the inputs or the model.
Shape=(4,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 4) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
index: 1 Got: 4 Expected: 2
Please fix either the inputs or the model.
Shape=(2, 2) and predicted probabilities=[{0: 0.9999734163284302, 1: 2.656836477399338e-05, 2: 5.484377840758725e-09}, {0: 0.9999914169311523, 1: 8.446793799521402e-06, 2: 1.7366836857490853e-07}]
Shape=(3,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 3) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
index: 1 Got: 3 Expected: 2
Please fix either the inputs or the model.
如果維度的數量高於預期,它也不會失敗,但會產生警告。
for x in [
np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=np.float32),
np.array([[[1.0, 2.0, 3.0]]], dtype=np.float32),
np.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=np.float32),
]:
try:
r = sess.run([output_name], {input_name: x})
print("Shape={0} and predicted labels={1}".format(x.shape, r))
except (RuntimeError, InvalidArgument) as e:
print("Shape={0} and error={1}".format(x.shape, e))
Shape=(1, 2, 2) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 3 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 1, 3) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 3 Expected: 2 Please fix either the inputs or the model.
Shape=(2, 1, 2) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 3 Expected: 2 Please fix either the inputs or the model.
此範例使用的版本
print("numpy:", np.__version__)
print("scikit-learn:", sklearn.__version__)
print("onnx: ", onnx.__version__)
print("onnxruntime: ", rt.__version__)
print("skl2onnx: ", skl2onnx.__version__)
numpy: 1.23.5
scikit-learn: 1.4.dev0
onnx: 1.15.0
onnxruntime: 1.16.0+cu118
skl2onnx: 1.16.0
腳本的總執行時間: (0 分鐘 0.054 秒)