简体   繁体   中英

TensorFlow issue with feed_dict not being noticed when using batching

I have been trying to do the mnist tutorial with png files, and have gotten most things to the point where they make sense.

The gist of the code is here however I'm going to walk through what it does and where the issue is happening.

I have a function that generates filenames that I can give to the slice_input_producer.

def gen_file_names_and_labels(rootDir):

"""goes through the directory structure and extracts images and labels from each image."""
file_names = []
labels = []
for file_name in glob.glob(rootDir+'/*/*'):

    file_type_removed = file_name.split('.')[0]
    split_by_dir = file_type_removed.split('/')
    file_names.append(file_name)
    labels.append(int(split_by_dir[2])) #getting the folder it's in, turning into an int, and using as label
return file_names, labels

This behaves as expected.

In the body I run this function for training and testing, and turning them into tensors, passing those tensors into a slice_input_producer

sess = tf.InteractiveSession()

#THERE A PIPELINE FOR BOTH TESTING AND TRAINING. THEY COME IN PAIRS    
image_list_train,   label_list_train    = gen_file_names_and_labels('mnist_png/training')
image_list_test,    label_list_test     = gen_file_names_and_labels('mnist_png/testing')

images_train    = tf.convert_to_tensor(image_list_train,dtype=tf.string)    
images_test     = tf.convert_to_tensor(image_list_test,dtype=tf.string)    

#remember that these aren't the actual images, just file_names
labels_train    = tf.convert_to_tensor(label_list_train,dtype=tf.int32)
labels_test     = tf.convert_to_tensor(label_list_test,dtype=tf.int32)

input_queue_train   = tf.train.slice_input_producer([images_train   ,labels_train]  , shuffle=True)
input_queue_test    = tf.train.slice_input_producer([images_train   ,labels_train]  , shuffle=True)

this part also works correctly.

This is where things get strange.

asdf = tf.placeholder(tf.int32)
input_queue = tf.cond( asdf>0, lambda: input_queue_train, lambda: input_queue_test)
# input_queue = input_queue_test
image, label = read_images_from_disk(input_queue)
image_reshaped = tf.reshape( image, [28,28,1])
image_batch, label_batch = tf.train.batch([image_reshaped,label],batch_size=50)

The variable asdf was renamed in anger as it was the bearer of bad news. See the plan here was to use different queues for training and testing. I planned to feed_dict a single int that would work as an ad-hoc boolean for switching between the two.

coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
sess.run(tf.initialize_all_variables())
print(label_batch.eval(feed_dict={asdf:0,keep_prob:1.0}))
for i in range(500):
    # batch = mnist.train.next_batch(50)

    if i%20 ==0:
        train_accuracy = accuracy.eval(feed_dict={keep_prob:1.0,asdf:0})
        print("step %d, training accuracy %g"%(i, train_accuracy))

    train_step.run(feed_dict={keep_prob:0.9,asdf:0})

When running it though, I get the error: "You must feed a value for placeholder tensor 'Placeholder' with dtype int32" which is strange because I am feeding it.

using the "print(foo.eval(feed_dict={asdf:0,keep_prob:1.0)) I was able to notice some interesting phenomena. It seems that the switching works fine when I evaluate the individual variables declared "image, label" that come out of "read_images_from_disk(input_queue)"

However if I try to evaluate the batching that comes right after, I get the aforementioned error.

What am I doing wrong with batching to make this happen? Is there a better way to do this switching between testing and training sets? What is the meaning of life the universe and everything? I'm counting on you StackOverflow. You're my only hope.

In answer to your question, "Is there a better way to do this switching between testing and training sets?", yes there is. tf.cond() evaluates both functions at each step (see here ) and therefore unnecessarily accesses both queues. This SO discussion and the associated links provide a couple of better alternatives:

  • use tf.placeholder_with_default() for your test data
  • use make_template

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM