• 1 如何使用pb文件保存和恢复模型进行迁移学习(学习Tensorflow 实战google深度学习框架)


    学习过程是Tensorflow 实战google深度学习框架一书的第六章的迁移学习环节。

    具体见我提出的问题:https://www.tensorflowers.cn/t/5314

    参考https://blog.csdn.net/zhuiqiuk/article/details/53376283后,对代码进行了修改。

    问题的跟踪情况记录:

    1 首先是保存模型:

    import tensorflow as tf
    from tensorflow.python.framework import graph_util
    v1=tf.constant([10000.0],name='v1')
    #v1 = tf.placeholder(tf.float32,shape=[1],name='v1')
    v2 = tf.Variable(tf.constant(2.0, shape=[1]), name = "v2")
    result = v1 + v2
    
    init_op = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init_op,{v1:[100]})
        print (sess.run(result,{v1:[1000]}))
        writer = tf.summary.FileWriter('./graphs/model_graph', sess.graph)
        writer.close()    
        graph_def = tf.get_default_graph().as_graph_def()
        output_graph_def = graph_util.convert_variables_to_constants(sess, graph_def,['add'])
        with tf.gfile.GFile("Saved_model/combined_model.pb", "wb") as f:
            f.write(output_graph_def.SerializeToString())

    因为inception v3接受输入的tensor是Decode/Content:0,是一个const类型,就是tf.constant类型,而一开始,我并不明白问题的所在,就将tf.placeholder改为了tf.constant,而实际上,两个都可以。问题的本身不是出在这里,而是对书本有错误的理解。

    书上因为获取的是两个return elements,会自动从列表中取出元素。

    而我获得的是一个retrun elelment,则只能返回一个列表。

    2 使用并加载持久化模型,直接调用模型的训练参数进行计算。

    #这是我以前写的程序,是错误的
    """
    因为我以前写的只是获取一个值。
    而现在修正的v1则是一个tensor。我们可以修正tensor的值。
    所以,tensorflow 实战google深度学习框架中有重大bug。
    不懂的联系我手机 18627711314 杰
    """
    import tensorflow as tf
    import numpy as np
    from numpy.random import RandomState
    from tensorflow.python.platform import gfile
    with tf.Session() as sess:
        model_filename = "Saved_model/combined_model.pb"  
        #model_filename = "inception_dec_2015/tensorflow_inception_graph.pb"  
        
        with gfile.FastGFile(model_filename, 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())
        """将模型的相关信息写入文件,和利用tensorboard进行可视化
        f = open("xiaojie2.txt", "w")
        print ("xiaojie2
    ",file = f)
        print (graph_def,file=f)
        f.close()
        writer = tf.summary.FileWriter('./graphs/model_graph2', graph_def)
        writer.close()
        """
        """④输出所有可训练的变量名称,也就是神经网络的参数"""
        trainable_variables=tf.trainable_variables()
        variable_list_name = [c.name for c in tf.trainable_variables()]
        variable_list = sess.run(variable_list_name)
        for k,v in zip(variable_list_name,variable_list):
            print("variable name:",k)
            print("shape:",v.shape)
            #print(v) 
        """④输出所有可训练的变量名称,也就是神经网络的参数"""

    v1= tf.import_graph_def(graph_def, return_elements=["v1:0"]) print (v1) print (sess.run(v1)) v2= tf.import_graph_def(graph_def, return_elements=["v2:0"]) print (sess.run(v2)) result = tf.import_graph_def(graph_def, return_elements=["add:0"]) print (sess.run(result)) x=np.array([2000.0]) print (sess.run(result,feed_dict={v1: x}))

    这些都是参照书上使用inception模型时的做法,我参照着自己写了一个模型,但是有重大bug

    运行结果总是提示:

    因为总是无法用feed_dict传入我想计算的输入。我一开始因为是tf.placeholder的原因,就参照inception的改为tf.constant。但是还是不行。后来在网上看到别人加载pb文件的一段代码https://blog.csdn.net/zhuiqiuk/article/details/53376283,重新对代码进行了修正。如下:

    import tensorflow as tf
    import numpy as np
    from numpy.random import RandomState
    from tensorflow.python.platform import gfile
    with tf.Graph().as_default():
        output_graph_def = tf.GraphDef()
        output_graph_path='Saved_model/combined_model.pb'
        with open(output_graph_path, "rb") as f:
            output_graph_def.ParseFromString(f.read())
            _ = tf.import_graph_def(output_graph_def, name="")
        with tf.Session() as sess:
    """④输出所有可训练的变量名称,也就是神经网络的参数"""
            trainable_variables=tf.trainable_variables()
            variable_list_name = [c.name for c in tf.trainable_variables()]
            variable_list = sess.run(variable_list_name)
            for k,v in zip(variable_list_name,variable_list):
                print("variable name:",k)
                print("shape:",v.shape)
                #print(v) 
    """④输出所有可训练的变量名称,也就是神经网络的参数"""
            input_x = sess.graph.get_tensor_by_name("v1:0")
            result = tf.import_graph_def(graph_def, return_elements=["add:0"])
            print (input_x)
            x=np.array([2000.0])
            print (sess.run(result,feed_dict={input_x: x}))

    问题的根本在于:

    V1= tf.import_graph_def(graph_def, return_elements=["v1:0"])获取的是

    [<tf.Tensor 'import/v1:0' shape=(1,) dtype=float32>],是一个列表

    而:input_x = sess.graph.get_tensor_by_name("v1:0")

    获取的是一个Tensor,即Tensor("v1:0", shape=(1,), dtype=float32)。

    使用sess.run的时候,feed_dict要修正的是tensor,而不是一个list。因此,总会提出unhashable type:listd的报错。

    3 将原始错误程序的代码改为:

    v1= tf.import_graph_def(graph_def, return_elements=["v1:0"])
    print (v1)
    print (sess.run(v1))
    v2= tf.import_graph_def(graph_def, return_elements=["v2:0"])
    print (sess.run(v2))
    result = tf.import_graph_def(graph_def, return_elements=["add:0"])
    print (sess.run(result))
    x=np.array([2000.0])

    #print (sess.run(result,feed_dict={v1: x}))
    print (sess.run(result,feed_dict={v1[0]: x}))

    也可以正确运行

    4 后来正确的程序还可以改为:

    import tensorflow as tf
    import numpy as np
    from numpy.random import RandomState
    from tensorflow.python.platform import gfile
    output_graph_def = tf.GraphDef()
    output_graph_path='Saved_model/combined_model.pb'
    with open(output_graph_path, "rb") as f:
        output_graph_def.ParseFromString(f.read())
        _ = tf.import_graph_def(output_graph_def, name="")
    with tf.Session() as sess:
    """④输出所有可训练的变量名称,也就是神经网络的参数"""
        trainable_variables=tf.trainable_variables()
        variable_list_name = [c.name for c in tf.trainable_variables()]
        variable_list = sess.run(variable_list_name)
        for k,v in zip(variable_list_name,variable_list):
            print("variable name:",k)
            print("shape:",v.shape)
            #print(v) 
      """④输出所有可训练的变量名称,也就是神经网络的参数"""
        input_x = sess.graph.get_tensor_by_name("v1:0")
        result = tf.import_graph_def(graph_def, return_elements=["add:0"])
        print (input_x)
        x=np.array([2000.0])
        print (sess.run(result,feed_dict={input_x: x}))

    需要注意的是:

    首先,无论如何,加载pb以后,输出所有可训练的变量,都不可能输出持久化模型中的变量。这一点以前就说过。以前说过,只能使用train.saver的方式。

    其次,如果使用后一种方式,即sess.graph.get_tensor_by_name,则必须要有红黄标注的那一幕。即:_ = tf.import_graph_def(output_graph_def, name="")

    程序附件

    链接:https://pan.baidu.com/s/11YtyDEyV84jONPi9tO2TCw 密码:8mfj

  • 相关阅读:
    基数排序
    计数排序和桶排序
    部署Java Web项目到云服务器的步骤全解析
    IP地址0.0.0.0/0是什么意思
    Tomcat在阿里云Centos7上正常启动,但浏览器无法访问的解决方法
    eclipse光标怎么返回上一次浏览的位置
    IDEA设置方法自动显示参数提示
    socket通信模型、socket中的accept()阻塞与read()阻塞
    Ubuntu18.04 下修改 root密码
    Ubuntu18.04 安装 VMwareTools
  • 原文地址:https://www.cnblogs.com/xiaojieshisilang/p/9217366.html
Copyright © 2020-2023  润新知