Keras训练 hdf5模型 转成 Tensorflow pb模型

keras由于其易于上手的特性,广受研究人员的好评。
但是Keras本身没有C++接口,而一般的生产环境都需要C++环境支持。所以能够在C++上部属深度学习模型至关重要。
所以我们需要将hdf5模型转化成tensorflow的 pb模型才可以运用到visual studio 2015中。
本文主要分三个步骤,采用环境为jupter notebook:

1,保存训练好的keras的hdf5模型

2,用keras进行hdf5模型的读取,并输入一个样本进行测试

3,hdf5模型 转成 tensorflow pb模型

4,输入一个样本 测试pb模型,和hdf5模型的输出进行比较

步骤1:保存训练好的keras的hdf5模型
主要参考
Keras框架下的保存模型和加载模型_人工智能_tszupup的博客-CSDN博客
https://blog.csdn.net/tszupup/article/details/85198949
我采用的代码是:

   	# 保存最好的模型
   	filepath="weights.best.hdf5"
   	checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True,
   	mode='max')
   	callbacks_list = [checkpoint]
   	history = DD_Net.fit([X_0,X_1],Y,
   	                    batch_size=len(Y),
   	                    epochs=500,
   	                    verbose=True,
   	                    shuffle=True,
   	                    callbacks=callbacks_list,
   	                    validation_data=([X_test_0,X_test_1],Y_test)      
   	                    )

步骤2:用keras进行hdf5模型的读取,并输入一个样本进行测试

   	#加载整个模型
   	DD_Net = load_model('weights.best.hdf5')	
我这里直接读取HDF5文件会报错,NameError: name 'poses_diff' is not defined,原因是没有将函数poses_diff()输入给模型,模型在数据处理上有些步骤缺失了,正确代码应该是
   	
   	# 加载整个模型
   	DD_Net = load_model('weights.best.hdf5',custom_objects={'poses_diff': poses_diff})

输入一个样本进行测试

   	#输入一个样本的数据,我这里处理过后的一个样本数据格式是([X_0,X_1],大家要根据自己的实际修改		
   	print(DD_Net.predict([X_0,X_1]))
   	print(np.argmax(DD_Net.predict([X_0,X_1])))

结果:
在这里插入图片描述
大家要记住这个输出,方便和后面pb模型的输出结果进行比较,如果一致的话就证明成功。

步骤3:hdf5模型 转成 tensorflow pb模型

   from keras.models import load_model
   import tensorflow as tf
   from keras import backend as K
   from tensorflow.python.framework import graph_io
   #from keras.models import TripletModel
    
   def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
       from tensorflow.python.framework.graph_util import convert_variables_to_constants
       graph = session.graph
       with graph.as_default():
           freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
           output_names = output_names or []
           output_names += [v.op.name for v in tf.global_variables()]
           input_graph_def = graph.as_graph_def()
           if clear_devices:
               for node in input_graph_def.node:
                   node.device = ""
           frozen_graph = convert_variables_to_constants(session, input_graph_def,
                                                         output_names, freeze_var_names)
           return frozen_graph
    
    
   """----------------------------------配置路径-----------------------------------"""
   h5_model_path='.\\JHMDB\\weights.best.hdf5'#Keras训练模型
   output_path='.\\JHMDB/'#转换后pb模型的地址
   pb_model_name='pb_model.pb'#转换后pb模型的文件名
    
    
   """----------------------------------导入keras模型------------------------------"""
   K.set_learning_phase(0)
   net_model = load_model(h5_model_path,custom_objects={'poses_diff': poses_diff})
    
   #print('input is :', net_model.input.name)
   #print ('output is:', net_model.output.name)
    
   """----------------------------------保存为.pb格式------------------------------"""
   sess = K.get_session()
   frozen_graph = freeze_session(K.get_session(), output_names=[net_model.output.op.name])
   graph_io.write_graph(frozen_graph, output_path, pb_model_name, as_text=False)

4,输入一个样本 测试pb模型,和hdf5模型的输出进行比较
这里我也是搞了很久,主要原因是因为没接触过tensorflow ,搞不懂tensorflow的输入输出。简单来说,直接套用下面的这个识别函数,我是根据几个博主的代码改过来的,原出处忘记了,在此对他们表示感谢。

只需要修改sess.run(outputVec,feed_dict)。

我的理解是feed_dict作为输入数据,outputVec作为输出数据

"""-----------------------------------------------定义识别函数-----------------------------------------"""
def recognize( pb_file_path):
    with tf.Graph().as_default():
        output_graph_def = tf.GraphDef()
 

        # 打开.pb模型
        with open(pb_file_path, "rb") as f:
            output_graph_def.ParseFromString(f.read())
            tensors = tf.import_graph_def(output_graph_def, name="")
            print("tensors:",tensors)
           
            
            
        # 在一个session中去run一个前向
        with tf.Session() as sess:
            init = tf.global_variables_initializer()
            sess.run(init)
            
            op = sess.graph.get_operations()
            '''
            # 打印图中有的操作
            for i,m in enumerate(op):
                print('op{}:'.format(i),m.values())
            '''
            outputVec = sess.graph.get_tensor_by_name('dense_1_1/Softmax:0')#名称要和模型里名称一致
            X0 = sess.graph.get_tensor_by_name('M_1:0')
            X1 = sess.graph.get_tensor_by_name('P_1:0')
            feed_dict = {X0:X_0 , X1:X_1}
            
            img_out_softmax = sess.run(outputVec,feed_dict)
 
            print("img_out_softmax:", img_out_softmax)
            print(np.argmax(img_out_softmax))
 
 
pb_path = 'C:\\Users\\Administrator\\DD-Net-master\\JHMDB\\pb_model.pb'
recognize(pb_path)

但是tensorflow里面,还要你知道这些输入数据是在模型的哪个地方输入的,要把这个地方的“名字”写上去,他才明白。(感觉好麻烦)
あの人は谁?忘れたくない人、忘れたくなかた人、忘れちゃダメな人、君の名前…
在这里插入图片描述
那我们怎么获得模型的名字呢
在这里插入图片描述

#获取节点名称

import tensorflow as tf
import os

model_name = 'C:\\Users\\Administrator\\DD-Net-master\\JHMDB\\pb_model.pb'

def create_graph():
    with tf.gfile.FastGFile(model_name, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        tf.import_graph_def(graph_def, name='')

create_graph()
tensor_name_list = [tensor.name for tensor in tf.get_default_graph().as_graph_def().node]
for tensor_name in tensor_name_list:
    print(tensor_name,'\n')

在这里插入图片描述
我这里的输入节点名字是M_1,P_1,至此我们就获得了输入节点的名字,输出节点同理找一下可得名字:dense_1_1/Softmax,注意名字后面要加 “ :0 ”,要求你要对你的模型比较熟悉。
名字写好后进行测试。
获得结果:和HDF5模型输出一致,成功!
在这里插入图片描述
最后,我永远喜欢宫水三叶.jpg
在这里插入图片描述

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值