编辑ONNX的python代码
一、ONNX模型的基本操作
1,加载ONNX模型
2,保存ONNX模型
3,OP节点列表
4,输入节点名称
5,输出节点名称
6,参数节点
二、ONNX模型的修改
1,修改内部的变量
2,创建tensor
3,增加OP节点
4,增加输入\输出tensor节点
5,增加参数节点
6,特殊节点-constant增加
7,读取ONNX的参数tensor格式,转换为numpy
三、例程
得到第一个Conv的节点信息
注意:
在运行程序的时候,记得安装onnx的环境,在pycharm里面切换到onnx的解释器。
关于onnx的更多信息可以查看:https://github.com/onnx
一、ONNX模型的基本操作
1,加载ONNX模型
model = onnx.load("test.onnx")
2,保存ONNX模型
onnx.save(model, 'save_path.onnx')
3,OP节点列表
model.graph.node 是List, 可以增删改查
4,输入节点名称
model.graph.input
5,输出节点名称
model.graph.output
6,参数节点
model.graph.initializer
二、ONNX模型的修改
1,修改内部的变量
可直接修改内部的变量,如改变任意OP名称或者属性。
model.graph.node[0].op_type= '自定义'
改变输入的batch=1,model.graph.input[0].type.tensor_type.shape.dim[0].dim_value=1
当然也可以采用下面方法创建新的节点插入
2,创建tensor
ONNX模型采用tensor与node(op)将整个网络构建起来,node中输入输出为tensor的名称,用来连接各个tensor,中间的节点tensor不用创建,网络的输入输出节点需要创建tensor。Tensor常用的2种创建方法,样例如下:
1) onnx.helper.make_tensor_value_info(name=output, elem_type=type, shape=[1,3,224])
仅根据形状创建,用于输入输出节点
2)onnx.helper.make_tensor(name='const_tensor', data_type,dims=values.shape,vals=values.flatten())),
根据numpy数据创建
3,增加OP节点
函数:add_node = onnx.helper.make_node(op_type='Conv', inputs=input_names, outputs=output_names,name='conv1', **attribute)
添加OP节点到图中:
model.graph.node.append(add_node)
model.graph.node.insert(insert_pos, add_node)
其中,input_names、output_names 是字符串数组,为tensor的名称,例如,input_names=[‘name1’, ‘name2’]
attribute是字典,如 attribute[‘eps’] = 0.0001
4,增加输入\输出tensor节点
函数:
output_node = onnx.helper.make_tensor_value_info(name=output, elem_type=type, shape=[1,3,224])
model.graph.output.append(output_node)
5,增加参数节点
params = numpy_helper.from_array(numpy, name='p_name')
model.graph.initializer.append(params)
6,特殊节点-constant增加
函数:
value=onnx.helper.make_tensor(name='const_tensor', data_type=1, dims=numpy_data.shape,vals=numpy_data.flatten()))
constant_node = onnx.helper.make_node(op_type='Constant', inputs=[], outputs=[output_name],name='constant1', value = value)
7,读取ONNX的参数tensor格式,转换为numpy
constant节点:onnx.numpy_helper.to_array(onnx_node.attribute[0].t)
initialize的参数:onnx.numpy_helper.to_array(params)
特别数值,若数值为1个数,则导出的非numpy格式,也是一个数值
三、例程
本文使用打开onnx模型的软件为netron,本文使用mobilenetv2-7.onnx模型,从官网的模型库中下载的。
onnx官网:https://onnx.ai/ 进行查找和下载
使用topo_tailoring_infer_smoke_resnet18_704x384_fp16_2_Conv_161.onnx (netron.app)打开xxx.onnx文件
打开onnx模型如下图所示:
得到第一个Conv的节点信息
import onnx
model = onnx.load("mobilenetv2-7.onnx")
nodel_list = model.graph.node
input_list = model.graph.input
output_list = model.graph.output
initializer_list = model.graph.initializer
print(nodel_list[0])
运行之后,打印如下结果:
input: "input"
input: "475"
input: "476"
output: "474"
name: "Conv_0"
op_type: "Conv"
attribute {
name: "dilations"
ints: 1
ints: 1
type: INTS
}
attribute {
name: "group"
i: 1
type: INT
}
attribute {
name: "kernel_shape"
ints: 3
ints: 3
type: INTS
}
attribute {
name: "pads"
ints: 1
ints: 1
ints: 1
ints: 1
type: INTS
}
attribute {
name: "strides"
ints: 2
ints: 2
type: INTS
}
我们使用netron打开该模型的第一个Conv节点进行对照:
可以看到input,output,等等信息都可以得到,其他的修改部分按照上面给出的语法进行操作即可。
后面的操作就相当于对着List进行操作。
注意:
在运行程序的时候,记得安装onnx的环境,在pycharm里面切换到onnx的解释器。
关于onnx的更多信息可以查看:https://github.com/onnx