onnx.reference¶
默认无¶
参考评估器¶
- 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原型的输出(ModelProto,FunctionProto,GraphProto,NodeProto)。
这是ONNX规范的纯Python实现。官方规范与此处的实现之间可能存在不匹配。在这种情况下,以官方规范为准。
- Parameters:
proto –
onnx.ModelProto,onnx.GraphProto,onnx.FunctionProto,onnx.NodeProto, 文件名或字节verbose – 在执行期间在标准输出上显示中间结果
opsets – 如果 proto 是 GraphProto 的实例,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 以导入文件并让参考评估器知道它的存在。
这个类也可以用来测试自定义操作符的实现。假设这个新操作符是来自域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¶
返回操作集。
- 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:
节点原型
- 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]¶
返回所有未注册为输入且不由图中节点生成的变量。这些输入是调用此图的图中现有上下文的一部分。
- 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 }
- 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_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]¶
根据给定的信息实例化此类。
- Parameters:
n_inputs – 输入数量(默认值由操作符模式定义)
n_outputs – 输出的数量(默认值由操作符模式定义)
verbose – 详细程度
**kwargs – 节点属性
- Returns:
节点原型
- 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]¶
返回所有未注册为输入且不由图中节点生成的变量。这些输入是调用此图的图中现有上下文的一部分。
- 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 }