feed_dict 的 TensorFlow 问题在使用批处理时未被注意到

TensorFlow issue with feed_dict not being noticed when using batching

我一直在尝试使用 png 文件来完成 mnist 教程,并且已经把大部分内容都讲得通了。

代码的要点是 here,但是我将介绍它的作用以及问题发生的位置。

我有一个生成文件名的函数,我可以将这些文件名提供给 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

这符合预期。

在正文中,我运行这个函数用于训练和测试,并将它们转化为张量,将这些张量传递给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)

这部分也能正常工作。

这就是事情变得奇怪的地方。

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)

asdf这个变量是坏消息的承载者,一怒之下改名了。 看到这里的计划是使用不同的队列进行训练和测试。 我计划 feed_dict 一个单独的 int ,它可以用作在两者之间切换的临时布尔值。

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})

当 运行 连接它时,我得到了错误: "You must feed a value for placeholder tensor 'Placeholder' with dtype int32" 这很奇怪,因为 我正在喂它。

使用来自 "read_images_from_disk(input_queue)"

的 "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"

但是,如果我尝试评估紧随其后的批处理,则会出现上述错误。

为了实现这一点,我做错了什么?有没有更好的方法在测试集和训练集之间进行切换?生命宇宙万物的意义何在?我指望你 Whosebug。你是我唯一的希望。

在回答您的问题时,"Is there a better way to do this switching between testing and training sets?",是的。 tf.cond() 在每一步评估两个函数(参见 here) and therefore unnecessarily accesses both queues. This SO discussion 相关链接提供了几个更好的选择:

  • 使用 tf.placeholder_with_default() 作为测试数据
  • 使用make_template