onnx.reference

默认无

class onnx.reference.op_run.DefaultNone[source]

当参数未设置但操作符对其有默认行为时,参数的默认值。

参考评估器

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)[source]

计算ONNX原型的输出(ModelProtoFunctionProtoGraphProtoNodeProto)。

这是ONNX规范的纯Python实现。官方规范与此处的实现之间可能存在不匹配。在这种情况下,以官方规范为准。

Parameters:
  • protoonnx.ModelProto, onnx.GraphProto, onnx.FunctionProto, onnx.NodeProto, 文件名或字节

  • verbose – 在执行期间在标准输出上显示中间结果

  • opsets – 如果 protoGraphProto 的实例,opsets 必须 通过一个字典来定义

  • functions – 已知的onnx函数

  • new_ops – 此运行时可用于测试新操作符的实现,new_ops 是从 OpRun 派生的类列表,每个类必须定义静态属性 domain,同一个操作符可能有多个实现,列表中第一个被使用。

  • 优化 – 一些运算符有两个实现,一个是对应于运算符数学定义的简单实现,另一个是更高效的实现。这是运算符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 以导入文件并让参考评估器知道它的存在。

这个类也可以用来测试自定义操作符的实现。假设这个新操作符是来自域customInvAlpha。实现必须在一个继承自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

返回操作集。

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模型。

Parameters:
  • output_names – 按名称请求的输出,None 表示全部

  • feed_inputs – 字典 { 输入名称: 输入值 }

  • attributes – 如果实例运行的是 FunctionProto,则为属性值

  • intermediate – 如果为True,函数将返回所有结果,包括最终结果和中间结果,放在同一个字典中;如果为False,则只返回最终结果,放在一个列表中

Returns:

如果 intermediate 为 False,则列出请求的输出,否则在字典中命名结果

操作函数

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

根据给定的信息实例化此类。

Parameters:
  • n_inputs – 输入数量(默认值由操作符模式定义)

  • n_outputs – 输出的数量(默认值由操作符模式定义)

  • verbose – 详细程度

  • **kwargs – 节点属性

Returns:

节点原型

property domain: str

返回节点属性 domain

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

评估此操作符。

Parameters:
  • *args – 输入

  • n_outputs – 输出数量(默认值由操作符模式定义)

  • verbose – 详细程度

  • **kwargs – 节点属性

Returns:

节点原型

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节点。

Parameters:
  • n_inputs – 输入数量(默认值由操作符模式定义)

  • n_outputs – 输出数量(默认值由操作符模式定义)

  • verbose – 详细程度

  • **kwargs – 节点属性

Returns:

节点原型

方法 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

告诉运行时此节点是否需要上下文(到目前为止生成的所有结果),因为它可能会静默访问其中一个(操作符扫描、如果、循环)。 默认答案是False

property output: Iterable[str]

返回节点属性 output

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

调用方法 _run,捕获异常, 显示更长的错误信息。

Parameters:
  • *args – 输入

  • linked_attributes – 如果此属性与其所属函数的属性相关联,则使用此属性

  • context – 如果此节点是子图的一部分,context 是一个包含此节点可能使用的值的字典

Returns:

结果元组

OpRun

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

此子文件夹中所有操作符的祖先。

Parameters:
  • onnx_nodeonnx 节点

  • run_params – 额外的参数,例如 verbose, opsets (如果操作符有子图,则可能有多个), log 用于记录日志的函数

  • schema – 操作符模式

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

根据给定的信息实例化此类。

Parameters:
  • n_inputs – 输入数量(默认值由操作符模式定义)

  • n_outputs – 输出的数量(默认值由操作符模式定义)

  • verbose – 详细程度

  • **kwargs – 节点属性

Returns:

节点原型

property domain: str

返回节点属性 domain

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

评估此操作符。

Parameters:
  • *args – 输入

  • n_outputs – 输出的数量(默认值由操作符模式定义)

  • verbose – 详细程度

  • **kwargs – 节点属性

Returns:

节点原型

static implicit_inputs(graph: GraphProto) list[str][source]

返回所有未注册为输入且不由图中节点生成的变量。这些输入是调用此图的图中现有上下文的一部分。

property input: Iterable[str]

返回节点属性 input

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

根据给定的信息为此类创建一个ONNX节点。

Parameters:
  • n_inputs – 输入数量(默认值由操作符模式定义)

  • n_outputs – 输出的数量(默认值由操作符模式定义)

  • verbose – 详细程度

  • **kwargs – 节点属性

Returns:

节点原型

方法 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[source]

告诉运行时此节点是否需要上下文(到目前为止生成的所有结果),因为它可能会静默访问其中一个(操作符扫描、如果、循环)。 默认答案是False

property output: Iterable[str]

返回节点属性 output

run(*args, linked_attributes=None, context=None)[来源]

调用方法 _run,捕获异常, 显示更长的错误信息。

Parameters:
  • *args – 输入

  • linked_attributes – 如果此属性与其所属函数的属性相关联,则使用此属性

  • context – 如果此节点是子图的一部分,context 是一个包含此节点可能使用的值的字典

Returns:

结果元组

运行时类型错误

class onnx.reference.op_run.RuntimeTypeError[source]

当变量的类型不符合预期时引发。

稀疏张量

class onnx.reference.op_run.SparseTensor(values: ndarray, indices: ndarray, shape: tuple[int])[来源]

稀疏张量的简单表示。 它基于numpy,但不需要scipy。