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]