keras h5 模型转换 onnx 并推理测试

目录

一.版本介绍

转换:

keras 2.1.5
tensorflow 1.13.1
tf2onnx 1.5.5

推理:

opencv 4.4.0
onnx 1.5.0
onnxruntime 1.6.0

二.转换流程

  • ① h5 to pb
  • ② pb to onnx

三.转换过程

首先准备自己的h5模型;这里要注意h5模型的保存方式,不同保存方式,对应不同加载方式,如下:

> 训练:  model.save()    
> 加载:  model.load_model()
> 训练:  model.save_weights()    
> 加载:    
> 		model = LeNet()     
> 		model.load_weights(weight_path) 
  • ① h5 to pb
# h5 to  pb
from keras.models import load_model
import tensorflow as tf
import os
from keras import backend as K
from tensorflow.python.framework import graph_util, graph_io
import tensorflow as tf
from tensorflow.python.platform import gfile

def h5_to_pb(h5_weight_path, output_dir, out_prefix="output_", log_tensorboard=True):
    if not os.path.exists(output_dir):
        os.mkdir(output_dir)
    h5_model =  load_model(h5_weight_path) 
    out_nodes = []
    for i in range(len(h5_model.outputs)):
        out_nodes.append(out_prefix + str(i + 1))
        tf.identity(h5_model.output[i], out_prefix + str(i + 1))

    model_name = os.path.splitext(os.path.split(h5_weight_path)[-1])[0] + '.pb'

    sess = K.get_session()
    init_graph = sess.graph.as_graph_def()
    main_graph = graph_util.convert_variables_to_constants(sess, init_graph, out_nodes)
    graph_io.write_graph(main_graph, output_dir, name=model_name, as_text=False)

#读取模型各层
def read_pb(GRAPH_PB_PATH):
    with tf.Session() as sess:
        print("load graph!!!")
        with gfile.FastGFile(GRAPH_PB_PATH, 'rb') as f:
            graph_def = tf.GraphDef()在这里插入代码片
            graph_def.ParseFromString(f.read())
            tf.import_graph_def(graph_def, name='')
            for i, n in enumerate(graph_def.node):
                print("Name of the node - %s" % n.name)

h5_to_pb(h5_weight_path='model.h5', output_dir='./')
read_pb('./model.pb')
  • ② pb to onnx
#安装tf2onnx
pip install tf2onnx==1.5.5

这里需要使用netron查看pb模型的输入,输出层名称。

https://netron.app/
keras h5 模型转换 onnx 并推理测试

python -m tf2onnx.convert --input ./model.pb  --inputs conv2d_1_input:0 --outputs output_1:0 --output ./model.onnx

四.推理测试

这里使用minst数据集训练的lenet模型测试,故图像预处理为(28,28,1) 。

import cv2
from keras.models import load_model
import numpy as np
import onnxruntime as rt
from keras.preprocessing.image import img_to_array
import time

#keras推理
img = cv2.imread('1.jpg',0)
img = cv2.resize(img,(28,28))
img = np.array([img_to_array(img)],dtype='float')/255.0
model = load_model('model.h5')
predict = model.predict(img)
p = [round(i,5) for i in predict[0]]
print('\n keras :')
print(p)

#opencv dnn pb
img = cv2.imread('1.jpg',0)
img = cv2.resize(img,(28,28))
img = np.array([img_to_array(img)],dtype='float')/255.0
img = img.transpose((0,3,1,2))
net = cv2.dnn.readNetFromTensorflow("model.pb")
net.setInput(img)  
out = net.forward()  
print('\n opencv dnn pb:')
p = [round(i,5) for i in out[0]]
print(p)

#onnxruntime 
img = cv2.imread('1.jpg',0)
img = cv2.resize(img,(28,28))
img = np.array([img_to_array(img)],dtype='float')/255.0
img= img.astype(np.float32)
sess=rt.InferenceSession('model.onnx')
input_name=sess.get_inputs()[0].name
res=sess.run(None,{input_name:img})
print('\n onnxruntime :')
print([round(i,5) for i in res[0]])

如图推理结果一致即可:
keras h5 模型转换 onnx 并推理测试keras h5 模型转换 onnx 并推理测试

上一篇:360 政企安全集团基于 Flink 的 PB 级数据即席查询实践


下一篇:作业帮 PB 级低成本日志检索服务解读