onnx模型解析


1.原始模型分析

由於centerface的模型是onnx的,可以通過netron工具包查看改模型的輸入輸出維度

import netron
modelPath = ""centerface.onnx""
netron.start(modelPath)

運行上述代碼會生成如下的網絡結構圖:

 

點擊input.1可以查看模型的輸入輸出維度,如下圖

 

從上圖可以看出原始模型的輸入維度是(10,3,32,32)輸出537的維度是(10,1,8,8);538的維度是(10,2,8,8);539的維度是(10,2,8,8);540的維度是(10,2,8,8)

2.模型修改

  由於我們的實際圖片大小是1920*1080,所有要對網絡的輸入輸出維度進行修改

  

import onnx
import math

input_size =(1080,1920)
model = onnx.load_model("centerface.onnx")
d = model.graph.input[0].type.tensor_type.shape.dim
print(d)
rate = (int(math.ceil(input_size[0]/d[2].dim_value)),int(math.ceil(input_size[1]/d[3].dim_value)))
print("rare",rate)
d[0].dim_value = 1
d[2].dim_value *= rate[0]
d[3].dim_value *= rate[1]
for output in model.graph.output:
    d = output.type.tensor_type.shape.dim
    print(d)
    d[0].dim_value = 1
    d[2].dim_value  *= rate[0]
    d[3].dim_value  *= rate[1]

onnx.save_model(model,"centerface_1088_1920.onnx" )    

  再次查看 centerface_1088_1920.onn模型的輸入輸出維度如下圖:

 

 

  也可以使用代碼方式查看網絡結構,代碼如下

  

import onnx
from onnx import helper
import sys,getopt

#加載模型
def loadOnnxModel(path):
    model = onnx.load(path)
    return model

#獲取節點和節點的輸入輸出名列表,一般節點的輸入將來自於上一層的輸出放在列表前面,參數放在列表后面
def getNodeAndIOname(nodename,model):
    for i in range(len(model.graph.node)):
        if model.graph.node[i].name == nodename:
            Node = model.graph.node[i]
            input_name = model.graph.node[i].input
            output_name = model.graph.node[i].output
    return Node,input_name,output_name

#獲取對應輸入信息
def getInputTensorValueInfo(input_name,model):
    in_tvi = []
    for name in input_name:
        for params_input in model.graph.input:
            if params_input.name == name:
               in_tvi.append(params_input)
        for inner_output in model.graph.value_info:
            if inner_output.name == name:
                in_tvi.append(inner_output)
    return in_tvi

#獲取對應輸出信息
def getOutputTensorValueInfo(output_name,model):
    out_tvi = []
    for name in output_name:
        out_tvi = [inner_output for inner_output in model.graph.value_info if inner_output.name == name]
        if name == model.graph.output[0].name:
            out_tvi.append(model.graph.output[0])
    return out_tvi

#獲取對應超參數值
def getInitTensorValue(input_name,model):
    init_t = []
    for name in input_name:
        init_t = [init for init in model.graph.initializer if init.name == name]
    return init_t

#構建單個節點onnx模型
def createSingelOnnxModel(ModelPath,nodename,SaveType="",SavePath=""):
    model = loadOnnxModel(str(ModelPath))
    Node,input_name,output_name = getNodeAndIOname(nodename,model)
    in_tvi = getInputTensorValueInfo(input_name,model)
    out_tvi = getOutputTensorValueInfo(output_name,model)
    init_t = getInitTensorValue(input_name,model)

    graph_def = helper.make_graph(
                [Node],
                nodename,
                inputs=in_tvi,  # 輸入
                outputs=out_tvi,  # 輸出
                initializer=init_t,  # initalizer
            )
    model_def = helper.make_model(graph_def, producer_name='onnx-example')
    print(nodename+"onnx模型生成成功!")
#獲取節點數量
def getNodeNum(model):
    return len(model.graph.node)
#獲取節點類型
def getNodetype(model):
    op_name = []
    for i in range(len(model.graph.node)):
        if model.graph.node[i].op_type not in op_name:
            op_name.append(model.graph.node[i].op_type)
    return op_name
#獲取節點名列表
def getNodeNameList(model):
    NodeNameList = []
    for i in range(len(model.graph.node)):
        NodeNameList.append(model.graph.node[i].name)
    return NodeNameList
#獲取模型的輸入信息
def getModelInputInfo(model):
    return model.graph.input[0]
#獲取模型的輸出信息
def getModelOutputInfo(model):
    return model.graph.output[0:4]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM