2
votes

My question is about context and the TensorFlow default sessions and graph.

The problem: Tensorflow is unable to feed a placeholder in the following scenario: Function Test defines a graph. Function Test_Once defines a session. When Function Test calls Test_Once -> Feeding fails. When I change the code so function Test declares the graph + the session -> all is working.

Here is the code:

def test_once(g, saver, summary_writer, logits, images, summary_op):
  """Run a session once for a givven test image.

  Args:
    saver: Saver.
    summary_writer: Summary writer.
    logits: 
    summary_op: Summary op.
  """
  with tf.Session(graph=g) as sess:
    ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
    if ckpt and ckpt.model_checkpoint_path:
      # Restores from checkpoint
      saver.restore(sess, ckpt.model_checkpoint_path)

      # extract global_step from it.
      global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
    else:
      print('No checkpoint file found')
      return

    images.astype(np.float32)

    predictions = sess.run(logits, feed_dict={'InputPlaceHolder/TestInput:0':images})

    summary = tf.Summary()
    summary.ParseFromString(sess.run(summary_op))
    summary_writer.add_summary(summary, global_step)

    return (predictions)


def test():
  """Test LCPR with a test image"""
  with tf.Graph().as_default() as g:

    # Get image for testing
    images, labels = lcpr.test_input()

    # Build a Graph that computes the logits predictions from the
    # inference model.
    with tf.name_scope('InputPlaceHolder'):

        test_image_placeholder = tf.placeholder(tf.float32, (None,None,None,3), 'TestInput')
        # Display the training images in the visualizer.
        # The 'max_outputs' default is 3. Not stated. (Max number of batch elements to generate images for.)
        #tf.summary.image('input_images', test_image_placeholder)


    with tf.name_scope('Inference'):
        logits = lcpr.inference(test_image_placeholder)


    # Restore the moving average version of the learned variables for eval.
    variable_averages = tf.train.ExponentialMovingAverage(
        lcpr.MOVING_AVERAGE_DECAY)
    variables_to_restore = variable_averages.variables_to_restore()
    saver = tf.train.Saver(variables_to_restore)

    # Build the summary operation based on the TF collection of Summaries.
    writer = tf.summary.FileWriter("/tmp/lcpr/test")
    writer.add_graph(g) 

    summary_op = tf.summary.merge_all()
    summary_writer = tf.summary.FileWriter(FLAGS.test_dir, g)

    #Sadly, this will not work:     
    predictions = test_once(g, saver, summary_writer, logits, images, summary_op)

    '''Alternative working option :  
    with tf.Session() as sess:
        ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
        if ckpt and ckpt.model_checkpoint_path:
          # Restores from checkpoint
          saver.restore(sess, ckpt.model_checkpoint_path)
          # Assuming model_checkpoint_path looks something like:
          #   /my-favorite-path/cifar10_train/model.ckpt-0,
          # extract global_step from it.
          global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
        else:
          print('No checkpoint file found')
          return

        x = sess.run(logits, feed_dict={'InputPlaceHolder/TestInput:0':images})
        print(x)
    '''

The above code yeilds an error that the placeholder is not fed:

InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'InputPlaceHolder/TestInput' with dtype float

And it's not that TensorFlow does not recognize the placeholder. If I change the name from 'InputPlaceHolder/TestInput:0' to 'InputPlaceHolder/TestInput:1' I receive a message calming that 'InputPlaceHolder/TestInput' exists but has only 1 output. This makes sense, and I guess the session runs on my default graph.

Things only work for me if I stay within the same def: If I change the code by running the commented part (starting ' with tf.Session() as sess:) directly from within the first function all works.

I wonder what am I missing? My guess that is context related, maybe not assigning the session to the graph?

1
Try with tf.Session(graph=g) as sess: and make sure you send the right graph to the session - bluesummers
Thanks for replying! I actually tried that and it did not solve the issue. Also tried to get the tf default graph and use it but no luck. Something is lost for me when running the session from external function. - Shahar Karny
Seems unlikely, you need to return g from the test function, and then send the returned value to the test_once function. Please try that and reply - bluesummers
Thanks. updated the code above with passing the graph g to test_once and also the error message. - Shahar Karny

1 Answers

2
votes

Solved. Stupid mistake test_once calls sess.run twice. On the second time, indeed no placeholder is fed.... : summary.ParseFromString(sess.run(summary_op))