Whenever I try to use tf.reset_default_graph(), I get this error: IndexError: list index out of range or ``. At which part of my code should I use this? When should I be using this?
Edit:
I updated the code, but the error still occurs.
def evaluate():
with tf.name_scope("loss"):
global x # x is a tf.placeholder()
xentropy = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=neural_network(x))
loss = tf.reduce_mean(xentropy, name="loss")
with tf.name_scope("train"):
optimizer = tf.train.AdamOptimizer()
training_op = optimizer.minimize(loss)
with tf.name_scope("exec"):
with tf.Session() as sess:
for i in range(1, 2):
sess.run(tf.global_variables_initializer())
sess.run(training_op, feed_dict={x: np.array(train_data).reshape([-1, 1]), y: label})
print "Training " + str(i)
saver = tf.train.Saver()
saver.save(sess, "saved_models/testing")
print "Model Saved."
def predict():
with tf.name_scope("predict"):
tf.reset_default_graph()
with tf.Session() as sess:
saver = tf.train.import_meta_graph("saved_models/testing.meta")
saver.restore(sess, "saved_models/testing")
output_ = tf.get_default_graph().get_tensor_by_name('output_layer:0')
print sess.run(output_, feed_dict={x: np.array([12003]).reshape([-1, 1])})
def main():
print "Starting Program..."
evaluate()
writer = tf.summary.FileWriter("mygraph/logs", tf.get_default_graph())
predict()
If I remove the tf.reset_default_graph() from the updated code, I get this error: ValueError: cannot add op with name hidden_layer1/kernel/Adam as that name is already used
From my current understanding, tf.reset_default_graph() removes all graphs, hence I avoided the error I mention above(ValueError: cannot add op with name hidden_layer1/kernel/Adam as that name is already used)
This is probably how you use it:
import tensorflow as tf
a = tf.constant(1)
with tf.Session() as sess:
tf.reset_default_graph()
You get an error because you use it in a session. From the tf.reset_default_graph() documentation:
Calling this function while a tf.Session or tf.InteractiveSession is
active will result in undefined behavior. Using any previously created
tf.Operation or tf.Tensor objects after calling this function will
result in undefined behavior
tf.reset_default_graph() can be helpful (at least for me) during the testing phase while I experiment in jupyter notebook. However, I have never used it in production and do not see how it would be helpful there.
Here is an example that could be in a notebook:
import tensorflow as tf
# create some graph
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print sess.run(...)
Now I do not need this stuff anymore, but if I create another graph and visualize it in tensorboard I will see old nodes and the new nodes. To solve this, I could restart the kernel and run only the next cell. However, I can just do:
tf.reset_default_graph()
# create a new graph
with tf.Session() as sess:
print sess.run(...)
Edit after OP added his code:
with tf.name_scope("predict"):
tf.reset_default_graph()
Here is what approximately happens. Your code fails because tf.name_scope already added something to a graph. While being inside of this "adding something to the graph", you tell TF to remove the graph completely, but it can't because it is busy adding something.
For some reason, I need to build a new graph FOR LOTS OF TIMES, and I have just tested, which works eventually! Many thanks for Salvador Dali's answer:-)
import tensorflow as tf
from my_models import Classifier
for i in range(10):
tf.reset_default_graph()
# build the graph
global_step = tf.get_variable('global_step', [], initializer=tf.constant_initializer(0), trainable=False)
classifier = Classifier(global_step)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
print("do sth here.")
With TensorFlow 2.0 coming out, now it's better to use tf.compat.v1.reset_default_graph() in order to avoid getting warning. Link to the documentation: https://www.tensorflow.org/api_docs/python/tf/compat/v1/reset_default_graph
simply put,
use to clear previous placeholder which you using sess.run() created
Related
I have a frozen inference graph stored in a .pb file, which was obtained from a trained Tensorflow model by the freeze_graph function.
Suppose, for simplicity, that I would like to change some of the sigmoid activations in the model to tanh activations (and let's not discuss whether this is a good idea).
How can this be done with access only to the frozen graph in the .pb file, and without the possibility to retrain the model?
I am aware of the Graph Editor library in tf.contrib, which should be able to do this kind of job, but I wasn't able to figure out a simple way to do this in the documentation.
The solution is to use import_graph_def:
import tensorflow as tf
sess = tf.Session()
def load_graph(frozen_graph_filename):
with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
with tf.Graph().as_default() as graph:
tf.import_graph_def(graph_def, name='')
return graph
graph_model = load_graph("frozen_inference_graph.pb")
graph_model_def = graph_model.as_graph_def()
graph_new = tf.Graph()
graph_new.as_default()
my_new_tensor = # whatever
tf.import_graph_def(graph_model_def, name='', input_map={"tensor_to_replace": my_new_tensor})
#do somthing with your new graph
Here I wrote a post about it
Can you try this:
graph = load_graph(filename)
graph_def = graph.as_graph_def()
# if ReLu op is at node 161
graph_def.node[161].op="tanh"
tf.train.write_graph(graph_def, path2savfrozn, "altered_frozen.pb", False)
Please let know the if it works.
The *.pb file contains a SavedModel protocol buffer. You should be able to load it using a SavedModel loader. You can also inpsect it with the SavedModel CLI. The full documentation on SavedModels is here.
Something along these lines should work:
graph_def = tf.GraphDef()
with open('frozen_inference.pb', 'rb') as f:
graph_def.ParseFromString(f.read())
with tf.Graph().as_default() as graph:
importer.import_graph_def(graph_def, name='')
new_model = tf.GraphDef()
with tf.Session(graph=graph) as sess:
for n in sess.graph_def.node:
if n.op == 'Sigmoid':
nn = new_model.node.add()
nn.op = 'Tanh'
nn.name = n.name
for i in n.input:
nn.input.extend([i])
else:
nn = new_model.node.add()
nn.CopyFrom(n)
So I implemented a RNN word generator model in jupytor notebook.
When I was trying to use the trained model to generate some words:
with open(os.path.join(cfgs['save_dir'], 'config.pkl'), 'rb') as f:
saved_args = cPickle.load(f)
with open(os.path.join(cfgs['save_dir'], 'words_vocab.pkl'), 'rb') as f:
words, vocab = cPickle.load(f)
with tf.Session() as sess:
model = Model(saved_args, True)
tf.global_variables_initializer().run()
saver = tf.train.Saver(tf.global_variables())
ckpt = tf.train.get_checkpoint_state(cfgs['save_dir'])
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
print(model.sample(sess, words, vocab, cfgs['n'], cfgs['prime'], cfgs['sample'], cfgs['pick'], cfgs['width']))
It works for the first time, but if I run the code again there is an error:
ValueError: Variable rnnlm/softmax_w already exists, disallowed. Did you mean to set reuse=True in VarScope?
Right now I have to shut down the ipynb file then run the code to get a new sample.
How to change the code to avoid this situation?
You can call the model.sample function multiple times without a problem but everything else (creating the session, constructing the Model, loading the checkpoint) should only be run once. If you refactor your code then you won't see that error message anymore.
I need to get the loss history over time to plot it in graph.
Here is my skeleton of code:
optimizer = tf.contrib.opt.ScipyOptimizerInterface(loss, method='L-BFGS-B',
options={'maxiter': args.max_iterations, 'disp': print_iterations})
optimizer.minimize(sess, loss_callback=append_loss_history)
With append_loss_history definition:
def append_loss_history(**kwargs):
global step
if step % 50 == 0:
loss_history.append(loss.eval())
step += 1
When I see the verbose output of ScipyOptimizerInterface, the loss is actually decrease over time.
But when I print loss_history, the losses are nearly the same over time.
Refer to the doc:
"Variables subject to optimization are updated in-place AT THE END OF OPTIMIZATION"
https://www.tensorflow.org/api_docs/python/tf/contrib/opt/ScipyOptimizerInterface. Is that the reason for the being unchanged of the loss?
I think you have the problem down; the variables themselves are not modified until the end of the optimization (instead being fed to session.run calls), and evaluating a "back channel" Tensor gets the un-modified variables. Instead, use the fetches argument to optimizer.minimize to piggyback on the session.run calls which have the feeds specified:
import tensorflow as tf
def print_loss(loss_evaled, vector_evaled):
print(loss_evaled, vector_evaled)
vector = tf.Variable([7., 7.], 'vector')
loss = tf.reduce_sum(tf.square(vector))
optimizer = tf.contrib.opt.ScipyOptimizerInterface(
loss, method='L-BFGS-B',
options={'maxiter': 100})
with tf.Session() as session:
tf.global_variables_initializer().run()
optimizer.minimize(session,
loss_callback=print_loss,
fetches=[loss, vector])
print(vector.eval())
(Modified from the example in the documentation). This prints Tensors with the updated values:
98.0 [ 7. 7.]
79.201 [ 6.29289341 6.29289341]
7.14396e-12 [ -1.88996808e-06 -1.88996808e-06]
[ -1.88996808e-06 -1.88996808e-06]
There are two python files, The first one is for saving the tensorflow
model. The second one is for restoring the saved model.
Question:
When I run the two files one after another, it's ok.
When I run the first one, restart the edit and run the second one,it
tells me that the w1 is not defined?
What I want to do is:
Save a tensorflow model
Restore the saved model
What's wrong with it? Thanks for your kindly help?
model_save.py
import tensorflow as tf
w1 = tf.Variable(tf.random_normal(shape=[2]), name='w1')
w2 = tf.Variable(tf.random_normal(shape=[5]), name='w2')
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
saver.save(sess, 'SR\\my-model')
model_restore.py
import tensorflow as tf
with tf.Session() as sess:
saver = tf.train.import_meta_graph('SR\\my-model.meta')
saver.restore(sess,'SR\\my-model')
print (sess.run(w1))
Briefly, you should use
print (sess.run(tf.get_default_graph().get_tensor_by_name('w1:0')))
instead of print (sess.run(w1)) in your model_restore.py file.
model_save.py
import tensorflow as tf
w1_node = tf.Variable(tf.random_normal(shape=[2]), name='w1')
w2_node = tf.Variable(tf.random_normal(shape=[5]), name='w2')
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(w1_node.eval()) # [ 0.43350926 1.02784836]
#print(w1.eval()) # NameError: name 'w1' is not defined
saver.save(sess, 'my-model')
w1_node is only defined in model_save.py, and model_restore.py file can't recognize it.
When we call a Tensor variable by its name, we should use get_tensor_by_name, as this post Tensorflow: How to get a tensor by name? suggested.
model_restore.py
import tensorflow as tf
with tf.Session() as sess:
saver = tf.train.import_meta_graph('my-model.meta')
saver.restore(sess,'my-model')
print (sess.run(tf.get_default_graph().get_tensor_by_name('w1:0')))
# [ 0.43350926 1.02784836]
print(tf.global_variables()) # print tensor variables
# [<tf.Variable 'w1:0' shape=(2,) dtype=float32_ref>,
# <tf.Variable 'w2:0' shape=(5,) dtype=float32_ref>]
for op in tf.get_default_graph().get_operations():
print str(op.name) # print all the operation nodes' name
When I run this code:
x = tf.placeholder(tf.int32, shape=(None, 3))
with tf.Session() as sess:
feed_dict = dict()
feed_dict[x] = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
input = sess.run([x], feed_dict=feed_dict)
I get this error:
Placeholder_2:0 is both fed and fetched.
I'm not sure what I'm doing wrong here. Why does this not work?
Are you sure this code covers what you are trying to achieve?
You ask to read out whatever you pass through. This is not a valid call in tensorflow. If you want to pass through values and do nothing with it (what for?) you should have an identity operation.
x = tf.placeholder(tf.int32, shape=(None, 3))
y = tf.identity(x)
with tf.Session() as sess:
feed_dict = dict()
feed_dict[x] = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
input = sess.run([y], feed_dict=feed_dict)
The problem is "feeding" actually kind of overwrites whatever your op generates, thus you cannot fetch it at this moment (since there is nothing being really produced by this particular op anymore). If you add this identity op, you correctly feed (override x) do nothing with the result (identity) and fetch it (what identity produces, which is whatever you feeded as an output of x)
I found out what I was doing wrong.
x is a placeholder -- it holds information and evaluating x does not do anything. I forgot that vital piece of information and proceeded to attempt to run the Tensor x inside sess.run()
Code similar to this would work if, say, there was another Tensor y that depended on x and I ran that like sess.run([y], feed_dict=feed_dict)