學習過程是Tensorflow 實戰google深度學習框架一書的第六章的遷移學習環節。python
具體見我提出的問題:https://www.tensorflowers.cn/t/5314網絡
參考https://blog.csdn.net/zhuiqiuk/article/details/53376283後,對代碼進行了修改。框架
問題的跟蹤狀況記錄:dom
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,會自動從列表中取出元素。ui
而我得到的是一個retrun elelment,則只能返回一個列表。google
#這是我之前寫的程序,是錯誤的 """ 由於我之前寫的只是獲取一個值。 而如今修正的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\n",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模型時的作法,我參照着本身寫了一個模型,可是有重大bugspa
運行結果老是提示:.net
由於老是沒法用feed_dict傳入我想計算的輸入。我一開始由於是tf.placeholder的緣由,就參照inception的改成tf.constant。可是仍是不行。後來在網上看到別人加載pb文件的一段代碼https://blog.csdn.net/zhuiqiuk/article/details/53376283,從新對代碼進行了修正。以下:code
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的報錯。
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}))
也能夠正確運行
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