精华内容
下载资源
问答
  • 主要介绍了tensorflow实现将ckpt转pb文件的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
  • tensorflow实现将ckpt转pb文件

    万次阅读 多人点赞 2018-09-01 07:32:30
    tensorflow实现将ckpt转pb文件 【尊重原创,转载请注明出处】:https://blog.csdn.net/guyuealian/article/details/82218092 本博客实现将自己训练保存的ckpt模型转换为pb文件,该方法适用于任何ckpt模型,当然你...

    tensorflow实现将ckpt转pb文件

    尊重原创,转载请注明出处】:https://blog.csdn.net/guyuealian/article/details/82218092

       本博客实现将自己训练保存的ckpt模型转换为pb文件,该方法适用于任何ckpt模型,当然你需要确定ckpt模型输入/输出的节点名称。


    目录

    tensorflow实现将ckpt转pb文件

    一、CKPT 转换成 PB格式

    二、 pb模型预测

    三、源码下载和资料推荐

        1、训练方法

        2、本博客Github地址

        3、将模型移植Android的方法


       使用 tf.train.saver()保存模型时会产生多个文件,会把计算图的结构和图上参数取值分成了不同的文件存储。这种方法是在TensorFlow中是最常用的保存方式。

        例如:下面的代码运行后,会在save目录下保存了四个文件:

    import tensorflow as tf
    # 声明两个变量
    v1 = tf.Variable(tf.random_normal([1, 2]), name="v1")
    v2 = tf.Variable(tf.random_normal([2, 3]), name="v2")
    init_op = tf.global_variables_initializer() # 初始化全部变量
    saver = tf.train.Saver() # 声明tf.train.Saver类用于保存模型
    with tf.Session() as sess:
        sess.run(init_op)
        print("v1:", sess.run(v1)) # 打印v1、v2的值一会读取之后对比
        print("v2:", sess.run(v2))
        saver_path = saver.save(sess, "save/model.ckpt")  # 将模型保存到save/model.ckpt文件
        print("Model saved in file:", saver_path)
    

        其中

    • checkpoint是检查点文件,文件保存了一个目录下所有的模型文件列表;
    • model.ckpt.meta文件保存了TensorFlow计算图的结构,可以理解为神经网络的网络结构,该文件可以被 tf.train.import_meta_graph 加载到当前默认的图来使用。
    • ckpt.data : 保存模型中每个变量的取值

       但很多时候,我们需要将TensorFlow的模型导出为单个文件(同时包含模型结构的定义与权重),方便在其他地方使用(如在Android中部署网络)。利用tf.train.write_graph()默认情况下只导出了网络的定义(没有权重),而利用tf.train.Saver().save()导出的文件graph_def与权重是分离的,因此需要采用别的方法。 我们知道,graph_def文件中没有包含网络中的Variable值(通常情况存储了权重),但是却包含了constant值,所以如果我们能把Variable转换为constant,即可达到使用一个文件同时存储网络架构与权重的目标。

        TensoFlow为我们提供了convert_variables_to_constants()方法,该方法可以固化模型结构,将计算图中的变量取值以常量的形式保存,而且保存的模型可以移植到Android平台。


    一、CKPT 转换成 PB格式

        将CKPT 转换成 PB格式的文件的过程可简述如下:

    • 通过传入 CKPT 模型的路径得到模型的图和变量数据
    • 通过 import_meta_graph 导入模型中的图
    • 通过 saver.restore 从模型中恢复图中各个变量的数据
    • 通过 graph_util.convert_variables_to_constants 将模型持久化

     下面的CKPT 转换成 PB格式例子,是我训练GoogleNet InceptionV3模型保存的ckpt转pb文件的例子,训练过程可参考博客:

    使用自己的数据集训练GoogLenet InceptionNet V1 V2 V3模型(TensorFlow)》:https://blog.csdn.net/guyuealian/article/details/81560537

    def freeze_graph(input_checkpoint,output_graph):
        '''
    
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
    
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        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,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
    
            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())

    说明:

    1、函数freeze_graph中,最重要的就是要确定“指定输出的节点名称”,这个节点名称必须是原模型中存在的节点,对于freeze操作,我们需要定义输出结点的名字。因为网络其实是比较复杂的,定义了输出结点的名字,那么freeze的时候就只把输出该结点所需要的子图都固化下来,其他无关的就舍弃掉。因为我们freeze模型的目的是接下来做预测。所以,output_node_names一般是网络模型最后一层输出的节点名称,或者说就是我们预测的目标。

     2、在保存的时候,通过convert_variables_to_constants函数来指定需要固化的节点名称,对于鄙人的代码,需要固化的节点只有一个:output_node_names。注意节点名称张量的名称的区别,例如:“input:0”是张量的名称,而"input"表示的是节点的名称。

    3、源码中通过graph = tf.get_default_graph()获得默认的图,这个图就是由saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)恢复的图,因此必须先执行tf.train.import_meta_graph,再执行tf.get_default_graph() 。

    4、实质上,我们可以直接在恢复的会话sess中,获得默认的网络图,更简单的方法,如下:

    def freeze_graph(input_checkpoint,output_graph):
        '''
    
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
    
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)
    
        with tf.Session() as sess:
            saver.restore(sess, input_checkpoint) #恢复图并得到数据
            output_graph_def = graph_util.convert_variables_to_constants(  # 模型持久化,将变量值固定
                sess=sess,
                input_graph_def=sess.graph_def,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
    
            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)) #得到当前图有几个操作节点

    调用方法很简单,输入ckpt模型路径,输出pb模型的路径即可:

        # 输入ckpt模型路径
        input_checkpoint='models/model.ckpt-10000'
        # 输出pb模型的路径
        out_pb_path="models/pb/frozen_model.pb"
        # 调用freeze_graph将ckpt转为pb
        freeze_graph(input_checkpoint,out_pb_path)

    5、上面以及说明:在保存的时候,通过convert_variables_to_constants函数来指定需要固化的节点名称,对于鄙人的代码,需要固化的节点只有一个:output_node_names。因此,其他网络模型,也可以通过简单的修改输出的节点名称output_node_names,将ckpt转为pb文件 。

           PS:注意节点名称,应包含name_scope 和 variable_scope命名空间,并用“/”隔开,如"InceptionV3/Logits/SpatialSqueeze"


    二、 pb模型预测

        下面是预测pb模型的代码

    
    def freeze_graph_test(pb_path, image_path):
        '''
        :param pb_path:pb文件的路径
        :param image_path:测试图片的路径
        :return:
        '''
        with tf.Graph().as_default():
            output_graph_def = tf.GraphDef()
            with open(pb_path, "rb") as f:
                output_graph_def.ParseFromString(f.read())
                tf.import_graph_def(output_graph_def, name="")
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
    
                # 定义输入的张量名称,对应网络结构的输入张量
                # input:0作为输入图像,keep_prob:0作为dropout的参数,测试时值为1,is_training:0训练参数
                input_image_tensor = sess.graph.get_tensor_by_name("input:0")
                input_keep_prob_tensor = sess.graph.get_tensor_by_name("keep_prob:0")
                input_is_training_tensor = sess.graph.get_tensor_by_name("is_training:0")
    
                # 定义输出的张量名称
                output_tensor_name = sess.graph.get_tensor_by_name("InceptionV3/Logits/SpatialSqueeze:0")
    
                # 读取测试图片
                im=read_image(image_path,resize_height,resize_width,normalization=True)
                im=im[np.newaxis,:]
                # 测试读出来的模型是否正确,注意这里传入的是输出和输入节点的tensor的名字,不是操作节点的名字
                # out=sess.run("InceptionV3/Logits/SpatialSqueeze:0", feed_dict={'input:0': im,'keep_prob:0':1.0,'is_training:0':False})
                out=sess.run(output_tensor_name, feed_dict={input_image_tensor: im,
                                                            input_keep_prob_tensor:1.0,
                                                            input_is_training_tensor:False})
                print("out:{}".format(out))
                score = tf.nn.softmax(out, name='pre')
                class_id = tf.argmax(score, 1)
                print "pre class_id:{}".format(sess.run(class_id))

    说明:

    1、与ckpt预测不同的是,pb文件已经固化了网络模型结构,因此,即使不知道原训练模型(train)的源码,我们也可以恢复网络图,并进行预测。恢复模型十分简单,只需要从读取的序列化数据中导入网络结构即可:

    tf.import_graph_def(output_graph_def, name="")
    

    2、但必须知道原网络模型的输入和输出的节点名称(当然了,传递数据时,是通过输入输出的张量来完成的)。由于InceptionV3模型的输入有三个节点,因此这里需要定义输入的张量名称,它对应网络结构的输入张量:

    input_image_tensor = sess.graph.get_tensor_by_name("input:0")
    input_keep_prob_tensor = sess.graph.get_tensor_by_name("keep_prob:0")
    input_is_training_tensor = sess.graph.get_tensor_by_name("is_training:0")

    以及输出的张量名称:

    output_tensor_name = sess.graph.get_tensor_by_name("InceptionV3/Logits/SpatialSqueeze:0")
    

    3、预测时,需要feed输入数据:

    # 测试读出来的模型是否正确,注意这里传入的是输出和输入节点的tensor的名字,不是操作节点的名字
    # out=sess.run("InceptionV3/Logits/SpatialSqueeze:0", feed_dict={'input:0': im,'keep_prob:0':1.0,'is_training:0':False})
    out=sess.run(output_tensor_name, feed_dict={input_image_tensor: im,
                                                input_keep_prob_tensor:1.0,
                                                input_is_training_tensor:False})

     4、其他网络模型预测时,也可以通过修改输入和输出的张量的名称 。

           PS:注意张量的名称,即为:节点名称+“:”+“id号”,如"InceptionV3/Logits/SpatialSqueeze:0"

    完整的CKPT 转换成 PB格式和预测的代码如下:

    # -*-coding: utf-8 -*-
    """
        @Project: tensorflow_models_nets
        @File   : convert_pb.py
        @Author : panjq
        @E-mail : pan_jinquan@163.com
        @Date   : 2018-08-29 17:46:50
        @info   :
        -通过传入 CKPT 模型的路径得到模型的图和变量数据
        -通过 import_meta_graph 导入模型中的图
        -通过 saver.restore 从模型中恢复图中各个变量的数据
        -通过 graph_util.convert_variables_to_constants 将模型持久化
    """
    
    import tensorflow as tf
    from create_tf_record import *
    from tensorflow.python.framework import graph_util
    
    resize_height = 299  # 指定图片高度
    resize_width = 299  # 指定图片宽度
    depths = 3
    
    def freeze_graph_test(pb_path, image_path):
        '''
        :param pb_path:pb文件的路径
        :param image_path:测试图片的路径
        :return:
        '''
        with tf.Graph().as_default():
            output_graph_def = tf.GraphDef()
            with open(pb_path, "rb") as f:
                output_graph_def.ParseFromString(f.read())
                tf.import_graph_def(output_graph_def, name="")
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
    
                # 定义输入的张量名称,对应网络结构的输入张量
                # input:0作为输入图像,keep_prob:0作为dropout的参数,测试时值为1,is_training:0训练参数
                input_image_tensor = sess.graph.get_tensor_by_name("input:0")
                input_keep_prob_tensor = sess.graph.get_tensor_by_name("keep_prob:0")
                input_is_training_tensor = sess.graph.get_tensor_by_name("is_training:0")
    
                # 定义输出的张量名称
                output_tensor_name = sess.graph.get_tensor_by_name("InceptionV3/Logits/SpatialSqueeze:0")
    
                # 读取测试图片
                im=read_image(image_path,resize_height,resize_width,normalization=True)
                im=im[np.newaxis,:]
                # 测试读出来的模型是否正确,注意这里传入的是输出和输入节点的tensor的名字,不是操作节点的名字
                # out=sess.run("InceptionV3/Logits/SpatialSqueeze:0", feed_dict={'input:0': im,'keep_prob:0':1.0,'is_training:0':False})
                out=sess.run(output_tensor_name, feed_dict={input_image_tensor: im,
                                                            input_keep_prob_tensor:1.0,
                                                            input_is_training_tensor:False})
                print("out:{}".format(out))
                score = tf.nn.softmax(out, name='pre')
                class_id = tf.argmax(score, 1)
                print "pre class_id:{}".format(sess.run(class_id))
    
    
    def freeze_graph(input_checkpoint,output_graph):
        '''
    
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
    
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)
    
        with tf.Session() as sess:
            saver.restore(sess, input_checkpoint) #恢复图并得到数据
            output_graph_def = graph_util.convert_variables_to_constants(  # 模型持久化,将变量值固定
                sess=sess,
                input_graph_def=sess.graph_def,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
    
            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 sess.graph.get_operations():
            #     print(op.name, op.values())
    
    def freeze_graph2(input_checkpoint,output_graph):
        '''
    
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
    
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        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,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
    
            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())
    
    
    if __name__ == '__main__':
        # 输入ckpt模型路径
        input_checkpoint='models/model.ckpt-10000'
        # 输出pb模型的路径
        out_pb_path="models/pb/frozen_model.pb"
        # 调用freeze_graph将ckpt转为pb
        freeze_graph(input_checkpoint,out_pb_path)
    
        # 测试pb模型
        image_path = 'test_image/animal.jpg'
        freeze_graph_test(pb_path=out_pb_path, image_path=image_path)
    

    三、源码下载和资料推荐

        1、训练方法

         上面的CKPT 转换成 PB格式例子,是我训练GoogleNet InceptionV3模型保存的ckpt转pb文件的例子,训练过程可参考博客:

    使用自己的数据集训练GoogLenet InceptionNet V1 V2 V3模型(TensorFlow)》:https://blog.csdn.net/guyuealian/article/details/81560537

        2、本博客Github地址

    Github源码:https://github.com/PanJinquan/tensorflow_models_learning中的convert_pb.py文件

    预训练模型下载地址:https://download.csdn.net/download/guyuealian/10610847

        3、将模型移植Android的方法

         pb文件是可以移植到Android平台运行的,其方法,可参考:

    《将tensorflow训练好的模型移植到Android (MNIST手写数字识别)》

    https://blog.csdn.net/guyuealian/article/details/79672257

     

    展开全文
  • ckpt from tensorflow.python import pywrap_tensorflow checkpoint_path = 'model.ckpt-8000' reader = pywrap_tensorflow.NewCheckpointReader(checkpoint_path) ...pb import tensorflow as tf import
  • Semantic-Segmentation-Suite 的ckpt转 pb代码,根据最后一层更改。
  • 网上关于tensorflow模型文件ckpt格式转pb文件的帖子很多,本人几乎尝试了所有方法,最后终于成功了,现总结如下。方法无外乎下面两种: 使用tensorflow.python.tools.freeze_graph.freeze_graph 使用graph_util....
  • ckpt pb 如果只有ckpt文件,例如三个ckpt文件model-xxx.data, model-xxx.meta, model-xxx.index, pb文件方式很简单,按照上面的链接就可以,只需要确定好输出节点名称就可以。如果不知道,可以打印ckpt里面的...

    之前写过一篇文章有关tensorflow ckpt和pb模型之间转换的操作, 这次再详细说下里面的一些坑.

    ckpt 转 pb

    如果只有ckpt文件,例如三个ckpt文件model-xxx.data, model-xxx.meta, model-xxx.index, 转成pb文件方式很简单,按照上面的链接就可以,只需要确定好输出节点名称就可以。如果不知道,可以打印ckpt里面的节点名称,或者使用tf.summary.FileWriter保存模型用tensorboard去查看。

    我在转一个模型的时候,发现打印ckpt里面的节点名称,有两种方法:

    # read node name way 1
    import tensorflow as tf
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph(ckpt + '.meta', clear_devices=True)
        graph_def = tf.get_default_graph().as_graph_def(add_shapes=True)
        node_list=[n.name for n in graph_def.node]
        for node in node_list:
            print (node)
    
    #read node name way 2
    #the two ways result different
    from tensorflow.python import pywrap_tensorflow
    reader = pywrap_tensorflow.NewCheckpointReader(ckpt)
    var_to_shape_map = reader.get_variable_to_shape_map()
    for key in var_to_shape_map:
        print("tensor_name: ", key)
    

    但是这两种方法打印出来的节点名称不一样,按照经验来说,这两种方式应该打印的一样,我也没有找到原因在哪。还有一个方法是直接使用graph.get_operations(),结果和第一种一致。

    pb转tvm

    因为生成pb后需要转成tvm,如果模型里面有resize layer,那么在转成pb的时候,需要加入add_shapes=True选项,不然的话转出来的pb里面,所有的node信息都不包含_output_shapes属性。没有这个属性对于卷积层和BN层没有影响,但会影响tvm的转换,按照现在的tvm版本(截止2019.08.20)会在tensorlfow.py里有关resize的函数报错:TypeError: 'NoneType' object is not subscriptable. 所以需要让和resize相关的layer都保留_output_shapes属性。

    除了这个方法外,还可以对已有的pb文件进行node信息修改。首先,通过以下代码打印出pb文件中所有的节点信息:

    graph = tf.GraphDef()
    with tf.gfile.Open(RAW_FROZEN_GRAPH_FP, 'rb') as f:
    	data = f.read()
    	graph.ParseFromString(data)
    for node in graph.node:
        print (node)
    

    node的信息主要包括以下几类:

    • name–类型string。 在模型定义的时候由工程师定义,如果工程师没有定义的话会自动的利用node作为其值

    • op–类型string。表示这是一个什么op,比如加减乘除,当在运行的时候,编译器会根据node调用相应的算子来做计算

    • input–类型list.。列表中包含了该节点输入,是有序的,不可以被assign

    • attr–类型map。map中的key和value一般是指该node的配置信息

    print (node.name)
    print (node.node_def.attr)
    print (node.input)
    

    这个时候在graph里的node都可以被修改,可以往graph里增加、删除、修改某一个node,如果此时还有另外一个pb的话,可以通过上面的方法得到一个graph2,可以把两个graph的node进行组合得到一个新的nodes然后生成一个新的pb文件,如下所示(先不考虑这个图是否正确):

    nodes = graph2.node[0:10] + graph.node[2:]
    output_graph = graph_pb2.GraphDef()
    output_graph.node.extend(nodes)
    with tf.gfile.GFile(TRIMMED_FROZEN_GRAPH_FP, 'w') as f:
    	f.write(output_graph.SerializeToString())
    
    

    或者我们也可以直接取graph中的某一部分node组成个新的graph nodes,然后生成新的graph。

    如果要对某一个node修改,特别的,解决上面所说的问题,增加resize layer_output_shapes属性,可以按照下面操作:

    new_graph_def = graph_pb2.GraphDef()
    for node in graph_def.node:
        if hasattr(node, 'name') and node.name == 'part4_upsample':
            print ('find one resize bilinear')
            node.attr['_output_shapes'].CopyFrom(
                tf.AttrValue(list=tf.AttrValue.ListValue(
                    shape=[tensor_shape_pb2.TensorShapeProto(
                        dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=-1),
                             tensor_shape_pb2.TensorShapeProto.Dim(size=12),
                             tensor_shape_pb2.TensorShapeProto.Dim(size=12),
                             tensor_shape_pb2.TensorShapeProto.Dim(size=24)])])))
         new_graph_def.node.extend([copy.deepcopy(node)])
     # save new graph
    with tf.gfile.GFile(OUTPUT_GRAPH_DEF_FILE, "wb") as f:
        f.write(new_graph_def.SerializeToString())
    

    除了修改原有的node之外,还可以新建个node插入进去:

    # 根据已有node创建新的node
    new_node = tf.NodeDef()  # 构建一个op对象,所有属性都为空
    new_node.op = 'Conv2D'
    new_node.name = 'new_Conv_1'
    for input_name in old_op.input:  # 原始op的input导入进来
           new_node.input.extend([input_name])
    new_node.attr["T"].CopyFrom(old_op.attr["T"])
    new_node.attr["use_cudnn_on_gpu"].CopyFrom(old_op.attr["use_cudnn_on_gpu"])
    new_node.attr["strides"].CopyFrom(old_op.attr["strides"])
    new_node.attr["padding"].CopyFrom(old_op.attr["padding"])
    
    # 创建全新的node
    new_op = tf.NodeDef()
    new_op.op = "Const"
    new_op.name = conv_op.name
    new_op.attr["dtype"].CopyFrom(tf.AttrValue( type=tf.int32.as_datatype_enum))
    new_op.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto([0, 0, 0, 0, 0, 0, 0, 0], tf.int32, [4,2])))
    

    node中attr为map,每一个map中key为字符串,value为的类型由下面9种,每种对应的原型如下表所示:

    repeated bytes s = 2; // "list(string)"
    repeated int64 i = 3 [packed = true]; // "list(int)"
    repeated float f = 4 [packed = true]; // "list(float)"
    repeated bool b = 5 [packed = true]; // "list(bool)"
    repeated DataType type = 6 [packed = true]; // "list(type)"
    repeated TensorShapeProto shape = 7; // "list(shape)"
    repeated TensorProto tensor = 8; // "list(tensor)"
    repeated NameAttrList func = 9; // "list(attr)"
    # list 也为value的一种类型
    

    每一种类型初始化方式:

    CopyFrom(tf.AttrValue( s=b'hello,world'))
    CopyFrom(tf.AttrValue( i=88 ))
    CopyFrom(tf.AttrValue( f=88.0 ))
    CopyFrom(tf.AttrValue( b=1/0 ))
    new_op.attr["dtype"].CopyFrom(tf.AttrValue( type=tf.int32.as_datatype_enum))
    from tensorflow.core.framework import tensor_shape_pb2
    tensor_shape_pb2.TensorShapeProto(dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=-1 if d.value is None else d.vaule) for d in dims])
    new_op.attr["value"].CopyFrom(tf.AttrValue(tensor=tf.make_tensor_proto([0, 0, 0, 0, 0, 0, 0, 0], tf.int32, [4, 2])))
    # func目前没有没有遇到过
    stride_list = [1, 2, 2, 1]
    new_node.attr["strides"].CopyFrom(tf.AttrValue(list=tf.AttrValue.ListValue(i=stride_list)))
    

    转tvm时遇到的一些问题:

    1. tensorflow 1.8 1.9 1.10 1.11, 1.12 1.13.1 1.13.2 出问题op, ‘resize_bilinear’, 提示TypeError: 'NoneType' object is not subscriptable 解决方法是在转成pb的时候,加入 (add_shapes=True) 选项,这样resize_bilinear就会有_output_shapes选项。
      2.在将pb转成tvm的时候,设置的layout是NCHW,但tvm中的转换代码里面,默认的仍然是NHWC格式,如果将layout设置为NHWC,会提示tvm的cuda转换不支持NHWC格式。将layout设置为NCHW后,虽然可以成功转换,但生的json文件里,除了第一层和最后一个输出层是NHWC格式外,其余层貌似是NCHW。

    2. tensorflow中的输入层名字,转pb为tvm时的shape_dict名字及运行tvm时,set_input的名字,都需要保持一致,否则得到不到正确的结果

    参考链接:
    https://blog.csdn.net/feng__shuai/article/details/96423823
    https://codeday.me/bug/20190430/1010659.html
    https://github.com/KleinYuan/tf-tailor
    https://github.com/huachao1001/CNNGraph
    https://discuss.tvm.ai/t/resolved-problem-with-resizebilinear-in-tensorflow/3445

    展开全文
  • tensorflow | tensorflow实现将ckpt转pb文件

    千次阅读 2019-01-06 17:02:20
    本博客实现将自己训练保存的...tensorflow实现将ckpt转pb文件 一、CKPT 转换成 PB格式 二、 pb模型预测 三、源码下载和资料推荐  1、训练方法  2、本博客Github地址  3、将模型移植Android的方法  使用 ...

       本博客实现将自己训练保存的ckpt模型转换为pb文件,该方法适用于任何ckpt模型,当然你需要确定ckpt模型输入/输出的节点名称。

    目录

    tensorflow实现将ckpt转pb文件

    一、CKPT 转换成 PB格式

    二、 pb模型预测

    三、源码下载和资料推荐

        1、训练方法

        2、本博客Github地址

        3、将模型移植Android的方法

       使用 tf.train.saver()保存模型时会产生多个文件,会把计算图的结构和图上参数取值分成了不同的文件存储。这种方法是在TensorFlow中是最常用的保存方式。

        例如:下面的代码运行后,会在save目录下保存了四个文件:

    import tensorflow as tf
    # 声明两个变量
    v1 = tf.Variable(tf.random_normal([1, 2]), name="v1")
    v2 = tf.Variable(tf.random_normal([2, 3]), name="v2")
    init_op = tf.global_variables_initializer() # 初始化全部变量
    saver = tf.train.Saver() # 声明tf.train.Saver类用于保存模型
    with tf.Session() as sess:
        sess.run(init_op)
        print("v1:", sess.run(v1)) # 打印v1、v2的值一会读取之后对比
        print("v2:", sess.run(v2))
        saver_path = saver.save(sess, "save/model.ckpt")  # 将模型保存到save/model.ckpt文件
        print("Model saved in file:", saver_path)


        其中,checkpoint是检查点文件,文件保存了一个目录下所有的模型文件列表;
    model.ckpt.meta文件保存了TensorFlow计算图的结构,可以理解为神经网络的网络结构,该文件可以被 tf.train.import_meta_graph 加载到当前默认的图来使用。
    ckpt.data : 保存模型中每个变量的取值
       但很多时候,我们需要将TensorFlow的模型导出为单个文件(同时包含模型结构的定义与权重),方便在其他地方使用(如在Android中部署网络)。利用tf.train.write_graph()默认情况下只导出了网络的定义(没有权重),而利用tf.train.Saver().save()导出的文件graph_def与权重是分离的,因此需要采用别的方法。 我们知道,graph_def文件中没有包含网络中的Variable值(通常情况存储了权重),但是却包含了constant值,所以如果我们能把Variable转换为constant,即可达到使用一个文件同时存储网络架构与权重的目标。

        TensoFlow为我们提供了convert_variables_to_constants()方法,该方法可以固化模型结构,将计算图中的变量取值以常量的形式保存,而且保存的模型可以移植到Android平台。

    一、CKPT 转换成 PB格式
        将CKPT 转换成 PB格式的文件的过程可简述如下:

    通过传入 CKPT 模型的路径得到模型的图和变量数据
    通过 import_meta_graph 导入模型中的图
    通过 saver.restore 从模型中恢复图中各个变量的数据
    通过 graph_util.convert_variables_to_constants 将模型持久化
     下面的CKPT 转换成 PB格式例子,是我训练GoogleNet InceptionV3模型保存的ckpt转pb文件的例子,训练过程可参考博客:《使用自己的数据集训练GoogLenet InceptionNet V1 V2 V3模型(TensorFlow)》:

     

    def freeze_graph(input_checkpoint,output_graph):
        '''
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
     
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        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,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
     
            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())


    说明:

    1、函数freeze_graph中,最重要的就是要确定“指定输出的节点名称”,这个节点名称必须是原模型中存在的节点,对于freeze操作,我们需要定义输出结点的名字。因为网络其实是比较复杂的,定义了输出结点的名字,那么freeze的时候就只把输出该结点所需要的子图都固化下来,其他无关的就舍弃掉。因为我们freeze模型的目的是接下来做预测。所以,output_node_names一般是网络模型最后一层输出的节点名称,或者说就是我们预测的目标。

     2、在保存的时候,通过convert_variables_to_constants函数来指定需要固化的节点名称,对于鄙人的代码,需要固化的节点只有一个:output_node_names。注意节点名称与张量的名称的区别,例如:“input:0”是张量的名称,而"input"表示的是节点的名称。

    3、源码中通过graph = tf.get_default_graph()获得默认的图,这个图就是由saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)恢复的图,因此必须先执行tf.train.import_meta_graph,再执行tf.get_default_graph() 。

    4、实质上,我们可以直接在恢复的会话sess中,获得默认的网络图,更简单的方法,如下:

    def freeze_graph(input_checkpoint,output_graph):
        '''
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
     
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)
     
        with tf.Session() as sess:
            saver.restore(sess, input_checkpoint) #恢复图并得到数据
            output_graph_def = graph_util.convert_variables_to_constants(  # 模型持久化,将变量值固定
                sess=sess,
                input_graph_def=sess.graph_def,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
     
            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)) #得到当前图有几个操作节点


    调用方法很简单,输入ckpt模型路径,输出pb模型的路径即可:

        # 输入ckpt模型路径
        input_checkpoint='models/model.ckpt-10000'
        # 输出pb模型的路径
        out_pb_path="models/pb/frozen_model.pb"
        # 调用freeze_graph将ckpt转为pb
        freeze_graph(input_checkpoint,out_pb_path)
    5、上面以及说明:在保存的时候,通过convert_variables_to_constants函数来指定需要固化的节点名称,对于鄙人的代码,需要固化的节点只有一个:output_node_names。因此,其他网络模型,也可以通过简单的修改输出的节点名称output_node_names,将ckpt转为pb文件 。

           PS:注意节点名称,应包含name_scope 和 variable_scope命名空间,并用“/”隔开,如"InceptionV3/Logits/SpatialSqueeze"

    二、 pb模型预测
        下面是预测pb模型的代码

     

    def freeze_graph_test(pb_path, image_path):
        '''
        :param pb_path:pb文件的路径
        :param image_path:测试图片的路径
        :return:
        '''
        with tf.Graph().as_default():
            output_graph_def = tf.GraphDef()
            with open(pb_path, "rb") as f:
                output_graph_def.ParseFromString(f.read())
                tf.import_graph_def(output_graph_def, name="")
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
     
                # 定义输入的张量名称,对应网络结构的输入张量
                # input:0作为输入图像,keep_prob:0作为dropout的参数,测试时值为1,is_training:0训练参数
                input_image_tensor = sess.graph.get_tensor_by_name("input:0")
                input_keep_prob_tensor = sess.graph.get_tensor_by_name("keep_prob:0")
                input_is_training_tensor = sess.graph.get_tensor_by_name("is_training:0")
     
                # 定义输出的张量名称
                output_tensor_name = sess.graph.get_tensor_by_name("InceptionV3/Logits/SpatialSqueeze:0")
     
                # 读取测试图片
                im=read_image(image_path,resize_height,resize_width,normalization=True)
                im=im[np.newaxis,:]
                # 测试读出来的模型是否正确,注意这里传入的是输出和输入节点的tensor的名字,不是操作节点的名字
                # out=sess.run("InceptionV3/Logits/SpatialSqueeze:0", feed_dict={'input:0': im,'keep_prob:0':1.0,'is_training:0':False})
                out=sess.run(output_tensor_name, feed_dict={input_image_tensor: im,
                                                            input_keep_prob_tensor:1.0,
                                                            input_is_training_tensor:False})
                print("out:{}".format(out))
                score = tf.nn.softmax(out, name='pre')
                class_id = tf.argmax(score, 1)
                print "pre class_id:{}".format(sess.run(class_id))


    说明:

    1、与ckpt预测不同的是,pb文件已经固化了网络模型结构,因此,即使不知道原训练模型(train)的源码,我们也可以恢复网络图,并进行预测。恢复模型十分简单,只需要从读取的序列化数据中导入网络结构即可:

    tf.import_graph_def(output_graph_def, name="")
    2、但必须知道原网络模型的输入和输出的节点名称(当然了,传递数据时,是通过输入输出的张量来完成的)。由于InceptionV3模型的输入有三个节点,因此这里需要定义输入的张量名称,它对应网络结构的输入张量:

    input_image_tensor = sess.graph.get_tensor_by_name("input:0")
    input_keep_prob_tensor = sess.graph.get_tensor_by_name("keep_prob:0")
    input_is_training_tensor = sess.graph.get_tensor_by_name("is_training:0")
    以及输出的张量名称:

    output_tensor_name = sess.graph.get_tensor_by_name("InceptionV3/Logits/SpatialSqueeze:0")
    3、预测时,需要feed输入数据:

    # 测试读出来的模型是否正确,注意这里传入的是输出和输入节点的tensor的名字,不是操作节点的名字
    # out=sess.run("InceptionV3/Logits/SpatialSqueeze:0", feed_dict={'input:0': im,'keep_prob:0':1.0,'is_training:0':False})
    out=sess.run(output_tensor_name, feed_dict={input_image_tensor: im,
                                                input_keep_prob_tensor:1.0,
                                                input_is_training_tensor:False})
     4、其他网络模型预测时,也可以通过修改输入和输出的张量的名称 。

           PS:注意张量的名称,即为:节点名称+“:”+“id号”,如"InceptionV3/Logits/SpatialSqueeze:0"

    完整的CKPT 转换成 PB格式和预测的代码如下:

    # -*-coding: utf-8 -*-
    """
        @Project: tensorflow_models_nets
        @File   : convert_pb.py
        @Author : panjq
        @E-mail : pan_jinquan@163.com
        @Date   : 2018-08-29 17:46:50
        @info   :
        -通过传入 CKPT 模型的路径得到模型的图和变量数据
        -通过 import_meta_graph 导入模型中的图
        -通过 saver.restore 从模型中恢复图中各个变量的数据
        -通过 graph_util.convert_variables_to_constants 将模型持久化
    """
     
    import tensorflow as tf
    from create_tf_record import *
    from tensorflow.python.framework import graph_util
     
    resize_height = 299  # 指定图片高度
    resize_width = 299  # 指定图片宽度
    depths = 3
     
    def freeze_graph_test(pb_path, image_path):
        '''
        :param pb_path:pb文件的路径
        :param image_path:测试图片的路径
        :return:
        '''
        with tf.Graph().as_default():
            output_graph_def = tf.GraphDef()
            with open(pb_path, "rb") as f:
                output_graph_def.ParseFromString(f.read())
                tf.import_graph_def(output_graph_def, name="")
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
     
                # 定义输入的张量名称,对应网络结构的输入张量
                # input:0作为输入图像,keep_prob:0作为dropout的参数,测试时值为1,is_training:0训练参数
                input_image_tensor = sess.graph.get_tensor_by_name("input:0")
                input_keep_prob_tensor = sess.graph.get_tensor_by_name("keep_prob:0")
                input_is_training_tensor = sess.graph.get_tensor_by_name("is_training:0")
     
                # 定义输出的张量名称
                output_tensor_name = sess.graph.get_tensor_by_name("InceptionV3/Logits/SpatialSqueeze:0")
     
                # 读取测试图片
                im=read_image(image_path,resize_height,resize_width,normalization=True)
                im=im[np.newaxis,:]
                # 测试读出来的模型是否正确,注意这里传入的是输出和输入节点的tensor的名字,不是操作节点的名字
                # out=sess.run("InceptionV3/Logits/SpatialSqueeze:0", feed_dict={'input:0': im,'keep_prob:0':1.0,'is_training:0':False})
                out=sess.run(output_tensor_name, feed_dict={input_image_tensor: im,
                                                            input_keep_prob_tensor:1.0,
                                                            input_is_training_tensor:False})
                print("out:{}".format(out))
                score = tf.nn.softmax(out, name='pre')
                class_id = tf.argmax(score, 1)
                print "pre class_id:{}".format(sess.run(class_id))
     
     
    def freeze_graph(input_checkpoint,output_graph):
        '''
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
     
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=True)
     
        with tf.Session() as sess:
            saver.restore(sess, input_checkpoint) #恢复图并得到数据
            output_graph_def = graph_util.convert_variables_to_constants(  # 模型持久化,将变量值固定
                sess=sess,
                input_graph_def=sess.graph_def,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
     
            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 sess.graph.get_operations():
            #     print(op.name, op.values())
     
    def freeze_graph2(input_checkpoint,output_graph):
        '''
        :param input_checkpoint:
        :param output_graph: PB模型保存路径
        :return:
        '''
        # checkpoint = tf.train.get_checkpoint_state(model_folder) #检查目录下ckpt文件状态是否可用
        # input_checkpoint = checkpoint.model_checkpoint_path #得ckpt文件路径
     
        # 指定输出的节点名称,该节点名称必须是原模型中存在的节点
        output_node_names = "InceptionV3/Logits/SpatialSqueeze"
        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,# 等于:sess.graph_def
                output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
     
            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())
     
     
    if __name__ == '__main__':
        # 输入ckpt模型路径
        input_checkpoint='models/model.ckpt-10000'
        # 输出pb模型的路径
        out_pb_path="models/pb/frozen_model.pb"
        # 调用freeze_graph将ckpt转为pb
        freeze_graph(input_checkpoint,out_pb_path)
     
        # 测试pb模型
        image_path = 'test_image/animal.jpg'
        freeze_graph_test(pb_path=out_pb_path, image_path=image_path)


    三、源码下载和资料推荐
        1、训练方法
         上面的CKPT 转换成 PB格式例子,是我训练GoogleNet InceptionV3模型保存的ckpt转pb文件的例子,训练过程可参考博客:

    《使用自己的数据集训练GoogLenet InceptionNet V1 V2 V3模型(TensorFlow)》:https://blog.csdn.net/guyuealian/article/details/81560537

        2、Github地址
    Github源码:https://github.com/PanJinquan/tensorflow_models_nets 中的convert_pb.py文件

    预训练模型下载地址:https://download.csdn.net/download/guyuealian/10610847

        3、将模型移植Android的方法
         pb文件是可以移植到Android平台运行的,其方法,可参考:

    《将tensorflow训练好的模型移植到Android (MNIST手写数字识别)》

    参考:

    [1]https://blog.csdn.net/guyuealian/article/details/79672257

    【2】https://blog.csdn.net/yjl9122/article/details/78341689

    展开全文
  • 使用这个python程序可以直接将ckpt文件成固化的模型文件,用于预测结果,注意修改路径
  • 1、ckpt转pb import tensorflow as tf def freeze_graph(input_checkpoint, output_graph): # 指定输出的节点名称,该节点名称必须是原模型中存在的节点(重要!!!!!!!!!,如何找到该节点名称,见下文) ...

    1、ckpt转pb

    import tensorflow as tf
    
    def freeze_graph(input_checkpoint, output_graph):
    	# 指定输出的节点名称,该节点名称必须是原模型中存在的节点(重要!!!!!!!!!,如何找到该节点名称,见下文)
        output_node_names = ['attn_cell_1/transpose_1']  
        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 = tf.graph_util.convert_variables_to_constants(  # 模型持久化,将变量值固定
                sess=sess,
                input_graph_def=input_graph_def,  # 等于:sess.graph_def
                output_node_names=output_node_names)  # 如果有多个输出节点,以逗号隔开
            tensor_name_list = [tensor.name for tensor in input_graph_def.node]
            # print(tensor_name_list[:10])
            # sys.exit()
    
            with tf.gfile.FastGFile(output_graph, "wb") as f:  # 保存模型
                f.write(output_graph_def.SerializeToString())  # 序列化输出
            print("%d ops in the final graph." % len(output_graph_def.node))  # 得到当前图有几个操作节点
            for node in output_graph_def.node:
                print(node.name)
    
    if __name__ == '__main__':
        # 输入ckpt模型路径
        input_checkpoint='results/full/model_final.weights/a'
        # 输出pb模型的路径
        out_pb_path="frozen_model.pb"
        # 调用freeze_graph将ckpt转为pb
        freeze_graph(input_checkpoint,out_pb_path)
    

    2、pb模型预测

    def freeze_graph_test(pb_path, image_list):
        '''
        :param pb_path:pb文件的路径
        :param image_list:测试图片的路径
        '''
        with tf.Graph().as_default():
            output_graph_def = tf.GraphDef()
            with open(pb_path, "rb") as f:
                output_graph_def.ParseFromString(f.read())
                tf.import_graph_def(output_graph_def, name="")
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
    
                # tensor_name_list = [tensor.name for tensor in output_graph_def.node]
                # print(tensor_name_list[:10])
     
                # 定义输入的张量名称,对应网络结构的输入张量
                # input:0作为输入图像,keep_prob:0作为dropout的参数,测试时值为1,is_training:0训练参数
                input_image_tensor = sess.graph.get_tensor_by_name("img:0")
                droupout_tensor = sess.graph.get_tensor_by_name("dropout:0")
            
                # 定义输出的张量名称
                output_tensor_name = sess.graph.get_tensor_by_name("attn_cell_1/transpose_1:0")
    
                tensor_list = [output_tensor_name,input_image_tensor,droupout_tensor]
    
                hypo_final = formulaRec(image_list, sess, tensor_list)
    
                print(hypo_final)
    
                str_out = convert_str(hypo_final[0])
                print(str_out)
    
    展开全文
  • 把tensorflow保存的checkpoint类型模型冻结,转化为.pb模型输出。调用方法参见我的博文https://blog.csdn.net/weixin_41864878/article/details/84957681
  • tensorflow模型压缩——ckpt转pb

    千次阅读 2019-09-04 09:09:34
    ckpt模型转pb是项目落地的关键,如果你仅仅是想在服务器部署,也可忽略此步。人生的艰难有很多坑,不从坑里爬出来体会不到生命中的乐趣所在。简单的说,原来ckpt模型有4个文件(分别为checkpoint,index,data,meta)...
  • Tensorflow① 模型转换 ckpt转pb h5转pb

    万次阅读 热门讨论 2018-11-16 11:39:55
    1. Tensorflow ckpt模型转换pb模型 我们在Tensorflow中训练出来的模型一般是ckpt格式的,一个ckpt文件对应有xxx.ckpt.data,xxx.ckpt.meta和xxx.ckpt.index三个内容。 而在生产环境中,一般C++只能加载pb的模型,....
  • ckpt pb 模型

    2021-05-17 14:05:40
    tf1.12 ...now the code to make the pb is: import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf save_dir = 'checkpoints/' save_path = os.path.join(save_dir, 'best_val
  • 把tensorflow保存的checkpoint类型模型冻结,转化为.pb模型输出。调用方法参见我的博文https://blog.csdn.net/weixin_41864878/article/details/84957681
  • 报错1:Init node is_training/Assign doesn't exist in graph 报错2:restoring from checkpoint failed. this is most likely due to a variable name or other graph key that~ 报错3:OP_REQUIRES failed at ...
  • TensorFlow由ckpt转Pb文件的方法

    千次阅读 2019-07-20 20:45:25
    在有源代码和ckpt的情况下,想进一步获得用于部署到工业的pb文件。 先使用placeholder留一个输入接口,然后搭建模型,得到输出接口的node名称。 import tensorflow as tf from tensorflow.python.framework....
  • 问题1:在冻结一个ckpt格式的模型为pb格式时,需要加载图数据,使用 tf.train.import_meta_graph 遇到的报错如下: op_def = op_dict[node.op] KeyError: 'IteratorGetDevice' 冻结的代码是没有问题,另一个...
  • tensorflow中ckpt转pb模型

    2019-06-04 17:57:18
    model_path = "./model/4_class.ckpt-1" #设置model的路径,因新版tensorflow会生成三个文件,只需写到数字前 cfg=set_config() from tensorflow.python.saved_model import signature_constants, signature_...
  • Tensorflow ckpt模型转pb格式 1.ckpt转pb def ckpt2pb(): ''' :param input_checkpoint: :param output_graph: PB模型保存路径 :return: ''' BASE_DIR = os.path.dirname(os.path.abspath(__file__)) MODEL_PATH = ...
  • recongnize/pb/' os.makedirs(os.path.dirname(out_dirpath),exist_ok=True) out_pb_path = out_dirpath+"frozen_model.pb" # 调用freeze_graph将ckpt转为pb freeze_graph(input_checkpoint, out_pb_path) print(...
  • [openvino] tensorflow模型的格式转换:ckpt转pb 相关内容 tensorflow模型的格式转换:ckpt转pb tensorflow模型的格式转换:ckpt转pb 参考资料 cpkt转pb 简书-cpkt转pb ckpt转pb之不知输出节点 重新训练模型,...
  • 1,这段代码可以加在ckpt2pb里面 2,也可以加在使用pb模型时候 tf.import_graph_def 之前。   附:ckpt2pb.py 参考 # -*- coding: utf-8 -*- """ Created on Mon Aug 27 15:26:44 2018 @...
  • 模型转换:ckptpb转mnn 相关的参考链接: https://netron.app/ https://blog.csdn.net/qqqzmy/article/details/86060131 https://blog.csdn.net/sxlsxl119/article/details/81937815 ...
  • 为了深度学习模型的移植,首先需要将训练好的模型.ckpt的三个模型保存成.pb模型,在网上找到了很多方法,但是困难重重,中间经历找不到输入输出node,找到之后输出的模型不能进行预测,后来终于找到了方法,这里记录...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,023
精华内容 1,209
关键字:

ckpt转pb