I'm trying to use tensorflow for study and i don't undestand how to open and use saved early in file my graph with type tf.Graph. Something like this:
import tensorflow as tf
my_graph = tf.Graph()
with g.as_default():
x = tf.Variable(0)
b = tf.constant(-5)
k = tf.constant(2)
y = k*x + b
tf.train.write_graph(my_graph, '.', 'graph.pbtxt')
f = open('graph.pbtxt', "r")
# Do something with "f" to get my saved graph and use it below in
# tf.Session(graph=...) instead of dots
with tf.Session(graph=...) as sess:
tf.initialize_all_variables().run()
y1 = sess.run(y, feed_dict={x: 5})
y2 = sess.run(y, feed_dict={x: 10})
print(y1, y2)
You have to load file contents, parse it to GraphDef and then import.
It will be imported into current graph. You may want to wrap it with graph.as_default(): context manager.
import tensorflow as tf
from tensorflow.core.framework import graph_pb2 as gpb
from google.protobuf import text_format as pbtf
gdef = gpb.GraphDef()
with open('my-graph.pbtxt', 'r') as fh:
graph_str = fh.read()
pbtf.Parse(graph_str, gdef)
tf.import_graph_def(gdef)
One option: take a look at the Tensorflow MetaGraph save/restore support, documented here: https://www.tensorflow.org/versions/r0.11/how_tos/meta_graph/index.html
I solved this problem this way: first, i name needed calculation in my graph "output" and then save this model in code below...
import tensorflow as tf
x = tf.placeholder(dtype=tf.float64, shape=[], name="input")
a = tf.Variable(111, name="var1", dtype=tf.float64)
b = tf.Variable(-666, name="var2", dtype=tf.float64)
y = tf.add(x, a, name="output")
saver = tf.train.Saver()
with tf.Session() as sess:
tf.initialize_all_variables().run()
print(sess.run(y, feed_dict={x: 555}))
save_path = saver.save(sess, "model.ckpt", meta_graph_suffix='meta', write_meta_graph=True)
print("Model saved in file: %s" % save_path)
Second, I need to run certain operation in graph, which i know by name "output". So I just restore model in another code and run my restored calculation by taking necessary graph parts with names "input" and "output" :
import tensorflow as tf
# Restore graph to another graph (and make it default graph) and variables
graph = tf.Graph()
with graph.as_default():
saver = tf.train.import_meta_graph("model.ckpt.meta")
y = graph.get_tensor_by_name("output:0")
x = graph.get_tensor_by_name("input:0")
with tf.Session() as sess:
saver.restore(sess, "model.ckpt")
print(sess.run(y, feed_dict={x: 888}))
# Variable out:
for var in tf.all_variables():
print("%s %.2f" % (var.name, var.eval()))
Related
I have trained a deep CNN that predicts a one-dimentional array and saved the weight variables in the format of .ckpt. But when I give the model new inputs, it always outputs the same array. I have already check the preprocess of the inputs and I'm sure they are alright. Here is the code of my prediction.
import pandas as pd
import numpy as np
import os
import tensorflow as tf
sess = tf.Session()
sess.run(tf.global_variables_initializer())
filename = os.listdir("D:/project/test datasets/image")
new_dir = "D:/project/test datasets/"
for img in filename:
img=os.path.splitext(img)[0]
xs = pd.read_csv(new_dir+img+'.csv',index_col=0)
xs = xs.values.flatten()
xs = np.expand_dims(xs,0)
saver = tf.train.import_meta_graph('model.ckpt.meta')
saver.restore(sess, 'model.ckpt')
graph = tf.get_default_graph()
x = graph.get_tensor_by_name("x:0")
keep_prob = graph.get_tensor_by_name("keep_prob:0")
y_conv = graph.get_tensor_by_name("y_conv:0")
print(sess.run(y_conv,feed_dict={x:xs,keep_prob:1.0}))
And I also find that when I add the code statement y_conv = tf.constant(0) in the end of the loop, the following output will all be 0, which means my prediction y_conv doesn't update in each loop.
I have no idea where is wrong. Any feedback or advice would be greatly appreciated.
Your code looks fine to me. Please can you try in the below format
with tf.Session() as sess:
saver = tf.train.import_meta_graph(savefile)
saver.restore(sess, tf.train.latest_checkpoint(savedir))
graph = tf.get_default_graph()
input_x = graph.get_tensor_by_name("input_x:0")
result = graph.get_tensor_by_name("result:0")
feed_dict = {input_x: x_data,}
predictions = result.eval(feed_dict=feed_dict)
I have a problem with making batch inference using a tensorflow protobuf graph exported from a keras h5 model. Eventhough the exported pb graph can accept multiple inputs (samples), it always gives a single output regardless of the number of inputs. Here is a simple example to demonstrate the problem.
from keras.models import Model,load_model
from keras.layers import Dense, Input
from keras import backend as K
import tensorflow as tf
import numpy as np
import os
import os.path as osp
pinput = Input(shape=[10,], name='my_input')
poutput = Dense(1, activation='sigmoid')(pinput)
model = Model(inputs=[pinput], outputs=[poutput])
model.compile(loss='mean_squared_error',optimizer='sgd',metrics=['accuracy'])
data = np.random.random((100, 10))
labels = np.random.randint(2, size=(100, 1))
model.fit(data, labels, epochs=1, batch_size=32)
x = np.random.random((3, 10))
y = model.predict(x)
print y
####################################
# Save keras h5 to tensorflow pb
####################################
K.set_learning_phase(0)
#alias output names
numoutputs = 1
pred = [None]*numoutputs
pred_node_names = [None]*numoutputs
for i in range(numoutputs):
pred_node_names[i] = 'output'+'_'+str(i)
pred[i] = tf.identity(model.output[i], name=pred_node_names[i])
print('Output nodes names are: ', pred_node_names)
sess = K.get_session()
# Write the graph in human readable
f = 'graph_def_for_reference.pb.ascii'
tf.train.write_graph(sess.graph.as_graph_def(), '.', f, as_text=True)
input_graph_def = sess.graph.as_graph_def()
#freeze graph
from tensorflow.python.framework.graph_util import convert_variables_to_constants
output_names = pred_node_names
output_names += [v.op.name for v in tf.global_variables()]
constant_graph = convert_variables_to_constants(sess, input_graph_def,output_names)
# Write the graph in binary .pb file
from tensorflow.python.framework import graph_io
graph_io.write_graph(constant_graph, '.', 'model.pb', as_text=False)
def load_graph(frozen_graph_filename):
# We load the protobuf file from the disk and parse it to retrieve the
# unserialized graph_def
with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
# Then, we import the graph_def into a new Graph and returns it
with tf.Graph().as_default() as graph:
# The name var will prefix every op/nodes in your graph
# Since we load everything in a new graph, this is not needed
tf.import_graph_def(graph_def, name="prefix")
return graph
###################################
# Test batch inference with tf
###################################
graph = load_graph("model.pb")
for op in graph.get_operations():
print(op.name)
minput = graph.get_tensor_by_name('prefix/my_input:0')
moutput = graph.get_tensor_by_name('prefix/output_0:0')
with tf.Session(graph=graph) as sess:
y = sess.run(moutput, feed_dict={minput: x})
print y
The output of the run is
Epoch 1/1
100/100 [==============================] - 0s 661us/step - loss: 0.2655 - acc: 0.3900
[[0.62018263]
[0.41664478]
[0.40322617]]
('Output nodes names are: ', ['output_0'])
prefix/my_input
prefix/dense_1/kernel
prefix/dense_1/kernel/read
prefix/dense_1/bias
prefix/dense_1/bias/read
prefix/dense_1/MatMul
prefix/dense_1/BiasAdd
prefix/dense_1/Sigmoid
prefix/SGD/iterations
prefix/SGD/lr
prefix/SGD/momentum
prefix/SGD/decay
prefix/training/SGD/Variable
prefix/training/SGD/Variable_1
prefix/strided_slice/stack
prefix/strided_slice/stack_1
prefix/strided_slice/stack_2
prefix/strided_slice
prefix/output_0
[0.62018263]
You can see the keras h5 graphs gives 3 ouputs wile the tensorflow pb graph just gives the first output. What am I doing wrong? I would like to
modify the h5 to pb conversion process so that I can do batch inference using the pb grapth with the python and c++ tensorflow backends.
It turns out this is due to a bug I inherited from k2tf_convert
pred[i] = tf.identity(model.output[i], name=pred_node_names[i])
should be
pred[i] = tf.identity(model.outputs[i], name=pred_node_names[i])
It seems the keras model class has both 'output' and 'outputs' members that makes this bug hard to track.
Thanks for your help.
This question has bothered me for 2 days. I searched many sites and did not solve.
Background:
I am learning mnist, and it goes right at first, but when I save the model and restore, there is an Error, told me placeholder_1 must be fed. I am confused.
Code:
Below code goes right.
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("mnist data/", one_hot=True)
import tensorflow as tf
# 操作符号变量来描述这些可交互的操作单元
x = tf.placeholder(tf.float32, [None, 784])
# 权重值和偏置量
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
# 实现模型
y = tf.nn.softmax(tf.matmul(x,W) + b)
# 添加一个新的占位符用于输入正确值
y_ = tf.placeholder("float", [None,10])
# 计算交叉熵:
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
# 要求TensorFlow用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# 添加一个操作来初始化我们创建的变量
init = tf.initialize_all_variables()
saver = tf.train.Saver()
sess = tf.Session()
sess.run(init)
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
save_path = saver.save(sess, "./model_mnist.ckpt",write_meta_graph=False)
print("Model saved in life:", save_path)
import cv2
import numpy as np
img = cv2.imread('lena.png')
img = cv2.resize(img, (28,28))
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
arr = []
for i in range(28):
for j in range(28):
gray = 1 - img[i,j]/255
arr.append(gray)
arr_mnist = np.array([arr])
#print(arr_mnist)
result = sess.run(y, feed_dict={x:arr_mnist})
print(result)
#print(np.argmax(result[0]))
#print(np.sum(result[0]))
print("预测值为:",np.argmax(result[0]),";概率为:",np.max(result[0])/np.sum(result[0]))
#print(tf.argmax(result,1))
But, when I want to use the model to restore. it goes wrong.
import cv2
import numpy as np
import tensorflow as tf
img = cv2.imread('lena.png')
img = cv2.resize(img, (28,28))
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
arr = []
for i in range(28):
for j in range(28):
gray = 1 - img[i,j]/255
arr.append(gray)
arr_mnist = np.array([arr])
#print(arr_mnist)
tf.reset_default_graph()
x = tf.placeholder("float", shape=[None, 784])
y = tf.placeholder("float", shape=[None, 10])
#keep_prob = tf.placeholder("float")
sess = tf.Session()
saver = tf.train.import_meta_graph('./model_mnist.ckpt.meta')
saver.restore(sess, './model_mnist.ckpt')
result = sess.run(y, feed_dict={x:arr_mnist})
print(result)
print("预测值为:",np.argmax(result[0]),";概率为:",np.max(result[0])/np.sum(result[0]))
the Error is :
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'Placeholder_1' with dtype float and shape [?,10]
[[Node: Placeholder_1 = Placeholder[dtype=DT_FLOAT, shape=[?,10], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
so, I suppose the problem should be in the model save or restore process, but I cannot figure out.
how can I correct the code? thank you!
When restoring the graph, you are declaring two placeholders, and only feed one when running the session. The y placeholder is the one matching the error name.
But you do not need to declare these placeholders in the run script. The restoration takes care of it. Note that you can specify the feed dictionary with string keys:
feed_dict: { 'x': [1,2,3] }
I'm trying to create this super simple example with Tensorflow and I clearly don't fully understand the API for Tensorflow.
I have the following code. It's not mine originally - I found it from some demo, but I can't remember where I found it, or else I would give the author credit. Apologies.
Saving the Trained Line Model
import tensorflow as tf
import numpy as np
# Create 100 phony x, y data points in NumPy, y = x * 0.1 + 0.3
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data * 0.1 + 0.3
# Try to find values for W and b that compute y_data = W * x_data + b
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0), name='W')
b = tf.Variable(tf.zeros([1]), name='b')
y = W * x_data + b
# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
# Before starting, initialize the variables. We will 'run' this first.
init = tf.global_variables_initializer()
# Create a session saver
saver = tf.train.Saver()
# Launch the graph.
sess = tf.Session()
sess.run(init)
# Fit the line.
for step in range(201):
sess.run(train)
if step % 20 == 0:
print(step, sess.run(W), sess.run(b))
saver.save(sess, 'linemodel')
Ok that's all fine. I just want to load in the model and then query my model to get a predicted value. Here is my attempted code:
Loading and Querying the Trained Line Model
# This is going to load the line model
import tensorflow as tf
sess = tf.Session()
new_saver = tf.train.import_meta_graph('linemodel.meta')
new_saver.restore(sess, tf.train.latest_checkpoint('./')) # latest checkpoint
all_vars = tf.global_variables()
for v in all_vars:
v_ = sess.run(v)
print("This is {} with value: {}".format(v.name, v_))
# this works
# None of the below works
# Tried this as well
#fetches = {
# "input": tf.constant(10, name='input')
#}
#feed_dict = {"input": tf.constant(10, name='input')}
#vals = sess.run(fetches, feed_dict = feed_dict)
# Tried this and it didn't work
# query_value = tf.constant(10, name='query')
# print(sess.run(query_value))
This is a really basic question, but how can I just pass in a value and use my line almost like a function. Do I need to change the way the line model is being constructed? My guess is that the computation graph is not set up where the output is an actual variable that we can get. Is this correct? If so, how should I modify this program?
You have to create tensorflow graph again and load saved weights into it. I added couple of lines to your code and it gives desired outputs. Please check it.
import tensorflow as tf
import numpy as np
sess = tf.Session()
new_saver = tf.train.import_meta_graph('linemodel.meta')
new_saver.restore(sess, tf.train.latest_checkpoint('./')) # latest checkpoint
all_vars = tf.global_variables()
# load saved weights into new variables
W = all_vars[0]
b = all_vars[1]
# build TF graph
x = tf.placeholder(tf.float32)
y = tf.add(tf.multiply(W,x),b)
# Session
init = tf.global_variables_initializer()
print(sess.run(all_vars))
sess.run(init)
for i in range(2):
x_ip = np.random.rand(10).astype(np.float32) # batch_size : 10
vals = sess.run(y,feed_dict={x:x_ip})
print vals
Output:
[array([ 0.1000001], dtype=float32), array([ 0.29999995], dtype=float32)]
[-0.21707924 -0.18646611 -0.00732027 -0.14248954 -0.54388255 -0.33952206 -0.34291503 -0.54771954 -0.60995424 -0.91694558]
[-0.45050886 -0.01207681 -0.38950539 -0.25888413 -0.0103816 -0.10003483 -0.04783082 -0.83299863 -0.53189355 -0.56571382]
I hope this helps.
i am new to neural networks.
i have gone through TensorFlow mninst ML Beginners
used tensorflow basic mnist tutorial
and trying to get prediction using external image
I have the updated the mnist example provided by tensorflow
On top of that i have added few things :
1. Saving trained models locally
2. loading the saved models.
3. preprocessing the image into 28 * 28.
i have attached the image for reference
1. while training the models, save it locally. So i can reuse it at any point of time.
2. once after training, loading the models.
3. creating an external image via gimp which contains any one values ranging from [0 - 9]
4. using opencv to convert the image into 28 * 28 image and reversing the bit as well.
5. Then trying to predict.
i am able to train the models and save it properly.
i am getting predictions which are not right.
Find my codes Below
TrainSimple.py
# Load MNIST Data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
from random import randint
from scipy import misc
# Start TensorFlow InteractiveSession
import tensorflow as tf
sess = tf.InteractiveSession()
# Placeholders
x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
# Variables
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
sess.run(tf.initialize_all_variables())
# Predicted Class and Cost Function
y = tf.nn.softmax(tf.matmul(x,W) + b)
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
saver = tf.train.Saver() # defaults to saving all variables
# GradientDescentOptimizer
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# Train the Model
for i in range(40000):
if (i + 1) == 40000 :
saver.save(sess, "/Users/xxxx/Desktop/TensorFlow/"+"/model.ckpt", global_step=i)
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0], y_: batch[1]})
# Evaluate the Model
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
loadImageAndPredict.py
from random import randint
from scipy import misc
import numpy as np
import cv2
def preProcess(invert_file):
print "preprocessing the images" + invert_file
image=cv2.imread(invert_file,0)
ret,image_thresh = cv2.threshold(image,127,255,cv2.THRESH_BINARY)
l,b=image.shape
fr=0
lr=0
fc=0
lc=0
i=0
while len(set(image_thresh[i,]))==1:
i+=1
fr=i
i=0
while len(set(image_thresh[-1+i,]))==1:
i-=1
lr=i+l
j=0
while len(set(image_thresh[0:,j]))==1:
j+=1
fc=j
j=0
while len(set(image_thresh[0:,-1+j]))==1:
j-=1
lc=j+b
image_crop=image_thresh[fr:lr,fc:lc]
image_padded= cv2.copyMakeBorder(image_crop,5,5,5,5,cv2.BORDER_CONSTANT,value=255)
image_resized = cv2.resize(image_padded, (28, 28))
image_resized = (255-image_resized)
cv2.imwrite(invert_file, image_resized)
import tensorflow as tf
sess = tf.InteractiveSession()
# Placeholders
x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
# # Variables
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
# Predicted Class and Cost Function
y = tf.nn.softmax(tf.matmul(x,W) + b)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
saver = tf.train.Saver() # defaults to saving all variables - in this case w and b
# Train the Model
# GradientDescentOptimizer
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
flag_1 = 0
# create an an array where we can store 1 picture
images = np.zeros((1,784))
# and the correct values
correct_vals = np.zeros((1,10))
preProcess("4_white.png")
gray = cv2.imread("4_white.png", 0)
flatten = gray.flatten() / 255.0
"""
we need to store the flatten image and generate
the correct_vals array
correct_val for a digit (9) would be
[0,0,0,0,0,0,0,0,0,1]
"""
images[0] = flatten
# print images[0]
print len(images[0])
sess.run(tf.initialize_all_variables())
ckpt = tf.train.get_checkpoint_state("/Users/xxxx/Desktop/TensorFlow")
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
my_classification = sess.run(tf.argmax(y, 1), feed_dict={x: [images[0]]})
print 'Neural Network predicted', my_classification[0], "for your digit"
i am not sure what mistake i have done.
Thinking that simple model might not work i have used this convolution code to predict.
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/models/image/mnist/convolutional.py
Even that does not predict properly :(