onnx.reference¶
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[type[OpRun]] | None = None, optimized: bool = True)[source]¶
计算 ONNX 原型(ModelProto、FunctionProto、GraphProto、NodeProto)的输出。
这是 ONNX 规范的纯 Python 实现。官方规范与此处实现之间可能存在不匹配。如果出现这种不匹配,以官方规范为准。
- 参数:
proto –
onnx.ModelProto
、onnx.GraphProto
、onnx.FunctionProto
、onnx.NodeProto
、文件名或字节verbose – 在执行期间在标准输出上显示中间结果
opsets – 如果 *proto* 是 *GraphProto* 的实例,则 opset 必须由字典定义
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): # 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] [source]¶
执行 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)[source]¶
运行自定义函数。
- 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
- 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] ¶
返回所有未注册为输入且未由图中节点生成的变量。这些输入是调用此图的图中存在的上下文的一部分。
- 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 }
- 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)[source]¶
此子文件夹中所有运算符的祖先。
- 参数:
onnx_node – onnx 节点
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]¶
根据给定信息实例化此类别。
- 参数:
n_inputs – 输入数量(默认由运算符模式定义)
n_outputs – 输出数量(默认由运算符模式定义)
verbose – 详细程度
**kwargs – 节点属性
- 返回:
NodeProto
- classmethod eval(*args: list[Any], n_outputs: int | None = None, verbose: int = 0, **kwargs: Any) Any [source]¶
评估此运算符。
- 参数:
*args – 输入
n_outputs – 输出数量(默认由运算符模式定义)
verbose – 详细程度
**kwargs – 节点属性
- 返回:
NodeProto
- static implicit_inputs(graph: GraphProto) list[str] [source]¶
返回所有未注册为输入且未由图中节点生成的变量。这些输入是调用此图的图中存在的上下文的一部分。
- classmethod make_node(n_inputs: int | None = None, n_outputs: int | None = None, **kwargs: Any) NodeProto [source]¶
根据给定信息为此类创建 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 }