1

I declared the some Tensorflow variables representing weights and biases and updated their values in training before saving them, as shown:

#                # 5 x 5 x 5 patches, 1 channel, 32 features to compute.
weights = {'W_conv1':tf.Variable(tf.random_normal([3,3,3,1,32]), name='w_conv1'),
           #       5 x 5 x 5 patches, 32 channels, 64 features to compute.
           'W_conv2':tf.Variable(tf.random_normal([3,3,3,32,64]), name='w_conv2'),
           #                                  64 features
           'W_fc':tf.Variable(tf.random_normal([32448,1024]), name='w_fc'), #54080 = ceil(50/2/2) * ceil(50/2/2) * ceil(10/2/2) * 64
           #'W_fc':tf.Variable(tf.random_normal([54080,1024]), name='W_fc'), #54080 = ceil(50/2/2) * ceil(50/2/2) * ceil(20/2/2) * 64
           'out':tf.Variable(tf.random_normal([1024, n_classes]), name='w_out')}

biases = {'b_conv1':tf.Variable(tf.random_normal([32]), name='b_conv1'),
           'b_conv2':tf.Variable(tf.random_normal([64]), name='b_conv2'),
           'b_fc':tf.Variable(tf.random_normal([1024]), name='b_fc'),
           'out':tf.Variable(tf.random_normal([n_classes]), name='b_out')}

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())

    #some training code

    saver = tf.train.Saver()
    saver.save(sess, 'my-save-dir/my-model-10')

Then, I tried restoring the model and accessing the variables as shown below:

weights = {'W_conv1':tf.Variable(-1.0, validate_shape=False, name='w_conv1'),
           #       5 x 5 x 5 patches, 32 channels, 64 features to compute.
           'W_conv2':tf.Variable(-1.0, validate_shape=False, name='w_conv2'),
           #                                  64 features
           'W_fc':tf.Variable(-1.0, validate_shape=False, name='w_fc'), #54080 = ceil(50/2/2) * ceil(50/2/2) * ceil(10/2/2) * 64
           #'W_fc':tf.Variable(tf.random_normal([54080,1024]), name='W_fc'), #54080 = ceil(50/2/2) * ceil(50/2/2) * ceil(20/2/2) * 64
           'out':tf.Variable(-1.0, validate_shape=False, name='w_out')}

biases = {'b_conv1':tf.Variable(-1.0, validate_shape=False, name='b_conv1'),
           'b_conv2':tf.Variable(-1.0, validate_shape=False, name='b_conv2'),
           'b_fc':tf.Variable(-1.0, validate_shape=False, name='b_fc'),
           'out':tf.Variable(-1.0, validate_shape=False, name='b_out')}

with tf.Session() as sess:
    model_saver = tf.train.import_meta_graph('my-save-dir/my-model-10.meta')
    model_saver.restore(sess, "my-save-dir/my-model-10")
    print("Model restored.") 
    print('Initialized')
    print(sess.run(weights['W_conv1']))

However, I got a "FailedPreconditionError: Attempting to use uninitialized value w_conv1". Please assist.

1 Answers1

1

Here's what happens in your second code snippet: you first create all the variables w_conv1 to b_out, so the default graph is populated with the respective nodes. Then you call import_meta_graph(..) where again the default graph is populated with all the nodes from the model you stored in your first code snippet. However, for every node it tries to load, another node with the same name already exists (because you created it "by hand" just before). I don't know what happens internally in this case, but taking a look at the output of tf.global_variables() after the call to import_meta_graph(..) reveals that now every node exists twice with exactly the same name. So restoring is probably undefined and it might just restore half of the variables which is why you see this error.

So, you have two possibilites to solve this:

1) Don't use import_from_metagraph

weights = {'W_conv1':tf.Variable(tf.random_normal([3,3,3,1,32]), name='w_conv1'),
           #       5 x 5 x 5 patches, 32 channels, 64 features to compute.
           'W_conv2':tf.Variable(tf.random_normal([3,3,3,32,64]), name='w_conv2'),
           #                                  64 features
           'W_fc':tf.Variable(tf.random_normal([32448,1024]), name='w_fc'), #54080 = ceil(50/2/2) * ceil(50/2/2) * ceil(10/2/2) * 64
           #'W_fc':tf.Variable(tf.random_normal([54080,1024]), name='W_fc'), #54080 = ceil(50/2/2) * ceil(50/2/2) * ceil(20/2/2) * 64
           'out':tf.Variable(tf.random_normal([1024, n_classes]), name='w_out')}

biases = {'b_conv1':tf.Variable(tf.random_normal([32]), name='b_conv1'),
           'b_conv2':tf.Variable(tf.random_normal([64]), name='b_conv2'),
           'b_fc':tf.Variable(tf.random_normal([1024]), name='b_fc'),
           'out':tf.Variable(tf.random_normal([n_classes]), name='b_out')}

with tf.Session() as sess:
    model_saver = tf.train.Saver()
    model_saver.restore(sess, "my-save-dir/my-model-10")
    print("Model restored.")
    print('Initialized')
    print(sess.run(weights['W_conv1']))

2) Use import_from_metagraph but don't recreate the graph from hand

So, just this:

with tf.Session() as sess:
    model_saver = tf.train.import_meta_graph('my-save-dir/my-model-10.meta')
    model_saver.restore(sess, "my-save-dir/my-model-10")
    print("Model restored.") 
    print('Initialized')
    print(sess.run(tf.get_default_graph().get_tensor_by_name('w_conv1:0')))

Note how in this case you need to change how you retrieve the value in 'w_conv1' (last line). Instead of calling get_tensor_by_name() you could also use tf.get_variable(), but for this to work, you have to create the variables already by using tf.get_variable(). Check this post for more details: TensorFlow: getting variable by name

Graham
  • 7,431
  • 18
  • 59
  • 84
kafman
  • 2,862
  • 1
  • 29
  • 51