onnx.reference

DefaultNone

class onnx.reference.op_run.DefaultNone[原始碼]

當參數未設定但運算子對其具有預設行為時,參數的預設值。

ReferenceEvaluator

class onnx.reference.ReferenceEvaluator(proto: Any, opsets: dict[str, int] | None = None, functions: list[ReferenceEvaluator | FunctionProto] | None = None, verbose: int = 0, new_ops: list[OpRun] | None = None, optimized: bool = True)[原始碼]

計算 ONNX 原型 (ModelProtoFunctionProtoGraphProtoNodeProto) 的輸出。

這是 ONNX 規格的純 Python 實作。官方規格與此處的實作之間可能仍存在不匹配之處。如果發生此類不匹配,則以官方規格為準,覆蓋此實作。

參數:
  • protoonnx.ModelProtoonnx.GraphProtoonnx.FunctionProtoonnx.NodeProto、檔名或位元組

  • verbose – 在執行期間於標準輸出上顯示中間結果

  • opsets – 如果 protoGraphProto 的執行個體,則 opsets 必須由以下字典定義

  • functions – 已知的 onnx 函式

  • new_ops – 此執行階段可用於測試新運算子的實作,new_ops 是衍生自 OpRun 的類別清單,每個類別都必須定義靜態屬性 domain,同一個運算子可能會有多個實作,清單中的第一個實作會被使用。

  • optimized – 有些運算子有兩種實作,一個是符合運算子數學定義的簡單實作,另一個是更有效率的實作。Conv 運算子即為如此。簡單版本比使用分解為 Conv = im2col + Gemm 的最佳化版本慢十倍。如果為 True,則所有最佳化的核心都會新增至 new_ops,並且會取代內部實作 (如果清單 new_ops 尚未包含一個)。

此類別會將每個節點對應到其相關的實作。當遇到函式的子圖時,它會使用此類別來執行子圖或函式。下一個範例顯示如何使用儲存在檔案 model.onnx 中的 onnx 模型來執行 ReferenceEvaluator

import numpy as np
from onnx.reference import ReferenceEvaluator

X = np.array(...)
sess = ReferenceEvaluator("model.onnx")
results = sess.run(None, {"X": X})
print(results[0])  # display the first result

參數 verbose 可用於顯示中間結果。

import numpy as np
from onnx.reference import ReferenceEvaluator

X = np.array(...)
sess = ReferenceEvaluator("model.onnx", verbose=1)
results = sess.run(None, {"X": X})
print(results[0])  # display the first result

此類別可以使用 ops 資料夾中任何可用的實作。新增實作需要進行兩個變更。第一個是實作本身。任何現有的節點都可以作為範本。第二個是在 _op_list.py 檔案中加入一行,以匯入該檔案並讓參考評估器知道它的存在。

此類別也可用於測試自訂運算子的實作。假設這個新的運算子是來自 custom 網域的 InvAlpha。實作必須在繼承自 OpRun 的類別中進行。它還必須定義屬性 op_domain。以下是一個計算 \(\\frac{1}{X + \\alpha}\) 的範例。

from onnx.reference.op_run import OpRun

class InvAlpha(OpRun):

    op_domain = "custom"

    def _run(self, x, alpha=None):  # type: ignore
        # None must be the default value, it is automatically
        # replaced by class OpRun with either the default value
        # specified in the NodeProto or an attribute value defined
        # in a `FunctionProto`.
        return (1 / (x + alpha),)

alpha 是一個屬性。它可以由 onnx 節點定義,也可以由使用此節點的函數定義。可以安全地假設屬性與輸入同時已知。類別 ReferenceEvaluator 必須知道這個新的實作,這可以透過指定的參數 new_ops 來完成。

sess = ReferenceEvaluator(onnx_model, new_ops=[InvAlpha])
got = sess.run(None, {"X": x})[0]

可以簡單地評估一個特定的節點。

import numpy as np
from onnx.reference.ops._op_list import Celu

x = np.array([[0, 1], [-1, 2]], dtype=np.float32)
y = Celu.eval(x, alpha=0.5)
print(y)
[[ 0.          1.        ]
 [-0.43233237  2.        ]]

這也可以表示為

import numpy as np
from onnx.reference.ops import load_op

Celu = load_op("", "Celu")  # domain is ""
x = np.array([[0, 1], [-1, 2]], dtype=np.float32)
y = Celu.eval(x, alpha=0.5)
print(y)
[[ 0.          1.        ]
 [-0.43233237  2.        ]]

可以覆寫現有的運算子。類別名稱必須相同。預設網域不需要指定網域。但是,預設情況下,類別 OpRun 會載入此運算子的最新版本。可以透過新增 OpSchema 類型的靜態屬性 op_schema 來明確指定。

from onnx.reference.op_run.op_conv import Conv as _Conv

class Conv(_Conv):

    op_schema = instance_of_OpSchema()

    def _run(self, ...):
        ...

An operator may be different in a later opset. In that case,
a new implementation needs to be registered. `Pad_11`, `Pad_18`.
`Pad_11` is the implementation chose for opset in [11, 17].
`Pad_18` is selected for any greater opset. Both classes must be
imported into file `_op_list.py` to register their existence to the
runtime.

An operator may have a reference implementation such as `CastLike`
and still be defined as a function. By default, the reference implementation
is used. This behavior can be changed by adding a class to the list
of overwritten operators. It must inherit from :class:`OpRunExpand`.

::

    from onnx.reference.op_run import OpRunExpand

    class CastLike(OpRunExpand):
        op_domain = ""

    ref = ReferenceEvaluator(model, new_ops=[CastLike])
    # ...

    This mechanism is used in unit test to check the function
    implementation a schema may define.
property input_names

傳回輸入名稱。

property opsets

傳回 opsets。

property output_names

傳回輸出名稱。

run(output_names, feed_inputs: dict[str, Any], attributes: dict[str, Any] | None = None, intermediate: bool = False) dict[str, Any] | list[Any][原始碼]

執行 onnx 模型。

參數:
  • output_names – 依名稱要求的輸出,若為 None 則代表全部

  • feed_inputs – 字典 { 輸入名稱: 輸入值 }

  • attributes – 如果執行個體執行 FunctionProto,則為屬性值

  • intermediate – 如果為 True,則此函數會傳回所有結果,包括最終結果和中間結果在同一個字典中;如果為 False,則只會以清單形式傳回最終結果

傳回:

如果 intermediate 為 False,則傳回要求的輸出清單,否則以字典形式傳回具名結果

OpFunction

class onnx.reference.op_run.OpFunction(onnx_node: NodeProto, run_params: dict[str, Any] | None, impl: Any | None = None, attributes: dict[str, Any] | None = None)[原始碼]

執行自訂函數。

classmethod create(n_inputs: int | None = None, n_outputs: int | None = None, verbose: int = 0, **kwargs: Any) Any

根據給定的資訊實例化此類別。

參數:
  • n_inputs – 輸入數量(預設值由運算子架構定義)

  • n_outputs – 輸出數量(預設值由運算子架構定義)

  • verbose – 詳細程度

  • **kwargs – 節點屬性

傳回:

NodeProto

property domain: str

傳回節點屬性 domain

classmethod eval(*args: list[Any], n_outputs: int | None = None, verbose: int = 0, **kwargs: Any) Any

評估此運算子。

參數:
  • *args – 輸入

  • n_outputs – 輸出數量(預設值由運算子架構定義)

  • verbose – 詳細程度

  • **kwargs – 節點屬性

傳回:

NodeProto

static implicit_inputs(graph: GraphProto) list[str]

傳回所有未註冊為輸入,且非由圖形內節點產生的變數。這些輸入是呼叫此圖形的上下文中存在的一部分。

property input: Iterable[str]

傳回節點屬性 input

classmethod make_node(n_inputs: int | None = None, n_outputs: int | None = None, **kwargs: Any) NodeProto

根據給定的資訊,為此類別建立 ONNX 節點。

參數:
  • n_inputs – 輸入數量(預設值由運算子架構定義)

  • n_outputs – 輸出數量(預設值由運算子架構定義)

  • verbose – 詳細程度

  • **kwargs – 節點屬性

傳回:

NodeProto

方法 eval 會建立由方法 make_node 傳回的 onnx 節點。

import numpy as np
from onnx.reference.ops._op_list import Celu

onnx_node = Celu.make_node(alpha=0.5)
print(onnx_node)
input: "x0"
output: "y0"
op_type: "Celu"
attribute {
  name: "alpha"
  f: 0.5
  type: FLOAT
}
need_context() bool

告訴執行階段,此節點是否需要上下文(目前為止產生的所有結果),因為它可能會靜默地存取其中一個結果(運算子 Scan、If、Loop)。預設答案為 False

property output: Iterable[str]

傳回節點屬性 output

run(*args, linked_attributes=None, context=None)

呼叫方法 _run,捕捉例外,顯示較長的錯誤訊息。

參數:
  • *args – 輸入

  • linked_attributes – 如果此節點具有連結至它所屬函數的屬性,則會使用此屬性

  • context – 如果此節點是子圖的一部分,則 context 是包含此節點可能會使用的值的字典

傳回:

結果的元組

OpRun

class onnx.reference.op_run.OpRun(onnx_node: NodeProto, run_params: dict[str, Any], schema: Any | None = None)[原始碼]

此子資料夾中所有運算子的祖先。

參數:
  • onnx_nodeonnx 節點

  • run_params – 其他參數,例如 verboseopsets(如果運算子有子圖,則可以有多個)、log 用於記錄函數

  • schema – 運算子結構描述

classmethod create(n_inputs: int | None = None, n_outputs: int | None = None, verbose: int = 0, **kwargs: Any) Any[原始碼]

根據給定的資訊實例化此類別。

參數:
  • n_inputs – 輸入數量(預設值由運算子架構定義)

  • n_outputs – 輸出數量(預設值由運算子架構定義)

  • verbose – 詳細程度

  • **kwargs – 節點屬性

傳回:

NodeProto

屬性 domain: str

傳回節點屬性 domain

類別方法 eval(*args: list[Any], n_outputs: int | None = None, verbose: int = 0, **kwargs: Any) Any[原始碼]

評估此運算子。

參數:
  • *args – 輸入

  • n_outputs – 輸出數量(預設值由運算子架構定義)

  • verbose – 詳細程度

  • **kwargs – 節點屬性

傳回:

NodeProto

靜態方法 implicit_inputs(graph: GraphProto) list[str][原始碼]

傳回所有未註冊為輸入,且非由圖形內節點產生的變數。這些輸入是呼叫此圖形的上下文中存在的一部分。

屬性 input: Iterable[str]

傳回節點屬性 input

類別方法 make_node(n_inputs: int | None = None, n_outputs: int | None = None, **kwargs: Any) NodeProto[原始碼]

根據給定的資訊,為此類別建立 ONNX 節點。

參數:
  • n_inputs – 輸入數量(預設值由運算子架構定義)

  • n_outputs – 輸出數量(預設值由運算子架構定義)

  • verbose – 詳細程度

  • **kwargs – 節點屬性

傳回:

NodeProto

方法 eval 會建立由方法 make_node 傳回的 onnx 節點。

import numpy as np
from onnx.reference.ops._op_list import Celu

onnx_node = Celu.make_node(alpha=0.5)
print(onnx_node)
input: "x0"
output: "y0"
op_type: "Celu"
attribute {
  name: "alpha"
  f: 0.5
  type: FLOAT
}
need_context() bool[原始碼]

告訴執行階段,此節點是否需要上下文(目前為止產生的所有結果),因為它可能會靜默地存取其中一個結果(運算子 Scan、If、Loop)。預設答案為 False

屬性 output: Iterable[str]

傳回節點屬性 output

run(*args, linked_attributes=None, context=None)[原始碼]

呼叫方法 _run,捕捉例外,顯示較長的錯誤訊息。

參數:
  • *args – 輸入

  • linked_attributes – 如果此節點具有連結至它所屬函數的屬性,則會使用此屬性

  • context – 如果此節點是子圖的一部分,則 context 是包含此節點可能會使用的值的字典

傳回:

結果的元組

RuntimeTypeError

類別 onnx.reference.op_run.RuntimeTypeError[原始碼]

當變數的類型與預期不符時引發。

SparseTensor

類別 onnx.reference.op_run.SparseTensor(values: ndarray, indices: ndarray, shape: tuple[int])[原始碼]

稀疏張量的簡單表示。它基於 numpy,但不需要 scipy。