Tensorflow002-准备在C++上可用的模型(forzen graph)

本来是想先写如何在C++上调用X64和X86的tensorflow的,但是写着写着发现,应该先准备一下C++上可用的forzen graph即.pb文件。

对于我这种深度学习的Starter(试着把自己提升这Practitioner)来说,几乎都是直接通过Keras保存model,而出来的格式一般都是.model或者.h5。

在C++上可用的则是.pb,然后发现.pb文件是无法读取里面的layer信息,我想这也是为什么要使用.pb吧!毕竟一个深度学习应用,最值钱最有价值的就是layer的排序以及hyper-parameter了。(注:关于不可读取这点,如果我理解错误了,还请纠正我,十分感谢)

我本来是尝试把.model转换成.pb,先是在x64上测试,正常工作,乐呵呵的继续尝试x86,一直失败,最后自己怀疑起来了是不是x86和x64在使用.pb上是不一样,结果确实如此。我这个从.model转换来的.pb无法在x86上无法使用。(或许有其他方法,但是我没继续深究)。

所以呢,重新训练了一下,现在在model.fit之后增加了:

print("[INFO] saving to model ckpt...")
tag = "the_tga_you_want"
from keras import backend as K
import tensorflow as tf
print(model.output.op.name) #The output is going to be used later
saver = tf.train.Saver()
saver.save(K.get_session(), 'files_holder_ckpt/{}.ckpt'.format(tag))

这样子你就可以保存出来.ckpt的文件,注意这里还会print一个output_node_name的信息,这个要记下来,待会儿转换到.pb的时候是需要的。

[INFO] saving to model ckpt...
dense_6/Softmax #例子

在这个步骤后,你将拥有下面的文件

checkpoint
keras_model.ckpt.data-00000-of-00001
keras_model.ckpt.index
keras_model.ckpt.meta 

接下来呢,再把这个.ckpt转换成.pb就行了,这个时候output_nodel_name就可以用上了。

#%% if you wish to know more about this function, please viast the tensorflow.
def freeze_graph(input_checkpoint,output_graph):
    '''
    :param input_checkpoint: full path to your .ckpt file
    :param output_graph: full path to save your .pb file
    :return:
    ''' 
 
    #what you get from second step
    output_node_names = "dense_3/Softmax" 
    saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)
    graph = tf.get_default_graph() 
    input_graph_def = graph.as_graph_def()
 
    with tf.Session() as sess:
        saver.restore(sess, input_checkpoint) 
        output_graph_def = graph_util.convert_variables_to_constants(  #
            sess=sess,
            input_graph_def=input_graph_def,
            output_node_names=output_node_names.split(","))
 
        #saving out the model
        with tf.gfile.GFile(output_graph, "wb") as f: 
            f.write(output_graph_def.SerializeToString())
        print("%d ops in the final graph." % len(output_graph_def.node))
 
        # for op in graph.get_operations():
        #     print(op.name, op.values())
        
tag = "tag"
input_checkpoint='files_holder_ckpt/{}.ckpt'.format(tag)  #full path to your .ckpt file
out_pb_path="files_holder_pb/{}.pb".format(tag)           #full path to save your .pb file

graph = tf.get_default_graph()
input_graph_def = graph.as_graph_def()  

freeze_graph(input_checkpoint,out_pb_path)

这个时候呢,你就拥有了.pb文件了,还没完,既然我们知道了output_node_name,这个时候就需要知道input_node_name。通过以下代码检查:

import tensorflow as tf
gf = tf.GraphDef()
gf.ParseFromString(open('/your/path/to/graphname.pb','rb').read())
[n.name + '=>' +  n.op for n in gf.node if n.op in ( 'Softmax','Placeholder')]

输出:

>>> 'input_2=>Placeholder', 'dense_3/Softmax=>Softmax

现在你有用了C++所需要的模型,以及对应的接口信息了,当然你需要准备对应的label.txt文件。

	string graph = "pb/frozen_model.pb";
	string label = "pb/forzen_model_label.txt"; 
	string input_layer = "input_2:0";
	string output_layer = "dense_3/Softmax:0";  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值