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

淄博 建设网站wordpress获取用户信息

淄博 建设网站,wordpress获取用户信息,南昌做微网站,设计的网站都有哪些内容目录 前言0. 简述1. 执行一下我们的python程序2. ONNX是什么#xff1f;3. onnx中的各类Proto3.1 理解onnx中的ValueInfoProto3.2 理解onnx中的TensorProto3.3 理解onnx中的NodeProto3.4 理解onnx中的AttributeProto3.5 理解onnx中的GraphProto3.6 理解onnx中的ModelProto 4. … 目录 前言0. 简述1. 执行一下我们的python程序2. ONNX是什么3. onnx中的各类Proto3.1 理解onnx中的ValueInfoProto3.2 理解onnx中的TensorProto3.3 理解onnx中的NodeProto3.4 理解onnx中的AttributeProto3.5 理解onnx中的GraphProto3.6 理解onnx中的ModelProto 4. 根据onnx中的Proto信息创建onnx5. 根据onnx中的Proto信息读取onnx6. 根据onnx中的Proto信息修改onnx总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》链接。记录下个人学习笔记仅供自己参考 本次课程我们来学习课程第三章—TensorRT 基础入门一起来学习剖析 ONNX 并理解 Protobuf 课程大纲可以看下面的思维导图 0. 简述 本小节目标学习 ONNX 的 Proto 架构使用 onnx.helper 创建 onnx 修改 onnx 这节我们学习第三章节第五小节—剖析 onnx 架构并理解 ProtoBuf我们上一节学习了 Pytorch 模型导出 ONNX但如果我们想要更深层次的理解 ONNX 并创建 ONNX 修改 ONNX 的话就需要去理解 ONNX 数据结构是什么样子的所以也就引出了去理解 Protobuf 这个东西 本次课程学习完之后希望大家能够理解 ONNX 中的 Proto 架构并学会如何使用 onnx.helper 这个 Python API 去创建 ONNX、修改 ONNX 1. 执行一下我们的python程序 源代码获取地址https://github.com/kalfazed/tensorrt_starter 这个小节的案例主要是 3.3-read-and-parse-onnx如下所示 代码执行结果的一部分展示如下 在代码中我们会手动去创建一个 ONNX 而不是像之前那样导出 ONNX此外我们会加载创建的 ONNX 并读取里面的相关信息比如各个节点的权重信息输入输出信息等等实现一个简单的 parser 功能 2. ONNX是什么 我们先来看下 ONNX 是什么东西ONNX 是一种神经网络的格式采用 Protobuf 二进制形式进行序列化模型。Protobuf 全称叫做 Protocal Buffer 是 Google 提出来的一套表示和序列化数据的机制Protobuf 会根据用于定义的数据结构来进行序列化存储。 Protobuf的编译以及序列化流程 如果我们要用 protobuf 序列化存储数据的话首先我们得去定义 proto 这个概念它类似于一种数据结构像 ONNX 里面就有 graph 的 protograph 里面就有各种节点 node 的 proto 还有输入输出的 value 的 proto。根据定义的这些 proto 然后编译之后进行序列化这就是使用 protobuf 的整体的流程 言外之意就是说我们可以根据 ONNX 官方提供的数据结构信息去修改或者创建 onnx 下图是直接打印 ONNX 模型的 proto 信息可以看到 graph 里面有 nodenode 里面有 input、output、op_type 等等这些东西 3. onnx中的各类Proto onnx 的各类 proto 的定义需要看官方文档 https://github.com/onnx/onnx/tree/main这里面的 onnx/onnx.in.proto 定义了所有 onnx 的 Proto而有关 onnx 的 IRIntermediate Representation信息可以查看 https://github.com/onnx/onnx/blob/main/docs/IR.md onnx 中的组织结构可以分为如下几个层级 ModelProto描述的是整个模型的信息 GraphProto描述的是整个网络的信息 NodeProto描述的是各个计算节点比如 convlinearTensorProto描述的是 tensor 的信息主要包括权重ValueInfoProto描述的是 input/output 信息 下图展示的更加直观 我们先看下 GraphProto它的定义可以在 onnx/onnx.in.proto#L455 中找到如下图所示 GraphProto 描述的是整个模型的图结构可以看到它里面有 NodeProto、TensorProto、ValueInfoProto 等等下面我们一个个简单介绍下各个 Proto 补充IR (Intermediate Representation) 版本是什么意思呢和指令集 opset_version 一样指的是算子版本吗 IR (Intermediate Representation) 版本和 opset_version 是 ONNX 模型中的两个不同的概念分别代表不同的内容(form ChatGPT) IR (Intermediate Representation) 版本 定义IR 版本指定 ONNX 模型的整体格式版本。它描述了模型文件的结构和如何组织各个部分。作用它控制模型的元数据、图结构、节点之间的连接方式等。每次 ONNX 格式有较大改动时IR 版本号就会增加。更新IR 版本的更新通常涉及对模型文件格式的改进如支持新特性、增强兼容性或提升模型组织的灵活性。影响不同的 IR 版本可能影响模型的可读性和兼容性。例如某些工具或运行时环境可能只支持较低的 IR 版本。 opset_version (操作集版本) 定义opset_version 是 ONNX 中算子的版本号它描述了每个操作符算子的具体版本。作用控制算子如加法、卷积等的行为定义。每次某个算子的功能或参数发生变化时opset_version 就会增加。更新opset_version 的更新通常涉及特定算子的新特性、改进或修复。例如一个算子在新版本中可能增加了新的参数或优化了性能。影响模型中的每个算子都有一个 opset_version指定了该算子应遵循的版本定义。不同的 opset_version 可能影响模型的算子行为和兼容性。 总结起来 IR 版本影响整个模型的组织结构和格式。opset_version影响具体算子的定义和行为。 这两个版本是独立的但都对模型的兼容性和功能有重要影响。在使用 ONNX 模型时确保这两个版本与 ONNX Runtime 或其他工具的支持版本相匹配是很重要的。 3.1 理解onnx中的ValueInfoProto 首先我们来看 onnx 中的 ValueInfoProto 是什么ValueInfoProto 一般用来定义网络的 input/output会根据 input/output 的 type 来附加属性 大家可以在 onnx/onnx.in.proto#L188 中找到 ValueInfoProt 的定义如下图所示 它其实定义的内容比较少有 name、type 等等其中的 TypeProto 的定义如下 补充那其实我们在 ValueInfoProto 中还看到了 name 1type 2doc_string 3这些数字又代表什么含义呢 在 Protobuf 描述文件中input 1 和 output 2 是字段的标识符用于在二进制编码中标识字段的顺序和编号。这是 Protobuf 的一种机制用来高效地序列化和反序列化数据。具体解释如下(from ChatGPT) input 1 和 output 2 这些数字是字段编号用于在序列化时唯一标识字段。input 1 表示 input 字段在 Protobuf 编码中会使用编号 1。output 2 表示 output 字段在 Protobuf 编码中会使用编号 2。 Protobuf 编码中的字段编号 在 Protobuf 序列化过程中每个字段都会被编码为一个键值对其中键包括字段编号和字段类型。这样设计的目的是使得序列化的数据紧凑且高效便于解析和处理。 举例说明 假设有一个 NodeProto 实例 NodeProto {input: input_tensoroutput: output_tensorname: MyNodeop_type: Add }在 Protobuf 二进制编码中这些字段可能会被编码为类似于以下内容 input 字段会使用编号 1 编码例如1: input_tensoroutput 字段会使用编号 2 编码例如2: output_tensorname 字段会使用编号 3 编码例如3: MyNodeop_type 字段会使用编号 4 编码例如4: Add 这些编号是唯一且固定的用于确保在序列化和反序列化过程中字段的正确映射和识别。 总结 input 1 和 output 2 是字段的标识符表示这些字段在 Protobuf 编码中的编号。Protobuf 使用这些编号来有效地进行数据的序列化和反序列化。 3.2 理解onnx中的TensorProto TensorProto 一般用来定义一个权重比如 conv 的 weights 和 biasdims 是 repeated 类型意味着是数组raw_data 是 bytes 类型 我们可以在 onnx/onnx.in.proto#L498 找到它的定义如下图所示 3.3 理解onnx中的NodeProto 下一个是 NodeProtoNodeProto 一般用来定义一个计算节点比如 convlinear其中 input 是 repeated 类型意味着是数组output 是 repeated 类型意味着是数组attribute 有一个自己的 Protoop_type 需要严格根据 onnx 所提供的 Operators 写 我们可以在 onnx/onnx.in.proto#L207 找到它的定义如下图所示 具体的 op_type 在各个版本的算子支持可以参考 https://github.com/onnx/onnx/blob/main/docs/Operators.md 3.4 理解onnx中的AttributeProto AttributeProto 一般用来定义一个 node 的属性比如说 kernel size、pad、stride 等等 我们可以在 onnx/onnx.in.proto#L121 找到它的定义如下图所示 3.5 理解onnx中的GraphProto GraphProto 之前讲过它一般用来定义一个网络包括 input/output input/output 是 repeated所以是数组 initializer 在 onnx 中一般表示权重信息我们可以在 netron 看到initializer 是 repeated所以是数组 node node 是 repeated所以是数组 3.6 理解onnx中的ModelProto 最后我们来看下 ModelProtoModelProto 一般用来定义模型的全局信息比如 opsetgraph 并不是 repeated所以一个 model 对应一个 graph 我们可以在 onnx/onnx.in.proto#L356 找到它的定义如下图所示 4. 根据onnx中的Proto信息创建onnx 我们理解 onnx 中的各类 proto 信息之后再来创建一个 onnx 其实是一件特别简单的事情onnx 官方提供了一些很方便的 api 来创建 onnx例如 onnx.helper.make_tensoronnx.helper.make_tensor_value_infoonnx.helper.make_attributeonnx.helper.make_nodeonnx.helper.make_graphonnx.helper.make_model 我们先来看 3.3-read-and-parse-onnx\src\create_onnx_linear.py 案例代码如下所示 import onnx from onnx import helper from onnx import TensorProto# 理解onnx中的组织结构 # - ModelProto (描述的是整个模型的信息) # --- GraphProto (描述的是整个网络的信息) # ------ NodeProto (描述的是各个计算节点比如conv, linear) # ------ TensorProto (描述的是tensor的信息主要包括权重) # ------ ValueInfoProto (描述的是input/output信息) # ------ AttributeProto (描述的是node节点的各种属性信息)def create_onnx():# 创建ValueProtoa helper.make_tensor_value_info(a, TensorProto.FLOAT, [10, 10])x helper.make_tensor_value_info(x, TensorProto.FLOAT, [10, 10])b helper.make_tensor_value_info(b, TensorProto.FLOAT, [10, 10])y helper.make_tensor_value_info(y, TensorProto.FLOAT, [10, 10])# 创建NodeProto# op_type 不能随意写需要跟 https://github.com/onnx/onnx/blob/main/docs/Operators.md 对齐mul helper.make_node(Mul, [a, x], c, multiply)add helper.make_node(Add, [c, b], y, add)# 构建GraphProtograph helper.make_graph([mul, add], sample-linear, [a, x, b], [y])# 构建ModelProtomodel helper.make_model(graph)# 检查model是否有错误onnx.checker.check_model(model)# print(model)# 保存modelonnx.save(model, ../models/sample-linear.onnx)return modelif __name__ __main__:model create_onnx()这段代码使用 onnx 库创建了一个简单的 ONNX 模型。首先定义了四个 TensorProto 类型的 ValueInfoProto分别是输入张量 a 和 x以及输出张量 b 和 y。接着创建了两个 NodeProto 节点一个是 Mul 节点用于将 a 和 x 相乘得到中间张量 c另一个是 Add 节点用于将 c 和 b 相加得到最终输出 y。然后通过 helper.make_graph 函数将这些节点和张量组合成一个 GraphProto并进一步构建 ModelProto。最后代码检查模型是否正确并将其保存为 sample-linear.onnx 文件。(from ChatGPT) 导出的 ONNX 如下图所示 我们再来看 3.3-read-and-parse-onnx\src\create_onnx_convnet.py 案例代码如下所示 import numpy as np import onnx from onnx import numpy_helperdef create_initializer_tensor(name: str,tensor_array: np.ndarray,data_type: onnx.TensorProto onnx.TensorProto.FLOAT ) - onnx.TensorProto:initializer onnx.helper.make_tensor(name name,data_type data_type,dims tensor_array.shape,vals tensor_array.flatten().tolist())return initializerdef main():input_batch 1;input_channel 3;input_height 64;input_width 64;output_channel 16;input_shape [input_batch, input_channel, input_height, input_width]output_shape [input_batch, output_channel, 1, 1]##########################创建input/output################################model_input_name input0model_output_name output0input onnx.helper.make_tensor_value_info(model_input_name,onnx.TensorProto.FLOAT,input_shape)output onnx.helper.make_tensor_value_info(model_output_name, onnx.TensorProto.FLOAT, output_shape)##########################创建第一个conv节点##############################conv1_output_name conv2d_1.outputconv1_in_ch input_channelconv1_out_ch 32conv1_kernel 3conv1_pads 1# 创建conv节点的权重信息conv1_weight np.random.rand(conv1_out_ch, conv1_in_ch, conv1_kernel, conv1_kernel)conv1_bias np.random.rand(conv1_out_ch)conv1_weight_name conv2d_1.weightconv1_weight_initializer create_initializer_tensor(name conv1_weight_name,tensor_array conv1_weight,data_type onnx.TensorProto.FLOAT)conv1_bias_name conv2d_1.biasconv1_bias_initializer create_initializer_tensor(name conv1_bias_name,tensor_array conv1_bias,data_type onnx.TensorProto.FLOAT)# 创建conv节点注意conv节点的输入有3个: input, w, bconv1_node onnx.helper.make_node(name conv2d_1,op_type Conv,inputs [model_input_name, conv1_weight_name,conv1_bias_name],outputs [conv1_output_name],kernel_shape [conv1_kernel, conv1_kernel],pads [conv1_pads, conv1_pads, conv1_pads, conv1_pads],)##########################创建一个BatchNorm节点###########################bn1_output_name batchNorm1.output# 为BN节点添加权重信息bn1_scale np.random.rand(conv1_out_ch)bn1_bias np.random.rand(conv1_out_ch)bn1_mean np.random.rand(conv1_out_ch)bn1_var np.random.rand(conv1_out_ch)# 通过create_initializer_tensor创建权重方法和创建conv节点一样bn1_scale_name batchNorm1.scalebn1_bias_name batchNorm1.biasbn1_mean_name batchNorm1.meanbn1_var_name batchNorm1.varbn1_scale_initializer create_initializer_tensor(name bn1_scale_name,tensor_array bn1_scale,data_type onnx.TensorProto.FLOAT)bn1_bias_initializer create_initializer_tensor(name bn1_bias_name,tensor_array bn1_bias,data_type onnx.TensorProto.FLOAT)bn1_mean_initializer create_initializer_tensor(name bn1_mean_name,tensor_array bn1_mean,data_type onnx.TensorProto.FLOAT)bn1_var_initializer create_initializer_tensor(name bn1_var_name,tensor_array bn1_var,data_type onnx.TensorProto.FLOAT)# 创建BN节点注意BN节点的输入信息有5个: input, scale, bias, mean, varbn1_node onnx.helper.make_node(name batchNorm1,op_type BatchNormalization,inputs [conv1_output_name,bn1_scale_name,bn1_bias_name,bn1_mean_name,bn1_var_name],outputs[bn1_output_name],)##########################创建一个ReLU节点###########################relu1_output_name relu1.output# 创建ReLU节点ReLU不需要权重所以直接make_node就好了relu1_node onnx.helper.make_node(name relu1,op_type Relu,inputs [bn1_output_name],outputs [relu1_output_name],)##########################创建一个AveragePool节点####################avg_pool1_output_name avg_pool1.output# 创建AvgPool节点AvgPool不需要权重所以直接make_node就好了avg_pool1_node onnx.helper.make_node(name avg_pool1,op_type GlobalAveragePool,inputs [relu1_output_name],outputs [avg_pool1_output_name],)##########################创建第二个conv节点############################### 创建conv节点的属性conv2_in_ch conv1_out_chconv2_out_ch output_channelconv2_kernel 1conv2_pads 0# 创建conv节点的权重信息conv2_weight np.random.rand(conv2_out_ch, conv2_in_ch, conv2_kernel, conv2_kernel)conv2_bias np.random.rand(conv2_out_ch)conv2_weight_name conv2d_2.weightconv2_weight_initializer create_initializer_tensor(name conv2_weight_name,tensor_array conv2_weight,data_type onnx.TensorProto.FLOAT)conv2_bias_name conv2d_2.biasconv2_bias_initializer create_initializer_tensor(name conv2_bias_name,tensor_array conv2_bias,data_type onnx.TensorProto.FLOAT)# 创建conv节点注意conv节点的输入有3个: input, w, bconv2_node onnx.helper.make_node(name conv2d_2,op_type Conv,inputs [avg_pool1_output_name,conv2_weight_name,conv2_bias_name],outputs [model_output_name],kernel_shape [conv2_kernel, conv2_kernel],pads [conv2_pads, conv2_pads, conv2_pads, conv2_pads],)##########################创建graph##############################graph onnx.helper.make_graph(name sample-convnet,inputs [input],outputs [output],nodes [conv1_node, bn1_node, relu1_node, avg_pool1_node, conv2_node],initializer [conv1_weight_initializer, conv1_bias_initializer,bn1_scale_initializer, bn1_bias_initializer,bn1_mean_initializer, bn1_var_initializer,conv2_weight_initializer, conv2_bias_initializer],)##########################创建model##############################model onnx.helper.make_model(graph, producer_nameonnx-sample)model.opset_import[0].version 12##########################验证保存model##############################model onnx.shape_inference.infer_shapes(model)onnx.checker.check_model(model)print(Congratulations!! Succeed in creating {}.onnx.format(graph.name))onnx.save(model, ../models/sample-convnet.onnx)# 使用onnx.helper创建一个最基本的ConvNet # input (ch3, h64, w64) # | # Conv (in_ch3, out_ch32, kernel3, pads1) # | # BatchNorm # | # ReLU # | # AvgPool # | # Conv (in_ch32, out_ch10, kernel1, pads0) # | # output (ch10, h1, w1)if __name__ __main__:main()这段代码使用 onnx 库创建了一个简单的卷积神经网络ConvNet模型并将其保存为 sample-convnet.onnx 文件。首先定义了一个辅助函数 create_initializer_tensor用于生成权重和偏置的初始化器这些初始化器将作为 TensorProto 对象被添加到模型中。(from ChatGPT) 在主函数中首先设置了输入和输出的形状信息并使用 onnx.helper.make_tensor_value_info 创建了相应的 ValueInfoProto。接着定义了第一个卷积层的节点包括权重和偏置的初始化器通过 onnx.helper.make_node 创建 NodeProto 节点并指定了卷积操作的参数如核大小和填充方式。 随后代码添加了一个 BatchNormalization批归一化节点生成了对应的缩放、偏置、均值和方差的初始化器并创建了 BatchNormalization 节点。紧接着创建了一个 ReLU 激活层节点和一个全局平均池化层GlobalAveragePool节点这些节点不需要额外的权重初始化器。 接下来定义了第二个卷积层类似于第一个卷积层创建了其权重和偏置的初始化器以及对应的卷积节点。最后所有节点和初始化器被组合成一个 GraphProto并进一步构建 ModelProto。模型在进行形状推断和验证后被保存为 ONNX 格式文件。整个流程展示了如何使用 ONNX API 从头构建一个基本的卷积神经网络模型。 导出的 ONNX 如下图所示 5. 根据onnx中的Proto信息读取onnx ONNX 创建成功后我们就想去读取创建的 ONNX 的相关信息 我们来看 3.3-read-and-parse-onnx\src\parse_onnx_linear.py 案例代码如下所示 import onnxdef main(): model onnx.load(../models/sample-linear.onnx)onnx.checker.check_model(model)graph model.graphnodes graph.nodeinputs graph.inputoutputs graph.outputprint(\n**************parse input/output*****************)for input in inputs:input_shape []for d in input.type.tensor_type.shape.dim:if d.dim_value 0:input_shape.append(None)else:input_shape.append(d.dim_value)print(Input info: \\n\tname: {} \\n\tdata Type: {} \\n\tshape: {}.format(input.name, input.type.tensor_type.elem_type, input_shape))for output in outputs:output_shape []for d in output.type.tensor_type.shape.dim:if d.dim_value 0:output_shape.append(None)else:output_shape.append(d.dim_value)print(Output info: \\n\tname: {} \\n\tdata Type: {} \\n\tshape: {}.format(input.name, output.type.tensor_type.elem_type, input_shape))print(\n**************parse node************************)for node in nodes:print(node info: \\n\tname: {} \\n\top_type: {} \\n\tinputs: {} \\n\toutputs: {}.format(node.name, node.op_type, node.input, node.output))if __name__ __main__:main()这段代码通过 onnx 库加载并解析了一个名为 sample-linear.onnx 的 ONNX 模型输出了模型的输入、输出信息和节点信息。首先代码加载了 ONNX 模型并检查其有效性。接着从模型中提取 graph 对象并进一步提取图中的 nodes计算节点、inputs输入和 outputs输出。随后代码遍历输入和输出打印每个节点的名称、数据类型和形状信息。在形状解析中将维度值为 0 的维度标记为 None。最后代码遍历并打印每个计算节点的名称、操作类型、输入和输出信息提供了对模型内部结构的详细解析。(from ChatGPT) 输出如下图所示 我们再来看 3.3-read-and-parse-onnx\src\parse_onnx_convnet.py 案例代码如下所示 import onnxdef main(): model onnx.load(../models/sample-convnet.onnx)onnx.checker.check_model(model)graph model.graphinitializers graph.initializernodes graph.nodeinputs graph.inputoutputs graph.outputprint(\n**************parse input/output*****************)for input in inputs:input_shape []for d in input.type.tensor_type.shape.dim:if d.dim_value 0:input_shape.append(None)else:input_shape.append(d.dim_value)print(Input info: \\n\tname: {} \\n\tdata Type: {} \\n\tshape: {}.format(input.name, input.type.tensor_type.elem_type, input_shape))for output in outputs:output_shape []for d in output.type.tensor_type.shape.dim:if d.dim_value 0:output_shape.append(None)else:output_shape.append(d.dim_value)print(Output info: \\n\tname: {} \\n\tdata Type: {} \\n\tshape: {}.format(input.name, output.type.tensor_type.elem_type, input_shape))print(\n**************parse node************************)for node in nodes:print(node info: \\n\tname: {} \\n\top_type: {} \\n\tinputs: {} \\n\toutputs: {}.format(node.name, node.op_type, node.input, node.output))print(\n**************parse initializer*****************)for initializer in initializers:print(initializer info: \\n\tname: {} \\n\tdata_type: {} \\n\tshape: {}.format(initializer.name, initializer.data_type, initializer.dims))if __name__ __main__:main()这个和之前的读取 ONNX 代码一样只是计算节点的不同而已 输出如下图所示 如果我们要经常读取 ONNX 信息的话我们可以写一个函数来解析不同的 ONNX 我们再来看最后一个案例 3.3-read-and-parse-onnx\src\parse_onnx_cbr.py 案例代码如下所示 import torch import torch.nn as nn import torch.onnx import onnx from parser_custom import parse_onnx from parser_custom import read_weightclass Model(torch.nn.Module):def __init__(self):super().__init__()self.conv1 nn.Conv2d(in_channels3, out_channels16, kernel_size3)self.bn1 nn.BatchNorm2d(num_features16)self.act1 nn.LeakyReLU()def forward(self, x):x self.conv1(x)x self.bn1(x)x self.act1(x)return xdef export_norm_onnx():input torch.rand(1, 3, 5, 5)model Model()model.eval()file ../models/sample-cbr.onnxtorch.onnx.export(model model, args (input,),f file,input_names [input0],output_names [output0],opset_version 15)print(Finished normal onnx export)def main():export_norm_onnx()model onnx.load_model(../models/sample-cbr.onnx)parse_onnx(model)initializers model.graph.initializerfor item in initializers:read_weight(item)if __name__ __main__:main()其中的 parser_custom.py 实现如下 import onnx import numpy as np# 注意因为weight是以字节的形式存储的所以要想读需要转变为float类型 def read_weight(initializer: onnx.TensorProto):shape initializer.dimsdata np.frombuffer(initializer.raw_data, dtypenp.float32).reshape(shape)print(\n**************parse weight data******************)print(initializer info: \\n\tname: {} \\n\tdata: \n{}.format(initializer.name, data))def parse_onnx(model: onnx.ModelProto):graph model.graphinitializers graph.initializernodes graph.nodeinputs graph.inputoutputs graph.outputprint(\n**************parse input/output*****************)for input in inputs:input_shape []for d in input.type.tensor_type.shape.dim:if d.dim_value 0:input_shape.append(None)else:input_shape.append(d.dim_value)print(Input info: \\n\tname: {} \\n\tdata Type: {} \\n\tshape: {}.format(input.name, input.type.tensor_type.elem_type, input_shape))for output in outputs:output_shape []for d in output.type.tensor_type.shape.dim:if d.dim_value 0:output_shape.append(None)else:output_shape.append(d.dim_value)print(Output info: \\n\tname: {} \\n\tdata Type: {} \\n\tshape: {}.format(input.name, output.type.tensor_type.elem_type, input_shape))print(\n**************parse node************************)for node in nodes:print(node info: \\n\tname: {} \\n\top_type: {} \\n\tinputs: {} \\n\toutputs: {}.format(node.name, node.op_type, node.input, node.output))print(\n**************parse initializer*****************)for initializer in initializers:print(initializer info: \\n\tname: {} \\n\tdata_type: {} \\n\tshape: {}.format(initializer.name, initializer.data_type, initializer.dims))这段代码展示了一个从 PyTorch 模型到 ONNX 模型的完整导出和解析流程并对模型的权重进行了读取和输出。首先定义了一个包含卷积层、批归一化层和激活层的简单 PyTorch 模型 Model。在 export_norm_onnx 函数中通过 torch.onnx.export 方法将 PyTorch 模型转换为 ONNX 格式并保存为 sample-cbr.onnx 文件。(from ChatGPT) 在 main 函数中首先调用 export_norm_onnx 函数进行模型导出随后加载生成的 ONNX 模型并使用 parse_onnx 函数解析模型结构输出输入、输出节点信息以及计算节点信息。对于每个计算节点打印其名称、操作类型、输入和输出。随后遍历模型的初始化器即权重和偏置使用 read_weight 函数读取和打印每个初始化器的名称和数据内容。read_weight 函数将初始化器的字节数据转换为浮点数数组并输出其形状和数据内容。 parser_custom 模块中parse_onnx 函数详细解析了模型的图结构输出了模型的输入、输出、节点和初始化器的详细信息帮助全面理解 ONNX 模型的内部构成。 输出如下图所示 6. 根据onnx中的Proto信息修改onnx 之前杜老师的课程中有提到使用 onnx 的 api 来修改 onnx感兴趣的可以看下4.5.tensorRT基础(1)-onnx文件及其结构的学习编辑修改onnx 虽然 onnx 官方提供了一些 python api 来修改 onnx但是韩君老师这里推荐大家使用 TensorRT 下的 onnxsurgeon相关使用会在后面小节详细介绍 总结 本次课程我们主要学习了 ONNX 中的各种 ProtoONNX 本质上是一个 Protobuf 文件它由许多的 Proto 组成包括 ModelProto、GraphProto、NodeProto、TensorProto 等等。接着我们学习了如何利用 onnx 的 python api 去创建读取 onnx只要知道了 Proto 的数据结构我们就可以创建解析整个 onnx OK以上就是第 5 小节有关剖析 ONNX 架构并理解 Protobuf 的全部内容了下节我们来学习 ONNX 注册算子的方法敬请期待 参考 https://github.com/kalfazed/tensorrt_starterhttps://github.com/onnx/onnxhttps://github.com/onnx/onnx/blob/main/docs/Operators.md4.5.tensorRT基础(1)-onnx文件及其结构的学习编辑修改onnx
http://www.zqtcl.cn/news/507112/

相关文章:

  • 网站建设 甘肃wordpress rss去掉
  • 网站安全检测大连网龙建站优化推广
  • 人才网官方网站公众号排名优化软件
  • 淘宝返利网站建设软件开发哪里学好
  • 烟台网站制作公司如何注册国外网站
  • discuz企业网站网站可以做音频线吗
  • 怎样制作网站教程哪家好制作网页的的网站
  • 网站没有织梦后台无锡seo公司网站
  • 哈尔滨住房和城乡建设厅网站公司网站建设 费用入账
  • 网站图片缩略图t恤图案设计网站
  • 对招聘网站页面设计做建议网站流量 转化率
  • 怎么样做网站注册量郴州市北湖区
  • 山东企业展厅设计公司济南网站建设优化公司
  • 什么网站免费做游戏工艺品外贸订单网
  • 免费推广网站制作网站设计的技术有
  • 深圳电商网站建设高校学风建设专栏网站
  • 品牌网站建设 2蝌蚪小三网合一的网站怎么做
  • 对二次网站开发的认识wordpress修改图片大小
  • 电商网站项目建设个人网站空间收费
  • 官方网站制作思路樟木头东莞网站建设
  • 怎么寻找做有益做网站的客户大连网站推广
  • 湖南网站开发企业excel网站建设
  • 安康网站建设技巧腾讯建设网站视频下载
  • 如何能让企业做网站的打算中企动力做网站贵吗
  • wordpress 空间常州seo
  • 网站负责人备案采集照具体要求湛江网吧
  • 长春建站模板制作php网站空间购买
  • 网站域名到期怎么办食品包装设计的介绍
  • 建设网站专栏台州cms模板建站
  • 网站建设套餐方案湛江网站如何制作