我正在尝试使用多个队列进行读取和批处理,但这会导致TF偶尔锁定。这是一些示例代码:
import tensorflow as tf
coordinator = tf.train.Coordinator()
file_queue = tf.train.string_input_producer(tf.train.match_filenames_once(...))
reader = tf.TextLineReader()
key, serialized_example = reader.read(file_queue)
keys, serialized_examples = tf.train.batch([key, serialized_example], 10)
# repeat the code snippet below multiple times, in my case 4
file_queue_i = tf.train.string_input_producer(tf.train.match_filenames_once(...))
reader_i = tf.TextLineReader()
key_i, serialized_example_i = reader.read(file_queue_i)
initializer = tf.initialize_all_variables()
session = tf.Session(config=tf.ConfigProto(inter_op_parallelism_threads=1, intra_op_parallelism_threads=1))
session.run(initializer)
threads = tf.train.start_queue_runners(sess=session, coord=coordinator)
session.run(keys)
TensorFlow偶尔锁定在最后一行,当我实际尝试运行某些东西时。但是,使用上面的代码很难重现这种行为。在1000多次运行中,我只能挂起一次。在我的真实代码中,实际的读者更复杂,它使用的是TFRecords,但其他方面都是一样的。它有2/3的时间挂起,共有3个队列。有5个队列,它似乎永远不会运行,并且有一个队列,它似乎永远不会挂起。这是在0.6的Mac上。我有一个不同的系统运行Ubuntu,也有0.6,我遇到了同样的问题(虽然在Ubuntu系统上锁定的频率要高得多)。
更新:对上述代码锁定频率的更准确估计是5,000次试验中的1次。
答案 0 :(得分:2)
这可能是由于没有足够的操作线程造成的。如果你有一个队列运行器1取决于队列运行器2的工作,并且你以异步方式运行它们,那么你需要至少两个操作线程,通过inter_op_parallelism_threads
设置,以保证正在取得进展。
在您的情况下,您的队列运行符正在填充batch
线程,具体取决于string_input_producer
队列不为空。如果与string_input_producer
队列关联的队列运行器首先运行,那么一切都很好。但是如果首先调度batch
队列运行器,它将卡在string_input_producer.dequeue
op中,等待string_input_producer
队列获取一些文件名。由于TensorFlow操作线程池中只有1个线程,enqueue
的{{1}}操作永远不会被分配一个线程来完成(即执行其string_input_producer
方法)
最简单的解决方案是至少拥有与同时Compute
调用一样多的操作线程(即队列数+ 1)。如果您真的想限制自己使用一个线程,可以使用主线程同步预加载文件名队列文件文件名。
run
如果您有多个文件名队列,则上面的代码需要一些封装。或者,如果所有input_producer队列都有 coordinator = tf.train.Coordinator()
import glob
files = glob.glob('/temp/pipeline/*')
if FLAGS.preload_filenames:
file_queue = tf.FIFOQueue(capacity=len(files), dtypes=tf.string)
enqueue_val = tf.placeholder(dtype=tf.string)
enqueue_op = file_queue.enqueue(enqueue_val)
else:
file_queue = tf.train.string_input_producer(files)
reader = tf.TextLineReader()
key, serialized_example = reader.read(file_queue)
keys, serialized_examples = tf.train.batch([key, serialized_example], 5,
capacity=10)
initializer = tf.initialize_all_variables()
session = tf.Session(config=tf.ConfigProto(inter_op_parallelism_threads=1,
intra_op_parallelism_threads=1))
print 'running initializer'
session.run(initializer)
if FLAGS.preload_filenames:
print 'preloading filenames'
for fn in files:
session.run([enqueue_op], feed_dict={enqueue_val: fn})
print 'size - ', session.run([file_queue.size()])
session.run([file_queue.close()])
print 'starting queue runners'
threads = tf.train.start_queue_runners(sess=session, coord=coordinator)
print 'about to run session'
print session.run(keys)
个文件名
prebuffer_amount