Reputation: 177
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.
Upvotes: 0
Views: 181
Reputation: 2190
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:
tf.placeholder_with_default()
for your test datamake_template
Upvotes: 1