当前位置: 首页 > news >正文

网站建设山西建设网站公司招聘

网站建设山西,建设网站公司招聘,用asp.net做校园网站,深圳专业建站系统建站公司onnx作为一个通用格式,很少有中文教程,因此开一篇文章对onnx 1.16文档进行翻译与进一步解释, onnx 1.16官方文档:https://onnx.ai/onnx/intro/index.html](https://onnx.ai/onnx/intro/index.html), 如果觉得有收获&am…

onnx作为一个通用格式,很少有中文教程,因此开一篇文章对onnx 1.16文档进行翻译与进一步解释,
onnx 1.16官方文档:https://onnx.ai/onnx/intro/index.html](https://onnx.ai/onnx/intro/index.html),
如果觉得有收获,麻烦点赞收藏关注,目前仅在CSDN发布,本博客会分为多个章节,目前尚在连载中,详见专栏链接:
https://blog.csdn.net/qq_33345365/category_12581965.html

开始编辑时间:2024/2/27;最后编辑时间:2024/2/27。

这是本教程的第七篇,其余内容见上述专栏链接。


ONNX with Python

本教程的第一篇:介绍了ONNX的基本概念。

在本教程的第二篇,介绍了ONNX关于Python的API,具体涉及一个简单的线性回归例子和序列化。

本教程的第三篇,包括python API的三个部分:初始化器Initializer;属性Attributes;算子集和元数据Opset和Metadata

本教程的第四篇,包括子图的两个内容,使用If和Scan算子实现子图的选择和循环。

本教程的第五篇,包括函数,模型解析域形状推理。

本教程的第六篇:包括求值:即实现模型的计算与其他的一些实现细节。

在本教程,会简单的一览ONNX现有的API。


Python API一览

完整的的API描述见API Reference,后续的教程可能会进一步的进行介绍。

01 加载ONNX模型

import onnxonnx_model = onnx.load("path/to/the/model.onnx")

02 带有外部数据时加载ONNX模型

如果外部数据在模型的相同目录,则简单的使用onnx.load即可.

import onnxonnx_model = onnx.load("path/to/the/model.onnx")

如果外部数据在其他目录,使用load_external_data_for_model()来指定目录路径,并在onnx.load之后加载。

import onnx
from onnx.external_data_helper import load_external_data_for_modelonnx_model = onnx.load("path/to/the/model.onnx", load_external_data=False)
load_external_data_for_model(onnx_model, "data/directory/path/")

03 将ONNX模型转换为外部数据

from onnx.external_data_helper import convert_model_to_external_data# onnx_model是一个内存中的ModelProto
onnx_model = ...
convert_model_to_external_data(onnx_model, all_tensors_to_one_file=True, location="filename", size_threshold=1024, convert_attribute=False)
# 然后onnx_model已经将原始数据转换为外部数据;# 必须在后面保存模型

04 存储ONNX模型

import onnx# onnx_model是一个内存中的ModelProto
onnx_model = ...# 保存ONNX模型
onnx.save(onnx_model, "path/to/the/model.onnx")

05 转换并保存ONNX模型到一个外部数据

import onnx# onnx_model是一个内存中的ModelProto
onnx_model = ...
onnx.save_model(onnx_model, "path/to/save/the/model.onnx", save_as_external_data=True, all_tensors_to_one_file=True, location="filename", size_threshold=1024, convert_attribute=False)
# 然后onnx_model将原始数据转换为外部数据并保存到特定目录

06 操作TensorProto和Numpy数组

import numpy
import onnx
from onnx import numpy_helper# 预处理: 创建一个Numpy数组
numpy_array = numpy.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=float)
print(f"Original Numpy array:\n{numpy_array}\n")# 将Numpy数组转换成一个TensorProto
tensor = numpy_helper.from_array(numpy_array)
print(f"TensorProto:\n{tensor}")# 转换TensorProto成一个Numpy数组
new_array = numpy_helper.to_array(tensor)
print(f"After round trip, Numpy array:\n{new_array}\n")# 保存TensorProto
with open("tensor.pb", "wb") as f:f.write(tensor.SerializeToString())# 加载TensorProto
new_tensor = onnx.TensorProto()
with open("tensor.pb", "rb") as f:new_tensor.ParseFromString(f.read())
print(f"After saving and loading, new TensorProto:\n{new_tensor}")from onnx import TensorProto, helper# ONNX IR上映射属性的实用格式转换技巧;以下函数在ONNX 1.13之后可用
np_dtype = helper.tensor_dtype_to_np_dtype(TensorProto.FLOAT)
print(f"The converted numpy dtype for {helper.tensor_dtype_to_string(TensorProto.FLOAT)} is {np_dtype}.")
storage_dtype = helper.tensor_dtype_to_storage_tensor_dtype(TensorProto.FLOAT)
print(f"The storage dtype for {helper.tensor_dtype_to_string(TensorProto.FLOAT)} is {helper.tensor_dtype_to_string(storage_dtype)}.")
field_name = helper.tensor_dtype_to_field(TensorProto.FLOAT)
print(f"The field name for {helper.tensor_dtype_to_string(TensorProto.FLOAT)} is {field_name}.")
tensor_dtype = helper.np_dtype_to_tensor_dtype(np_dtype)
print(f"The tensor data type for numpy dtype: {np_dtype} is {helper.tensor_dtype_to_string(tensor_dtype)}.")for tensor_dtype in helper.get_all_tensor_dtypes():print(helper.tensor_dtype_to_string(tensor_dtype))

输出:

Original Numpy array:
[[1. 2. 3.][4. 5. 6.]]TensorProto:
dims: 2
dims: 3
data_type: 11
raw_data: "\000\000\000\000\000\000\360?\000\000\000\000\000\000\000@\000\000\000\000\000\000\010@\000\000\000\000\000\000\020@\000\000\000\000\000\000\024@\000\000\000\000\000\000\030@"After round trip, Numpy array:
[[1. 2. 3.][4. 5. 6.]]After saving and loading, new TensorProto:
dims: 2
dims: 3
data_type: 11
raw_data: "\000\000\000\000\000\000\360?\000\000\000\000\000\000\000@\000\000\000\000\000\000\010@\000\000\000\000\000\000\020@\000\000\000\000\000\000\024@\000\000\000\000\000\000\030@"The converted numpy dtype for TensorProto.FLOAT is float32.
The storage dtype for TensorProto.FLOAT is TensorProto.FLOAT.
The field name for TensorProto.FLOAT is float_data.
The tensor data type for numpy dtype: float32 is TensorProto.FLOAT.
TensorProto.FLOAT
TensorProto.UINT8
TensorProto.INT8
TensorProto.UINT16
TensorProto.INT16
TensorProto.INT32
TensorProto.INT64
TensorProto.BOOL
TensorProto.FLOAT16
TensorProto.BFLOAT16
TensorProto.DOUBLE
TensorProto.COMPLEX64
TensorProto.COMPLEX128
TensorProto.UINT32
TensorProto.UINT64
TensorProto.STRING
TensorProto.FLOAT8E4M3FN
TensorProto.FLOAT8E4M3FNUZ
TensorProto.FLOAT8E5M2
TensorProto.FLOAT8E5M2FNUZ

07 使用Helper函数创建ONNX模型

import onnx
from onnx import helper
from onnx import AttributeProto, TensorProto, GraphProto# 创建输入(ValueInfoProto)
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [3, 2])
pads = helper.make_tensor_value_info("pads", TensorProto.FLOAT, [1, 4])
value = helper.make_tensor_value_info("value", AttributeProto.FLOAT, [1])# 创建输出(ValueInfoProto)
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [3, 4])# 创建节点(NodeProto)
node_def = helper.make_node("Pad",                  # name["X", "pads", "value"], # inputs["Y"],                  # outputsmode="constant",        # attributes
)# 创建图(GraphProto)
graph_def = helper.make_graph([node_def],        # nodes"test-model",      # name[X, pads, value],  # inputs[Y],               # outputs
)# 创建模型(ModelProto)
model_def = helper.make_model(graph_def, producer_name="onnx-example")# 检查模型
onnx.checker.check_model(model_def)
print("The model is checked!")

08 ONNX IR上映射属性的转换实用技术

from onnx import TensorProto, helpernp_dtype = helper.tensor_dtype_to_np_dtype(TensorProto.FLOAT)
print(f"The converted numpy dtype for {helper.tensor_dtype_to_string(TensorProto.FLOAT)} is {np_dtype}.")field_name = helper.tensor_dtype_to_field(TensorProto.FLOAT)
print(f"The field name for {helper.tensor_dtype_to_string(TensorProto.FLOAT)} is {field_name}.")
# 在helper中还有其它转换函数

输出是:

The converted numpy dtype for TensorProto.FLOAT is float32.
The field name for TensorProto.FLOAT is float_data.

09 检查ONNX模型

Onnx提供了一个函数来检查模型是否有效。当它检测到不一致时,它会检查输入类型或形状。

import onnx# 预处理: 加载ONNX模型
model_path = "path/to/the/model.onnx"
onnx_model = onnx.load(model_path)print(f"The model is:\n{onnx_model}")# 检查模型
try:onnx.checker.check_model(onnx_model)
except onnx.checker.ValidationError as e:print(f"The model is invalid: {e}")
else:print("The model is valid!")

10 检查大于2GB的ONNX模型

当前检查器支持使用外部数据检查模型,但对于那些大于2GB的模型,请使用onnx的模型路径,而不是内存中的模型。Checker和外部数据需要在同一个目录下。

import onnxonnx.checker.check_model("path/to/the/model.onnx")
# onnx.checker.check_model(loaded_onnx_model)在模型大于2GB时会出错

11 在一个ONNX模型上执行形状推理

import onnx
from onnx import helper, shape_inference
from onnx import TensorProto# 预处理: 创建一个有两个节点的模型, Y的形状未知
node1 = helper.make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])
node2 = helper.make_node("Transpose", ["Y"], ["Z"], perm=[1, 0, 2])graph = helper.make_graph([node1, node2],"two-transposes",[helper.make_tensor_value_info("X", TensorProto.FLOAT, (2, 3, 4))],[helper.make_tensor_value_info("Z", TensorProto.FLOAT, (2, 3, 4))],
)original_model = helper.make_model(graph, producer_name="onnx-examples")# 检查模型并打印出Y的形状信息
onnx.checker.check_model(original_model)
print(f"Before shape inference, the shape info of Y is:\n{original_model.graph.value_info}")# 在模型上应用形状推理
inferred_model = shape_inference.infer_shapes(original_model)# 检查模型并打印出Y的形状信息
onnx.checker.check_model(inferred_model)
print(f"After shape inference, the shape info of Y is:\n{inferred_model.graph.value_info}")

输出是:

Before shape inference, the shape info of Y is:
[]
After shape inference, the shape info of Y is:
[name: "Y"
type {tensor_type {elem_type: 1shape {dim {dim_value: 3}dim {dim_value: 2}dim {dim_value: 4}}}
}
]

12 对一个大于2GB模型进行形状推理

当前的shape_inference支持具有外部数据的模型,但对于那些大于2GB的模型,请使用onnx.shape_inference的模型路径。Infer_shapes_path和外部数据需要位于同一目录下。你可以指定保存推断出的模型的输出路径;否则,默认输出路径与原始模型路径相同。

import onnx# 将推断出的模型输出到原始模型路径
onnx.shape_inference.infer_shapes_path("path/to/the/model.onnx")# 将推断出的模型输出到指定的模型路径
onnx.shape_inference.infer_shapes_path("path/to/the/model.onnx", "output/inferred/model.onnx")# inferred_model = onnx.shape_inference.infer_shapes(loaded_onnx_model)  # 在模型大于2GB会报错

13 在ONNX函数上执行类型推断

import onnx
import onnx.helper
import onnx.parser
import onnx.shape_inferencefunction_text = """<opset_import: [ "" : 18 ], domain: "local">CastTo <dtype> (x) => (y) {y = Cast <to : int = @dtype> (x)}
"""
function = onnx.parser.parse_function(function_text)# 上面的函数有一个输入参数x和一个属性参数dtype。
# 要对该函数应用“类型与形状推断”,必须提供输入参数的类型和属性参数的属性值,如下所示:
float_type_ = onnx.helper.make_tensor_type_proto(1, None)
dtype_6 = onnx.helper.make_attribute("dtype", 6)
result = onnx.shape_inference.infer_function_output_types(function, [float_type_], [dtype_6]
)
print(result) # a list containing the (single) output type

输出:

[tensor_type {elem_type: 6
}
]

14 转换默认域("“或"ai.onnx”)上ONNX模型的opset版本

import onnx
from onnx import version_converter, helper# 预处理: 加载待转换的模型
model_path = "path/to/the/model.onnx"
original_model = onnx.load(model_path)print(f"The model before conversion:\n{original_model}")# 进行版本转换
converted_model = version_converter.convert_version(original_model, <int target_version>)print(f"The model after conversion:\n{converted_model}")

15 实用函数:使用输入张量名称和输出张量名称提取子模型

函数extract_model()可以从一个ONNX模型中提取子模型,可以使用输入张量名称和输出张量名称提取子模型。

import onnxinput_path = "path/to/the/original/model.onnx"
output_path = "path/to/save/the/extracted/model.onnx"  # 提取模型保存到的路径
input_names = ["input_0", "input_1", "input_2"]
output_names = ["output_0", "output_1"]onnx.utils.extract_model(input_path, output_path, input_names, output_names)

注意:对于控制流操作,例如 If 和 Loop,子模型的边界,即由输入和输出张量定义的边界,不应穿过作为这些操作符属性连接到主图的子图。

16 实用函数:onnx.compose

onnx.compose 模块提供工具来创建结合的模型。

onnx.compose.merge_models可以用于合并两个模型,方法是将第一个模型的某些输出连接到第二个模型的输入。默认情况下,io_map参数中不存在的输入/输出将保留为合并模型的输入/输出。

在这个例子中,我们通过将第一个模型的每个输出连接到第二个模型中的一个输入来合并两个模型。得到的模型将具有与第一个模型相同的输入和与第二个模型相同的输出。

import onnxmodel1 = onnx.load("path/to/model1.onnx")
# agraph (float[N] A, float[N] B) => (float[N] C, float[N] D)
#   {
#      C = Add(A, B)
#      D = Sub(A, B)
#   }model2 = onnx.load("path/to/model2.onnx")
#   agraph (float[N] X, float[N] Y) => (float[N] Z)
#   {
#      Z = Mul(X, Y)
#   }combined_model = onnx.compose.merge_models(model1, model2,io_map=[("C", "X"), ("D", "Y")]  # c->x; d ->y
)

此外,用户可以指定一个输入/输出列表,以包含在组合模型中,有效地舍弃了对组合模型输出没有贡献的图的部分。在下面的示例中,我们只将第一个模型中的两个输出中的一个连接到第二个模型中的两个输入。通过显式指定组合模型的输出,我们从第一个模型中丢弃了未使用的输出,以及图的相关部分。

import onnx# 默认例子. 在结合后的模型上包括所有输出
combined_model = onnx.compose.merge_models(model1, model2,io_map=[("C", "X"), ("C", "Y")],
)  # outputs: "D", "Z"# 显式输出. “Y”输出和子节点在组合模型中不存在
combined_model = onnx.compose.merge_models(model1, model2,io_map=[("C", "X"), ("C", "Y")],outputs=["Z"],
)  # outputs: "Z"

onnx.compose.add_prefix允许您向模型中的名称添加前缀,以避免在合并它们时发生名称冲突。默认情况下,它会重命名图中的所有名称:输入、输出、边、节点、初始化器、稀疏初始化器和值信息。

import onnxmodel = onnx.load("path/to/the/model.onnx")
# model - outputs: ["out0", "out1"], inputs: ["in0", "in1"]new_model = onnx.compose.add_prefix(model, prefix="m1/")
# new_model - outputs: ["m1/out0", "m1/out1"], inputs: ["m1/in0", "m1/in1"]# 也可以就地运行
onnx.compose.add_prefix(model, prefix="m1/", inplace=True)

onnx.compose.expand_out_dim 可以用来连接那些期望不同维度数量的模型,通过插入范围为一的维度。当结合一个产生样本的模型与一个处理样本批次的模型时,这会很有用。

import onnx# outputs: "out0", shape=[200, 200, 3]
model1 = onnx.load("path/to/the/model1.onnx")# outputs: "in0", shape=[N, 200, 200, 3]
model2 = onnx.load("path/to/the/model2.onnx")# outputs: "out0", shape=[1, 200, 200, 3]
new_model1 = onnx.compose.expand_out_dims(model1, dim_idx=0)# 模型现在可以合并了
combined_model = onnx.compose.merge_models(new_model1, model2, io_map=[("out0", "in0")]
)# 也可以就地执行
onnx.compose.expand_out_dims(model1, dim_idx=0, inplace=True)

17 更行模型的输入/输出维度大小

函数 update_inputs_outputs_dims 更新模型的输入和输出的维度,将其更新为参数中提供的值。可以通过使用 dim_param 提供静态和动态维度大小。在更新输入/输出大小之后,该函数运行模型检查器。

import onnx
from onnx.tools import update_model_dimsmodel = onnx.load("path/to/the/model.onnx")
# Here both "seq", "batch" and -1 are dynamic using dim_param.
variable_length_model = update_model_dims.update_inputs_outputs_dims(model, {"input_name": ["seq", "batch", 3, -1]}, {"output_name": ["seq", "batch", 1, -1]})

18 ONNX解析器

函数 onnx.parser.parse_modelonnx.parser.parse_graph 可以用来从文本表示中创建一个 ONNX 模型或图,如下所示。有关语言语法的更多详细信息,请参阅Language Syntax。

input = """agraph (float[N, 128] X, float[128, 10] W, float[10] B) => (float[N, 10] C){T = MatMul(X, W)S = Add(T, B)C = Softmax(S)}
"""
graph = onnx.parser.parse_graph(input)input = """<ir_version: 7,opset_import: ["" : 10]>agraph (float[N, 128] X, float[128, 10] W, float[10] B) => (float[N, 10] C){T = MatMul(X, W)S = Add(T, B)C = Softmax(S)}
"""
model = onnx.parser.parse_model(input)

19 ONNX Inliner

函数 onnx.inliner.inline_local_functionsinline_selected_functions 可用于在 ONNX 模型中内联模型本地函数。特别地,inline_local_functions 可用于生成一个无函数的模型(适用于不处理或不支持函数的后端)。另一方面,inline_selected_functions 可用于内联选定的函数。目前尚不支持内联 ONNX 标准操作中的函数(也称为模式定义(schema-defined)的函数)。

import onnx
import onnx.inlinermodel = onnx.load("path/to/the/model.onnx")
inlined = onnx.inliner.inline_local_functions(model)
onnx.save("path/to/the/inlinedmodel.onnx")
http://www.yayakq.cn/news/231837/

相关文章:

  • 商城用什么系统做网站网站内链检查
  • 网站 推送wordpress模版对主机要求
  • cc域名的网站WordPress建站如何解析
  • 文案网站编辑怎么做wordpress模板 图片站
  • 优质网站建设价格西安免费网站建站模板
  • 职高网站建设例题泉州网站制作推广
  • 极速建站个人博客主页代码
  • 墨星写作网站app下载wordpress分类目录在
  • 搞计算机网站建设会亏钱吗wordpress显示全部标签
  • 山东专业网站建设公司哪家好手机网站 微信网站 区别
  • 网站建设与管理实训课程网络专题的设计策划方案
  • 杭州网站建设招聘wordpress支付下载地址
  • 深圳市建网站公自己做网站系统教程
  • 运城网站制作云南seo
  • 网站建设的重难点分析wordpress自定义分类面包屑导航
  • 花园设计网站推荐wordpress账号会员制
  • 商务网站建设与维护课程跨境电商平台建设方案
  • 宝安网站建设-信科网络产品展示网站建设
  • 企业做网站需要什么手续吗昆明企业网站的建设
  • 公司网站制作步骤网站建设遵循的原则是什么
  • 济南市建设招标中心网站驻马店网站网站建设
  • 公司做网站需要几个人网站建设的上机报告
  • 郑州网站建设新闻校园网站建设计划
  • 怎样做手机网站建设定制营销型网站建设
  • 学校网站建设 分工wordpress 上线到centos
  • 赣州网站设计哪家强哪种公司一般会做网站
  • 本地手机网站建设网站建设 金疙瘩计划
  • 网站开发语言 asp公众号制作教程
  • 网站被k 但收录内页网站推广专员的岗位职责是什么
  • 电商做网站做母婴的网站