环境
基础
Anaconda [1] Conda创建-非NNXPython=3.8-ycondaactivateonnx
# # onnx
# # https://github.com/onnx/onnx
孔达安装-抄送孔达-福克斯- y
透明导体; print (onnx._ _版本_ ) '
importonnx
model=onnx.load (模型. onnx ) )。
简化
#ONNXSimplifier# # https://github.com/daquexian/onnx-simplifier
pipinstallonnx -简化程序
掌上电脑xsim-h
importonnxsim
model_simp,check=Onnxsim.simplify(model,性能_优化=假) ) ) ) ) ) ) ) ) )。
资产检查,' simplifiedonnxmodelcouldnotbevalidated '
以下是
使用
onnx机型中使用的一些示例方法。
提取子模型
importonnxinput _ path='路径/到/the /原始/模型. onnx '
output _ path='路径/到/保存/到/延伸/模型. onnx '
输入名称=[ '输入0 ','输入1 ','输入2 ' ]
输出名称=[ '输出_0','输出_1' ]
(输入路径、输出路径、输入名称、输出名称) ) )。
修改输入输出名称
def _ onnx _ rename (模型、名称、名称_新建) :fornodeinmodel.graph.node:
二进制枚举(节点输入) :
ifninnames:
节点.输入=名称_新建
二进制枚举(节点输出) :
ifninnames:
节点.输出=名称_新建
fornodeinmodel.graph.input :
if node .名称:
节点名称=名称_新建[名称.索引(节点名称) ]
# # print (模型.图形输入) )。
fornodeinmodel.graph.output :
if node .名称:
节点名称=名称_新建[名称.索引(节点名称) ]
# # print (模型.图形.输出) )。
_ onnx _重命名(模型,“输入”,“输出”,“输入_新建”,“输出_新建”)
修改输入输出维度
这是模型的修改。 如果要修改节点,请参阅onnx_cut.py中的_onnx_specify_shapes ()。fromonnx.toolsimportupdate _ model _ dims
更新_模型_ dims .更新_输入_输出_ dims (模型,
输入: [ 1,3,512,512 ]、
“得分”: [ 100,1 ],“盒子”: [ 100,4 ]
)
推理模型节点维度
表示模型输入维后,可以自动推理后续节点的维。model _ infer=onnx.shape _ inference.infer _ shapes (模型)
获取图属性名称索引
帮助搜索具有指定名称的图属性。def _ onnx _图形名称地图(图形轮廓Li
st): m = {} for n in graph_prop_list: m[n.name] = n return m node_map = _onnx_graph_name_map(graph.node) initializer_map = _onnx_graph_name_map(graph.initializer) input_map = _onnx_graph_name_map(graph.input) output_map = _onnx_graph_name_map(graph.output) value_info_map = _onnx_graph_name_map(graph.value_info)获取节点输入名称索引
辅助找出指定输入名称的节点列表。输出同样。
def _onnx_node_input_map(node_list): m = {} for n in node_list: for n_input in n.input: if n_input in m: m[n_input].append(n) else: m[n_input] = [n] return m node_input_map = _onnx_node_input_map(graph.node)获取图属性位置
辅助找出图某属性所在列表位置。
def _onnx_graph_index(graph_prop_list, prop, by_name=False): for i, n in enumerate(graph_prop_list): if by_name: if n.name == prop.name: return i else: if n == prop: return i return -1 node_i = _onnx_graph_index(graph.node, node)获取某区间的节点
辅助找出某区间的节点字典。
def _onnx_node_between(node_beg, node_end, node_input_map): nodes = {} def _between(beg, end): if beg.name == end.name: return for n_output in beg.output: for n in node_input_map[n_output]: if n.name == end.name or n.name in nodes: continue nodes[n.name] = n _between(n, end) _between(node_beg, node_end) return nodes替换某个节点
替换或修改某个节点的过程。
from onnx import helper node = graph.node[100] node_i = _onnx_graph_index(graph.node, node) graph.node.remove(node) node_new = helper.make_node( 'Pad', # name ['X', 'pads', 'value'], # inputs ['Y'], # outputs mode='constant', # attributes ) graph.node.insert(node_i, node_new)模型运行推理
模型运行推理,得到输出的过程。
import cv2 as cv import numpy as np import onnxruntime as nxrun onnx_session = nxrun.InferenceSession("path/to/model.onnx") img = cv.imread("path/to/image.png", cv.IMREAD_COLOR) # _, _, h, w = input_node.shape # BCHW # img = cv.resize(src=img, dsize=(w, h), interpolation=cv.INTER_LINEAR_EXACT) input_data = np.swapaxes(img, 0, -1) input_data = input_data[np.newaxis, :].astype(np.float32) def _get_output_names(onnx_session): names = [] for node in onnx_session.get_outputs(): names.append(node.name) return names output_names = _get_output_names(onnx_session) outputs = onnx_session.run( output_names, input_feed={"input": input_data} )参考
onnx_cut.py[2]ONNX Python API[3]GoCoding 个人实践的经验分享,可关注公众号!
参考资料
[1] Anaconda: https://www.anaconda.com/products/individual#Downloads
[2] onnx_cut.py: https://gist.github.com/ikuokuo/29c5b7eaf6601b75302162ea28865fb9
[3] ONNX Python API: https://github.com/onnx/onnx/blob/master/docs/PythonAPIOverview.md