精华内容
下载资源
问答
  • tensorflow保存数据为.pb格式和加载pb文件

    万次阅读 多人点赞 2018-05-16 21:49:54
    谷歌推荐的保存模型的方式是保存模型为 PB 文件,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型。它的主要使用场景...

    最近接触了tensorflow的object detection API发现里面读取的预先训练模型都是pb格式。

    谷歌推荐的保存模型的方式是保存模型为 PB 文件,它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型。

    它的主要使用场景是实现创建模型与使用模型的解耦, 使得前向推导 inference的代码统一。

    另外的好处是保存为 PB 文件时候,模型的变量都会变成固定的,导致模型的大小会大大减小,适合在手机端运行。

    还有一个就是,真正离线测试使用的时候,pb格式的数据能够保证数据不会更新变动,就是不会进行反馈调节啦。

    保存 PB 文件的代码:

    import tensorflow as tf
    import os
    from tensorflow.python.framework import graph_util
    
    pb_file_path = os.getcwd()
    
    with tf.Session(graph=tf.Graph()) as sess:
        x = tf.placeholder(tf.int32, name='x')
        y = tf.placeholder(tf.int32, name='y')
        b = tf.Variable(1, name='b')
        xy = tf.multiply(x, y)
        # 这里的输出需要加上name属性
        op = tf.add(xy, b, name='op_to_store')
    
        sess.run(tf.global_variables_initializer())
    
        # convert_variables_to_constants 需要指定output_node_names,list(),可以多个
        constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['op_to_store'])
    
        # 测试 OP
        feed_dict = {x: 10, y: 3}
        print(sess.run(op, feed_dict))
    
        # 写入序列化的 PB 文件
        with tf.gfile.FastGFile(pb_file_path+'model.pb', mode='wb') as f:
            f.write(constant_graph.SerializeToString())
    
        # 输出
        # INFO:tensorflow:Froze 1 variables.
        # Converted 1 variables to const ops.
        # 31
    

    加载 PB 模型文件典型代码:

    from tensorflow.python.platform import gfile
    
    sess = tf.Session()
    with gfile.FastGFile(pb_file_path+'model.pb', 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        sess.graph.as_default()
        tf.import_graph_def(graph_def, name='') # 导入计算图
    
    # 需要有一个初始化的过程    
    sess.run(tf.global_variables_initializer())
    
    # 需要先复原变量
    print(sess.run('b:0'))
    # 1
    
    # 输入
    input_x = sess.graph.get_tensor_by_name('x:0')
    input_y = sess.graph.get_tensor_by_name('y:0')
    
    op = sess.graph.get_tensor_by_name('op_to_store:0')
    
    ret = sess.run(op,  feed_dict={input_x: 5, input_y: 5})
    print(ret)
    # 输出 26
    


    保存为 save model 格式也可以生成模型的 PB 文件,并且更加简单。

    保存好以后到saved_model_dir目录下,会有一个saved_model.pb文件以及variables文件夹。顾名思义,variables保存所有变量,saved_model.pb用于保存模型结构等信息。

    import tensorflow as tf
    import os
    from tensorflow.python.framework import graph_util
    
    pb_file_path = os.getcwd()
    
    with tf.Session(graph=tf.Graph()) as sess:
        x = tf.placeholder(tf.int32, name='x')
        y = tf.placeholder(tf.int32, name='y')
        b = tf.Variable(1, name='b')
        xy = tf.multiply(x, y)
        # 这里的输出需要加上name属性
        op = tf.add(xy, b, name='op_to_store')
    
        sess.run(tf.global_variables_initializer())
    
        # convert_variables_to_constants 需要指定output_node_names,list(),可以多个
        constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['op_to_store'])
    
        # 测试 OP
        feed_dict = {x: 10, y: 3}
        print(sess.run(op, feed_dict))
    
        # 写入序列化的 PB 文件
        with tf.gfile.FastGFile(pb_file_path+'model.pb', mode='wb') as f:
            f.write(constant_graph.SerializeToString())
    
        # INFO:tensorflow:Froze 1 variables.
        # Converted 1 variables to const ops.
        # 31
        
        
        # 官网有误,写成了 saved_model_builder  
        builder = tf.saved_model.builder.SavedModelBuilder(pb_file_path+'savemodel')
        # 构造模型保存的内容,指定要保存的 session,特定的 tag, 
        # 输入输出信息字典,额外的信息
        builder.add_meta_graph_and_variables(sess,
                                           ['cpu_server_1'])
    
    
    # 添加第二个 MetaGraphDef 
    #with tf.Session(graph=tf.Graph()) as sess:
    #  ...
    #  builder.add_meta_graph([tag_constants.SERVING])
    #...
    
    builder.save()  # 保存 PB 模型
    

    这种方法对应的导入模型的方法:

    with tf.Session(graph=tf.Graph()) as sess:
        tf.saved_model.loader.load(sess, ['cpu_1'], pb_file_path+'savemodel')
        sess.run(tf.global_variables_initializer())
    
        input_x = sess.graph.get_tensor_by_name('x:0')
        input_y = sess.graph.get_tensor_by_name('y:0')
    
        op = sess.graph.get_tensor_by_name('op_to_store:0')
    
        ret = sess.run(op,  feed_dict={input_x: 5, input_y: 5})
        print(ret)
    # 只需要指定要恢复模型的 session,模型的 tag,模型的保存路径即可,使用起来更加简单
    

    这样和之前的导入 PB 模型一样,也是要知道tensor的name。那么如何可以在不知道tensor name的情况下使用呢,实现彻底的解耦呢? 给add_meta_graph_and_variables方法传入第三个参数,signature_def_map即可。


    参考:

    https://zhuanlan.zhihu.com/p/32887066



    展开全文
  • PB读取文件所有文件

    2018-10-15 14:37:38
    PB读取文件所有文件,输入文件夹,读取制定文件夹所有文件
  • npy文件转为pb文件

    2019-06-27 10:17:06
    npy文件转为pb文件 下载后 直接打开代码就可以运行 里面包含要转换的npy文件和已经转换好的pb文件 转换完后测试pb文件正确可用
  • 使用Libxl可以无需安装office,即可建立、读写Excel格式文件,在编程中有较大的灵活性。 本示例程序包含三个读写Excel的例程,开发工具为PB9,参考libxl官网上的C++示例改写,旨在抛砖引玉,更多的例程可参考本程序...
  • 今天小编就为大家分享一篇将tensorflow模型打包成PB文件PB文件读取方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • PB XML文件操作工具

    2011-09-13 00:37:09
    PB XML文件操作工具 PB XML文件操作工具 PB XML文件操作工具
  • PB6.5文件转移程序

    2010-02-20 11:28:46
    PB6.5文件转移程序PB6.5文件转移程序PB6.5文件转移程序
  • PB读写文件

    千次阅读 2019-04-08 10:58:15
    文章目录读写文本读写二进制文件源代码 读写文本 1.读取文本 function readtext :读文本内容 function readlines :读文本各行 2.写入文本 function writetext :覆盖写入文本 function appendtext :追加写入文本...

    读写文本

    1.读取文本
    function readtext :读文本内容
    function readlines :读文本各行
    在这里插入图片描述
    2.写入文本
    function writetext :覆盖写入文本
    function appendtext :追加写入文本
    在这里插入图片描述
    执行到writetext的文件:
    在这里插入图片描述
    执行到appendtext的文件:在这里插入图片描述

    读写二进制文件

    function readfile 读取文件
    function writefile 覆盖写入文件
    function appendfile 追加写入文件
    在这里插入图片描述
    在这里插入图片描述
    写入的新文件SQLMonitor_write.rar与原文件完全一致,可以正常打开
    在这里插入图片描述
    在这里插入图片描述

    源代码

    代码拷贝到文本编辑器,另存为 n_func_file.sru,导入pbl
    发现BUG请留言或私信,以便修正(QQ:768310524 TEL:18649713925)

    $PBExportHeader$n_func_file.sru
    forward
    global type n_func_file from nonvisualobject
    end type
    end forward
    
    global type n_func_file from nonvisualobject autoinstantiate
    end type
    
    forward prototypes
    public function integer readfile (string as_file, ref blob rblob_file)
    public function integer readtext (string as_file, ref string rs_text)
    public function integer readlines (string as_file, ref string rs_line[])
    public function integer writefile (string as_file, blob ablob_file)
    public function integer writetext (string as_file, string as_text)
    public function integer appendtext (string as_file, string as_text)
    public function integer appendfile (string as_file, blob ablob_file)
    end prototypes
    
    public function integer readfile (string as_file, ref blob rblob_file);long ll_len
    long ll_loop,i
    int li_filenum,li_read
    blob lblob_read,lblob_file
    
    ll_len = filelength(as_file)
    ll_loop = ll_len / 32765
    if mod(ll_len,32765) <> 0 then ll_loop += 1
    
    li_filenum = fileopen(as_file,streammode!,read!,lockread!)
    if li_filenum < 0 then return li_filenum
    
    for i = 1 to ll_loop
    	li_read = fileread(li_filenum,lblob_read)
    	if li_read < 0 then return li_read
    	lblob_file += lblob_read
    next
    fileclose(li_filenum)
    
    rblob_file = lblob_file
    return 0
    end function
    
    public function integer readtext (string as_file, ref string rs_text);long ll_len
    long ll_loop,i
    int li_filenum,li_read
    string ls_read,ls_file
    
    ll_len = filelength(as_file)
    ll_loop = ll_len / 32765
    if mod(ll_len,32765) <> 0 then ll_loop += 1
    
    li_filenum = fileopen(as_file,streammode!,read!,lockread!)
    if li_filenum < 0 then return li_filenum
    
    for i = 1 to ll_loop
    	li_read = fileread(li_filenum,ls_read)
    	if li_read < 0 then return li_read
    	ls_file += ls_read
    next
    fileclose(li_filenum)
    
    rs_text = ls_file
    return 0
    end function
    
    public function integer readlines (string as_file, ref string rs_line[]);int li_filenum,li_read
    string ls_read,ls_line[]
    long i
    
    li_filenum = fileopen(as_file,LineMode!,Read!,LockRead!)
    if li_filenum < 0 then return li_filenum
    
    do while fileread(li_filenum,ls_read) >= 0
    	i += 1
    	ls_line[i] = ls_read
    loop
    
    fileclose(li_filenum)
    
    rs_line = ls_line
    return 0
    end function
    
    public function integer writefile (string as_file, blob ablob_file);long ll_len
    long ll_loop,i
    int li_filenum,li_write
    blob lblob_write
    
    ll_len = len(ablob_file)
    ll_loop = ll_len / 32765
    if mod(ll_len,32765) <> 0 then ll_loop += 1
    
    li_filenum = fileopen(as_file,StreamMode!,Write!,LockWrite!,Replace!)
    if li_filenum < 0 then return li_filenum
    
    for i = 1 to ll_loop
    	lblob_write = blobmid(ablob_file,(i - 1)*32765 + 1,32765)
    	li_write = filewrite(li_filenum,lblob_write)
    	if li_write < 0 then return li_write
    next
    
    fileclose(li_filenum)
    return 0
    end function
    
    public function integer writetext (string as_file, string as_text);long ll_len
    long ll_loop,i
    int li_filenum,li_write
    string ls_write
    
    ll_len = len(as_text)
    ll_loop = ll_len / 16382
    if mod(ll_len,16382) <> 0 then ll_loop += 1
    
    li_filenum = fileopen(as_file,StreamMode!,Write!,LockWrite!,Replace!)
    if li_filenum < 0 then return li_filenum
    
    for i = 1 to ll_loop
    	ls_write = mid(as_text,(i - 1)*16382 + 1,16382)
    	li_write = filewrite(li_filenum,ls_write)
    	if li_write < 0 then return li_write
    next
    
    fileclose(li_filenum)
    return 0
    end function
    
    public function integer appendtext (string as_file, string as_text);long ll_len
    long ll_loop,i
    int li_filenum,li_write
    string ls_write
    
    ll_len = len(as_text)
    ll_loop = ll_len / 16382
    if mod(ll_len,16382) <> 0 then ll_loop += 1
    
    li_filenum = fileopen(as_file,StreamMode!,Write!,LockWrite!,Append!)
    if li_filenum < 0 then return li_filenum
    
    for i = 1 to ll_loop
    	ls_write = mid(as_text,(i - 1)*16382 + 1,16382)
    	li_write = filewrite(li_filenum,ls_write)
    	if li_write < 0 then return li_write
    next
    
    fileclose(li_filenum)
    return 0
    end function
    
    public function integer appendfile (string as_file, blob ablob_file);long ll_len
    long ll_loop,i
    int li_filenum,li_write
    blob lblob_write
    
    ll_len = len(ablob_file)
    ll_loop = ll_len / 32765
    if mod(ll_len,32765) <> 0 then ll_loop += 1
    
    li_filenum = fileopen(as_file,StreamMode!,Write!,LockWrite!,Append!)
    if li_filenum < 0 then return li_filenum
    
    for i = 1 to ll_loop
    	lblob_write = blobmid(ablob_file,(i - 1)*32765 + 1,32765)
    	li_write = filewrite(li_filenum,lblob_write)
    	if li_write < 0 then return li_write
    next
    
    fileclose(li_filenum)
    return 0
    end function
    
    on n_func_file.create
    call super::create
    TriggerEvent( this, "constructor" )
    end on
    
    on n_func_file.destroy
    TriggerEvent( this, "destructor" )
    call super::destroy
    end on
    
    
    
    展开全文
  • 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

     

    展开全文
  • 再进入正题前,我们先介绍一下checkpoint(ckpt)和pb的区别和联系 model 保存方法 结果文件 加载 ckpt tf.train.Saver() 主要的4个文件 checkpoint model.ckpt.data-xxx model....

    再进入正题前,我们先介绍一下checkpoint(ckpt)和pb的区别和联系

    model保存方法结果文件加载
    ckpttf.train.Saver()

    主要的4个文件

    checkpoint                  

    model.ckpt.data-xxx  

    model.ckpt.index     

    model.ckpt.meta        

    tf.train.Saver() saver.restore() 

    pb
    SerializeToString()函数序列化
    
    pb文件见下文

    pb模型文件具有语言独立性,可独立运行,封闭的序列化格式,支持其他语言解析,而且模型的变量都是固定的,模型的大小减小,一个模型文件也便于之后的使用。

    tf生成pb文件

    import tensorflow as tf
    from tensorflow.python.framework import graph_util
    
    with tf.Session(graph=tf.Graph()) as sess:
        # 定义输入变量名
        x = tf.placeholder(tf.int32, name='x')
        y = tf.placeholder(tf.int32, name='y')
        b = tf.Variable(1, name='b')
        xy = tf.multiply(x, y)
        # 输出,需要加上变量名
        output = tf.add(xy, b, name='output')
    
        sess.run(tf.global_variables_initializer())
    
        # convert_variables_to_constants 需要指定output_node_names
        constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['output'])
    
        print(sess.run(output, feed_dict={x: 2, y: 5}))
    
        # 写入序列化的pb文件
        with tf.gfile.FastGFile('model.pb', mode='wb') as f:
            f.write(constant_graph.SerializeToString())

    tf加载pb文件

    from tensorflow.python.platform import gfile
    
    sess = tf.Session()
    with gfile.FastGFile('model.pb', 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        sess.graph.as_default()
        tf.import_graph_def(graph_def, name='')  # 导入计算图
    
    # 需要有一个初始化的过程
    sess.run(tf.global_variables_initializer())
    
    # 输入
    input_x = sess.graph.get_tensor_by_name('x:0')
    input_y = sess.graph.get_tensor_by_name('y:0')
    
    op = sess.graph.get_tensor_by_name('output:0')
    
    res = sess.run(op, feed_dict={input_x: 5, input_y: 5})
    print(res)

    tips:应用到自己的程序中记得在输出添加变量名(如:output = tf.add(xy, b, name='output')),加载时获取输入输出变量名,将值传给输入变量,sess.run()即可

    展开全文
  • PB 11.5 文件复制例子源码(需要安装.net环境)
  • YOLOV2的pb模型文件

    2018-06-20 17:15:58
    利用darkflow将yolov2的权重文件转换为tensorflow的pb模型文件,包括yolo.pb以及yolo.meta两个文件
  • 使用这个python程序可以直接将ckpt文件转成固化的模型文件,用于预测结果,注意修改路径
  • 用户win7、win10系统中的pb的帮助文件打不开的处理,处理简单,直接安装即可,解决了win32hlp.exe不能覆盖的问题,不用修改文件权限。处理后可以在pb中直接按F1弹出帮助,也可在代码编辑过程中点击Shift+F1直接定位...
  • pb6.5安装文件

    2011-10-15 10:17:25
    pb6.5的打印格式安装文件,用于设置软件的打印格式
  • 一个可以批量从PBL文件导出为srd,srw文件的小工具。 操作: 选择PBL文件所在文件夹,选择导出目标路径,点击Export按钮,PBL文件夹中所有的PBL文件中的SRW和SRD可迅速导出。 注意:此版本有导出源码32K限制,修正版...
  • 由于要同时运行几个网络,所以打算将这个网络模型进行固化成pb文件,然后直接调用. 主要包括一下内容: 1.查看ckpt模型的输入输出张量名称. 2.将ckpt文件生成pb文件. 3.查看生成的pb文件的输入输出节点 4.运行pb...
  • tensor pb文件可视化

    2018-04-16 18:53:03
    可用于单独的pb模型文件的可视化,利用tensorboard --logdir='路径'
  • PB12.5破解文件

    2014-04-30 15:59:11
    pb12.5破解文件
  • PB文件读写函数

    2013-06-20 15:38:47
    用于PB文件读写的必备函数,借口已经做了封装。欢迎试用。
  • pb客户端oracle文件

    2018-12-24 11:20:41
    pb客户端oracle文件, oracle 11g pb9.0 - pb 12 数据库存连接 dll相关文件
  • 一个可以批量从PBL文件导出为srd,srw文件的小工具,支持pb10,11,12。(导出pb7源码请下载另一个版本https://download.csdn.net/download/alistguy/10842685) 使用:执行PBCLTRT115.msi进行PB11的库文件安装,中间...
  • 代码地址:https://github.com/wangflying/pb2json_convertor.git
  • PB ini文件成生成与使用
  • pb文件,输入input,修改output_node,可以输出神经网络每层的输出features
  • 今天小编就为大家分享一篇TensorFlow实现checkpoint文件转换为pb文件,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • TensorFlow2.0模型格式转换为.pb格式

    千次阅读 2020-04-24 18:14:59
    本文主要介绍如何将tensorflow2.0模型转化为.pb格式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 89,451
精华内容 35,780
关键字:

pb格式的文件