简述网站开发的几个步骤,asp网站制作,一键制作自己的app软件,电商网站建设关键词优化Onnx 使用
Onnx 介绍 Onnx (Open Neural Network Exchange) 的本质是一种 Protobuf 格式文件#xff0c;通常看到的 .onnx 文件其实就是通过 Protobuf 序列化储存的文件。onnx-ml.proto 通过 protoc (Protobuf 提供的编译程序) 编译得到 onnx-ml.pb.h 和 onnx-ml.pb.cc 或 on…Onnx 使用
Onnx 介绍 Onnx (Open Neural Network Exchange) 的本质是一种 Protobuf 格式文件通常看到的 .onnx 文件其实就是通过 Protobuf 序列化储存的文件。onnx-ml.proto 通过 protoc (Protobuf 提供的编译程序) 编译得到 onnx-ml.pb.h 和 onnx-ml.pb.cc 或 onnx_ml_pb2.py然后用 onnx_ml.pb.cc 和代码来操作 onnx 模型文件实现增删改操作。onnx-ml.proto 则是描述 onnx 文件如何组成和结构用于作为操控 onnx 的参照。但是这个.proto 文件里面用的是 protobuf 语法只是一个中间表示文件不具备任何能力即并不面向存储和传输序列化反序列化读写。所以需要用 protoc 编译 .proto 文件是将 .proto 文件编译成不同语言的实现得到 .cc 和 .py 文件这两个接口文件这样不同语言中的数据就可以和自定义的结构化数据格式的数据进行交互。
onnx-ml.proto
查看 onnx-ml.proto 文件可以看到每个 proto 的不同的数据结构message 就是结构化数据的关键字用于描述数据的字段、类型和层次结构。之后加载了 onnx 模型后就可以按照这个文件内部记录的数据结构来访问模型中的数据。 使用 repeated 就表示内部的属性是数组使用 optional 就表示数据可选。NodeProto 中 input 就是一个数组其中储存着 string需要使用索引访问name 就是一个 string。这些参数后面的数值表示每个属性特定的 id这些 id 是不能冲突的官方已经指定好了。
Onnx 结构 onnx.model: 这是一个具体的 ONNX 模型实例它是一个 ModelProto 对象可以通过 onnx.helper.make_model 来构建。它包含了模型的所有信息包括元数据、图graph、初始参数等。代码中对应 ModelProto其中 opset_import 是 OperatorSetIdProto 数据结构的数组graph 是 GraphProto 数据结构一个 model 对应一个 graph。 onnx.model.graph: 这是 onnx 模型的计算图它是一个 GraphProto 对象可以通过 onnx.helper.make_graph 来构建。计算图是一种描述模型计算过程的图形结构它由一系列的节点 (node) 组成这些节点代表了模型中的各种操作 (如卷积、激活函数等)。代码中对应 GraphProto其中 node 是 NodeProto 数据结构的数组initializer 是一个 TensorProto 数据结构的数组sparse_initializer 是一个 SparseTensorProto 数据结构的数组input、output 和 value_info 是 ValueInfoProto 数据结构的数组。 onnx.model.graph.node: 这是计算图中的一个节点它是一个 NodeProto 对象可以通过 onnx.helper.make_node。每个节点代表了一个操作它有一定数量的输入和输出这些输入和输出都是张量。节点还有一个操作类型 (如Conv、Relu等) 和一些特定的参数 (如卷积核的大小、步长、填充等)。代码中对应 NodeProto其中 input 和 output 是 string 类型数组attribute 是一个 AttributeProto 数据结构用于定义 node 属性常见用法是将 (key, value) 传入 Proto 中op_type 是一个 string需要对应 onnx 提供的 operators。 onnx.model.graph.initializer: 这是模型的初始化参数它是一个 TensorProto 对象可以通过 onnx.helper.make_tensor。每个 TensorProto 对象都包含了一个张量的所有信息包括数据类型、形状、数据等。模型的所有权重和偏置都包含在这个列表中。代码中对应 TensorProto其中 dims 是 int64 类型数组raw_data 是 bytes 类型。 onnx.model.graph.input/output: 这是模型的输入/输出信息它是一个 ValueInfoProto 对象可以通过onnx.helper.make_value_info 或 onnx.helper.make_tensor_value_info。每个 ValueInfoProto 对象描述了一个输入/输出的信息包括名称、数据类型、形状等。主要是用于标记哪些节点是输入/输出。代码中对应 ValueInfoProto其中 type 是一个 TypeProto 数据结构内部定义了标准 onnx 数据类型。
ONNX 模型的计算图中的节点可以有多种类型其中包括 Constant表示一种特殊的操作它的作用是在计算过程中提供一个常量张量。这种常量张量的值在模型训练过程中不会改变因此被视为常量。例如对于大小为 (bs, N, H, W, 2) 的 anchorgrid 张量其中bs 是批处理大小N 是锚框(anchor box)的种类数量H 和 W 分别代表特征图的高度和宽度最后的** 2 **代表每个锚框的宽度和高度它可以被存储在一个 Constant 类型的节点中。值得注意的是当使用ONNX图形可视化工具如Netron时Constant 类型的节点可能不会显示出来。这是因为这些节点并不涉及任何计算操作只是提供了一个常量张量。
另外还有一种类型为Identity的节点。Identity节点表示一种标识操作它的输出和输入完全相同。这种节点通常用于在需要保持计算图结构完整性的情况下将某些张量传递到计算图的下一层。换句话说它不会改变传递给它的任何信息可以被视为一个透明的或者无操作的节点。
Onnx 模型生成
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.onnx
import osclass Model(torch.nn.Module):def __init__(self):super().__init__()self.conv nn.Conv2d(1, 1, 3, padding1)self.relu nn.ReLU()self.conv.weight.data.fill_(1)self.conv.bias.data.fill_(0)def forward(self, x):x self.conv(x)x self.relu(x)return x# 这个包对应opset11的导出代码如果想修改导出的细节可以在这里修改代码
# import torch.onnx.symbolic_opset11
print(对应opset文件夹代码在这里, os.path.dirname(torch.onnx.__file__))model Model()#dummy如果改成torch.zeros(8, 1, 3, 3)对生成的onnx图是没有影响的
dummy torch.zeros(1, 1, 3, 3)#生成的onnx图的conv算子的bias为1这是由输出通道数决定的因为输出通道为1
torch.onnx.export(model, # 这里的args是指输入给model的参数需要传递tuple因此用括号(dummy,), # 储存的文件路径demo.onnx, # 打印详细信息verboseTrue, # 为输入和输出节点指定名称方便后面查看或者操作input_names[image], output_names[output], # 这里的opset指各类算子以何种方式导出对应于symbolic_opset11opset_version11, # 表示他有batch、height、width3个维度是动态的在onnx中给其赋值为-1# 通常我们只设置batch为动态其他的避免动态dynamic_axes{image: {0: batch, 2: height, 3: width},output: {0: batch, 2: height, 3: width},}
)print(Done.!)Onnx 模型加载
import onnx
import onnx.helper as helper
import numpy as npmodel onnx.load(demo.onnx)#打印信息
print(node信息)
# print(helper.printable_graph(model.graph))
print(model)conv_weight model.graph.initializer[0]
conv_bias model.graph.initializer[1]# initializer里有dims这个属性是可以通过打印model看到的
# dims在onnx-ml.proto文件中是repeated类型的即数组类型所以要用索引去取
print(conv_weight.dims)
# 取node节点的第一个元素
print(f{model.graph.node[1].name})
print(model.graph.node[1])# 数据是以protobuf的格式存储的因此当中的数值会以bytes的类型保存通过np.frombuffer方法还原成类型为float32的ndarray
print(f{conv_weight.name})
print(conv_weight.name, np.frombuffer(conv_weight.raw_data, dtypenp.float32))print(f{conv_bias.name})
print(conv_bias.name, np.frombuffer(conv_bias.raw_data, dtypenp.float32))node信息
ir_version: 6
producer_name: pytorch
producer_version: 1.13.1
graph {node {input: imageinput: conv.weightinput: conv.biasoutput: /conv/Conv_output_0name: /conv/Convop_type: Convattribute {name: dilationsints: 1ints: 1type: INTS}attribute {name: groupi: 1type: INT}attribute {name: kernel_shapeints: 3ints: 3type: INTS}attribute {name: padsints: 1ints: 1ints: 1ints: 1type: INTS}attribute {name: stridesints: 1ints: 1type: INTS}}node {input: /conv/Conv_output_0output: outputname: /relu/Reluop_type: Relu}name: torch_jitinitializer {dims: 1dims: 1dims: 3dims: 3data_type: 1name: conv.weightraw_data: \000\000\200?\000\000\200?\000\000\200?\000\000\200?\000\000\200?\000\000\200?\000\000\200?\000\000\200?\000\000\200?}initializer {dims: 1data_type: 1name: conv.biasraw_data: \000\000\000\000}input {name: imagetype {tensor_type {elem_type: 1shape {dim {dim_param: batch}dim {dim_value: 1}dim {dim_param: height}dim {dim_param: width}}}}}output {name: outputtype {tensor_type {elem_type: 1shape {dim {dim_param: batch}dim {dim_value: 1}dim {dim_param: height}dim {dim_param: width}}}}}
}
opset_import {version: 11
}[1, 1, 3, 3]
/relu/Relu
input: /conv/Conv_output_0
output: output
name: /relu/Relu
op_type: Reluconv.weight
conv.weight [1. 1. 1. 1. 1. 1. 1. 1. 1.]
conv.bias
conv.bias [0.]这个是 TensorProto 中使用的数据类型initializer 中的 data_type 为 1 就表示数据类型为 FLOAT。
https://github.com/onnx/onnx/blob/v1.2.1/onnx/onnx-ml.proto#L88
https://onnx.ai/onnx/search.html?qSparseConvolutioncheck_keywordsyesareadefault# 通过 helper 自定义 Onnx 模型
import onnx # pip install onnx1.10.2
import onnx.helper as helper
import numpy as np# https://github.com/onnx/onnx/blob/v1.2.1/onnx/onnx-ml.protonodes [helper.make_node(nameConv_0, # 节点名字不要和op_type搞混了op_typeConv, # 节点的算子类型, 比如Conv、Relu、Add这类详细可以参考onnx给出的算子列表inputs[image, conv.weight, conv.bias], # 各个输入的名字结点的输入包含输入和算子的权重。必有输入X和权重W偏置B可以作为可选。outputs[3], pads[1, 1, 1, 1], # 其他字符串为节点的属性attributes在官网被明确的给出了标注了default的属性具备默认值。group1,dilations[1, 1],kernel_shape[3, 3],strides[1, 1]),helper.make_node(nameReLU_1,op_typeRelu,inputs[3],outputs[output])
]initializer [helper.make_tensor(nameconv.weight,data_typehelper.TensorProto.DataType.FLOAT,dims[1, 1, 3, 3],valsnp.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], dtypenp.float32).tobytes(),rawTrue),helper.make_tensor(nameconv.bias,data_typehelper.TensorProto.DataType.FLOAT,dims[1],valsnp.array([0.0], dtypenp.float32).tobytes(),rawTrue)
]inputs [helper.make_value_info(nameimage,type_protohelper.make_tensor_type_proto(elem_typehelper.TensorProto.DataType.FLOAT,shape[batch, 1, 3, 3]))
]outputs [helper.make_value_info(nameoutput,type_protohelper.make_tensor_type_proto(elem_typehelper.TensorProto.DataType.FLOAT,shape[batch, 1, 3, 3]))
]graph helper.make_graph(namemymodel,inputsinputs,outputsoutputs,nodesnodes,initializerinitializer
)# 如果名字不是ai.onnxnetron解析就不是太一样了
opset [helper.make_operatorsetid(ai.onnx, 11)
]# producer主要是保持和pytorch一致
model helper.make_model(graph, opset_importsopset, producer_namepytorch, producer_version1.9)
onnx.save_model(model, my.onnx)print(model)
print(Done.!)Extra
pytorch_quantization.tensor_quant
该模块是用于对张量量化的通常会使用 QuantDescriptor、TensorQuantFunction 和 FakeTensorQuantFunction。第一个为张量描述器后面两个是用于对张量进行量化。TensorQuantFunction 和 FakeTensorQuantFunction 中的前向即量化 (Quantization) 由_tensor_quant 进行计算反向就是反量化 (Dequantization)。
TensorQuantFunction 和 FakeTensorQuantFunction 代码介绍
前向
TensorQuantFunction 和 FakeTensorQuantFunction 在前向中的操作基本相同的TensorQuantFunction 会对输入为 torch.half 精度的张量的 scale 进行截断操作FakeTensorQuantFunction 中没有这样的操作。TensorQuantFunction 的输出是量化后的张量和 scaleFakeTensorQuantFunction 的输出仅仅是量化后的张量。
反向
TensorQuantFunction 和 FakeTensorQuantFunction 的反向过程是相同的。
pytorch_quantization.tensor_quant.QuantDescriptor
量化描述器主要用于描述一个张量如何被量化内部记录了量化方式、校准方法、缩放因子、零点等信息。
一般用于描述网络中的输入和权重。
QuantMixin 和 QuantInputMixin
QuantMixin 用于表示网络中有输入和权重在进行量化时要对这两个部分进行量化。
pytorch_quantization.nn.TensorQuantizer
TensorQuantizer 创建需要 Descriptor 做为入参。TensorQuantizer 通过量化描述器中的量化参数和量化方法来调用相应的量化方法从而实现对张量的量化。
Protobuf
Protocol Buffers简称 Protobuf是一种轻量级、高效的数据序列化格式由 Google 开发。它旨在支持跨平台、跨语言的数据交换和存储。
Protobuf 使用一种结构化的数据描述语言来定义数据的结构和格式这些描述文件被称为 .proto 文件。通过定义 .proto 文件您可以指定消息的字段和数据类型并使用 Protobuf 编译器将其转换为特定语言的类或结构体用于在不同的编程语言中进行数据的序列化和反序列化。
与其他数据序列化格式相比Protobuf 具有以下优势
高效性Protobuf 使用二进制编码因此比文本格式如 JSON、XML更紧凑占用更少的存储空间和网络带宽。快速性由于 Protobuf 的编解码过程是基于生成的高效代码实现的因此比通用的解析器更快。可扩展性您可以在已定义的消息结构中添加新的字段而不会破坏现有数据的兼容性。接收方可以选择性地忽略他们不理解的字段。跨平台和跨语言支持通过使用 Protobuf您可以在不同的编程语言和平台之间进行数据交换因为 Protobuf 提供了多种语言的支持包括 C、Java、Python、Go 等。
Protobuf 在众多领域中被广泛使用特别是在大规模分布式系统、通信协议、数据存储和数据交换等方面。它提供了一种高效、灵活和可扩展的方式来处理结构化数据。
append_initializer 函数介绍 入参
value 是模型当前模块的权重维度经过 permute 之后 KIO 变为 OKI。name 用于描述初始化是特定层的权重或偏置。
返回
将 name 作为函数返回值
这里在 initializers 中添加了一个 TensorProto 对象主要是用于记录权重和偏置的信息其中记录了数据名称、类型、维度和数值。这里的 name 需要设置为唯一的不能与其他相同的数据结构的 name 重复。这里的 dims 需要使用 list 来储存是因为在 TensorProto 数据结构中是使用 repeated int64 来定义的。raw 设置为了 True这里的 vals 就需要转换为 bytes 类型如果是 False就只需要转换为 np.float16 类型。
make_node 函数介绍 通过 make_node 函数可以创建一个 NodeProto 对象这个节点会记录了指定的操作用于之后生成 GraphProto 对象表示计算图。
以上面这段代码为例先介绍一下参数的含义
ops_type数据类型为 str该参数需要设置为特定的官方操作类型名称当前的 ops_type 为 “SparseConvolution”这里使用了自定义的操作并不是官方提供的默认操作。input/output数据类型为 list[str]该参数表示节点的输入/输出的名称当前的 input 为 [‘0’, ‘spconv0.weight’, ‘spconv0.bias’]output 为 [‘1’]。name: 数据类型为可选的 str该参数表示节点的名称当前的 names 为 conv0。doc_string: 数据类型为可选的 str用于提供节点的文档字符串 (Documentation String)用于描述节点的功能和用途。它对于理解和解释节点的作用非常有用。可以使用该参数为节点添加描述性的文本。这里没有设置该参数。domain: 数据类型为可选的 str指定节点所属的域Domain。域是用于标识特定领域或框架的字符串。不同的域可能有不同的操作类型和语义。默认情况下节点属于 ONNX 的主要域。如果要使用特定域的扩展或自定义操作类型可以指定相应的域。例如“com.example.custom” 表示自定义域。域的使用可以帮助在不同框架之间进行模型转换和兼容性。**kwargs: 数据类型为 dict用于描述节点的属性这里用于储存当前稀疏卷积模块的属性。 文章转载自: http://www.morning.hlfnh.cn.gov.cn.hlfnh.cn http://www.morning.srky.cn.gov.cn.srky.cn http://www.morning.ccsdx.cn.gov.cn.ccsdx.cn http://www.morning.glnxd.cn.gov.cn.glnxd.cn http://www.morning.kpbgvaf.cn.gov.cn.kpbgvaf.cn http://www.morning.sacxbs.cn.gov.cn.sacxbs.cn http://www.morning.mjbjq.cn.gov.cn.mjbjq.cn http://www.morning.qlkzl.cn.gov.cn.qlkzl.cn http://www.morning.rqqct.cn.gov.cn.rqqct.cn http://www.morning.ylsxk.cn.gov.cn.ylsxk.cn http://www.morning.spbp.cn.gov.cn.spbp.cn http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn http://www.morning.rczrq.cn.gov.cn.rczrq.cn http://www.morning.rdnjc.cn.gov.cn.rdnjc.cn http://www.morning.hkpn.cn.gov.cn.hkpn.cn http://www.morning.jfxth.cn.gov.cn.jfxth.cn http://www.morning.qwfl.cn.gov.cn.qwfl.cn http://www.morning.ghjln.cn.gov.cn.ghjln.cn http://www.morning.ccsdx.cn.gov.cn.ccsdx.cn http://www.morning.yhywx.cn.gov.cn.yhywx.cn http://www.morning.clfct.cn.gov.cn.clfct.cn http://www.morning.gcqdp.cn.gov.cn.gcqdp.cn http://www.morning.kzrbn.cn.gov.cn.kzrbn.cn http://www.morning.wpmlp.cn.gov.cn.wpmlp.cn http://www.morning.qxmnf.cn.gov.cn.qxmnf.cn http://www.morning.pqqxc.cn.gov.cn.pqqxc.cn http://www.morning.rwwdp.cn.gov.cn.rwwdp.cn http://www.morning.wyfpc.cn.gov.cn.wyfpc.cn http://www.morning.xdjwh.cn.gov.cn.xdjwh.cn http://www.morning.nshhf.cn.gov.cn.nshhf.cn http://www.morning.bpmdr.cn.gov.cn.bpmdr.cn http://www.morning.hxsdh.cn.gov.cn.hxsdh.cn http://www.morning.thbqp.cn.gov.cn.thbqp.cn http://www.morning.mjpgl.cn.gov.cn.mjpgl.cn http://www.morning.tpdg.cn.gov.cn.tpdg.cn http://www.morning.xpqyf.cn.gov.cn.xpqyf.cn http://www.morning.dycbp.cn.gov.cn.dycbp.cn http://www.morning.zcnwg.cn.gov.cn.zcnwg.cn http://www.morning.rbyz.cn.gov.cn.rbyz.cn http://www.morning.fnssm.cn.gov.cn.fnssm.cn http://www.morning.prplf.cn.gov.cn.prplf.cn http://www.morning.8yitong.com.gov.cn.8yitong.com http://www.morning.dfbeer.com.gov.cn.dfbeer.com http://www.morning.xkbdx.cn.gov.cn.xkbdx.cn http://www.morning.ydwsg.cn.gov.cn.ydwsg.cn http://www.morning.weitao0415.cn.gov.cn.weitao0415.cn http://www.morning.pyncm.cn.gov.cn.pyncm.cn http://www.morning.bwygy.cn.gov.cn.bwygy.cn http://www.morning.yzsdp.cn.gov.cn.yzsdp.cn http://www.morning.zyndj.cn.gov.cn.zyndj.cn http://www.morning.bmjfp.cn.gov.cn.bmjfp.cn http://www.morning.qkxt.cn.gov.cn.qkxt.cn http://www.morning.qttft.cn.gov.cn.qttft.cn http://www.morning.cmfkp.cn.gov.cn.cmfkp.cn http://www.morning.fpyll.cn.gov.cn.fpyll.cn http://www.morning.nj-ruike.cn.gov.cn.nj-ruike.cn http://www.morning.rkhhl.cn.gov.cn.rkhhl.cn http://www.morning.bsghk.cn.gov.cn.bsghk.cn http://www.morning.dfmjm.cn.gov.cn.dfmjm.cn http://www.morning.krnzm.cn.gov.cn.krnzm.cn http://www.morning.jwbfj.cn.gov.cn.jwbfj.cn http://www.morning.huihuangwh.cn.gov.cn.huihuangwh.cn http://www.morning.ydwsg.cn.gov.cn.ydwsg.cn http://www.morning.kbynw.cn.gov.cn.kbynw.cn http://www.morning.rkkh.cn.gov.cn.rkkh.cn http://www.morning.mzzqs.cn.gov.cn.mzzqs.cn http://www.morning.pxlsh.cn.gov.cn.pxlsh.cn http://www.morning.lbjdx.cn.gov.cn.lbjdx.cn http://www.morning.nptls.cn.gov.cn.nptls.cn http://www.morning.zwxfj.cn.gov.cn.zwxfj.cn http://www.morning.hbxnb.cn.gov.cn.hbxnb.cn http://www.morning.qszyd.cn.gov.cn.qszyd.cn http://www.morning.pzlcd.cn.gov.cn.pzlcd.cn http://www.morning.hdrrk.cn.gov.cn.hdrrk.cn http://www.morning.swbhq.cn.gov.cn.swbhq.cn http://www.morning.cnbdn.cn.gov.cn.cnbdn.cn http://www.morning.cbqqz.cn.gov.cn.cbqqz.cn http://www.morning.qptbn.cn.gov.cn.qptbn.cn http://www.morning.swzpx.cn.gov.cn.swzpx.cn http://www.morning.tcfhs.cn.gov.cn.tcfhs.cn