tf.train.string_input_producer 在循环中的行为 [英] tf.train.string_input_producer behavior in a loop
问题描述
以下片段摘自 TensorFlow 0.12 API 文档
The following snippet has been taken from the TensorFlow 0.12 API documentation
def input_pipeline(filenames, batch_size, num_epochs=None):
filename_queue = tf.train.string_input_producer(
filenames, num_epochs=num_epochs, shuffle=True)
example, label = read_my_file_format(filename_queue)
# min_after_dequeue defines how big a buffer we will randomly sample
# from -- bigger means better shuffling but slower start up and more
# memory used.
# capacity must be larger than min_after_dequeue and the amount larger
# determines the maximum we will prefetch. Recommendation:
# min_after_dequeue + (num_threads + a small safety margin) * batch_size
min_after_dequeue = 10000
capacity = min_after_dequeue + 3 * batch_size
example_batch, label_batch = tf.train.shuffle_batch(
[example, label], batch_size=batch_size, capacity=capacity,
min_after_dequeue=min_after_dequeue)
return example_batch, label_batch
我的问题对于普通 TensorFlow 用户来说可能非常基础,但我绝对是初学者.问题如下:
The question I have might be very basic for a regular TensorFlow user, but I am an absolute beginner. The question is the following :
tf.train.string_input_producer
创建一个队列来保存文件名.由于input_pipeline()
在训练期间被一遍又一遍地调用,如何确保每次都使用相同的队列?我想,这很重要,因为如果对input_pipeline()
的不同调用导致创建新队列,似乎没有办法确保每次都选择不同的图像和纪元计数器并且可以适当地维护洗牌.
tf.train.string_input_producer
creates a queue for holding the filenames. As theinput_pipeline()
is called over and over again during training, how will it be ensured that everytime the same queue is used ? I guess, it is important since, if different calls toinput_pipeline()
result in a creation of a new queue, there does not seem to be a way to ensure that different images are picked everytime and epoch counter and shuffling can be properly maintained.
推荐答案
input_pipeline
函数仅创建负责生成批量数据的图(通常更大)的一部分.如果您要两次调用 input_pipeline
- 无论出于何种原因 - 您确实会创建两个不同的队列.
The input_pipeline
function only creates the part of a (usually larger) graph that is responsible for producing batches of data. If you were to call input_pipeline
twice - for whatever reason - you would be creating two different queues indeed.
一般来说,tf.train.string_input_producer
函数实际上在当前活动图中创建了一个队列node(或操作)(它是默认图形,除非您指定不同的内容).read_my_file_format
然后从该队列中读取并依次生成单个示例"张量,而 tf.train.shuffle_batch
然后将这些张量分成长度为 batch_size
的束每个.
In general, the function tf.train.string_input_producer
actually creates a queue node (or operation) in the currently active graph (which is the default graph unless you specify something different). read_my_file_format
then reads from that queue and sequentially produces single "example" tensors, while tf.train.shuffle_batch
then batches these into bundles of length batch_size
each.
然而,tf.train.shuffle_batch
的输出,这里是从 input_pipeline
函数返回的两个张量,只有当它在会话下评估.如果您多次评估这些张量,它们将包含不同的值 - 通过 read_my_file_format
从输入队列中列出的文件中获取.
However, the output of tf.train.shuffle_batch
, two Tensors here that are returned from the input_pipeline
function, only really takes on a (new) value when it is evaluated under a session. If you evaluate these tensors multiple times, they will contain different values - taken, through read_my_file_format
, from files listed in the input queue.
这样想:
X_batch, Y_batch = input_pipeline(..., batch_size=100)
with tf.Session() as sess:
sess.run(tf.global_variable_initializer())
tf.train.start_queue_runners()
# get the first 100 examples and labels
X1, Y1 = sess.run((X_batch, Y_batch))
# get the next 100 examples and labels
X2, Y2 = sess.run((X_batch, Y_batch))
# etc.
让它运行的样板代码有点复杂,例如因为队列需要在图中实际启动和停止,因为它们在运行时会抛出 tf.errors.OutOfRangeError
等.更完整的示例可能如下所示:
The boilerplate code to get it running is a bit more complex, e.g. because queues need to actually be started and stopped in the graph, because they will throw a tf.errors.OutOfRangeError
when they run dry, etc.
A more complete example could look like this:
with tf.Graph().as_default() as graph:
X_batch, Y_batch = input_pipeline(..., batch_size=100)
prediction = inference(X_batch)
optimizer, loss = optimize(prediction, Y_batch)
coord = tf.train.Coordinator()
with tf.Session(graph=graph) as sess:
init = tf.group(tf.local_variable_initializer(),
tf.global_variable_initializer())
sess.run(init)
# start the queue runners
threads = tf.train.start_queue_runners(coord=coord)
try:
while not coord.should_stop():
# now you're really indirectly querying the
# queue; each iteration will see a new batch of
# at most 100 values.
_, loss = sess.run((optimizer, loss))
# you might also want to do something with
# the network's output - again, this would
# use a fresh batch of inputs
some_predicted_values = sess.run(prediction)
except tf.errors.OutOfRangeError:
print('Training stopped, input queue is empty.')
finally:
coord.request_stop()
# stop the queue(s)
coord.request_stop()
coord.join(threads)
要更深入地了解,您可能需要查看阅读数据文档.
For a deeper understanding, you might want to look at the Reading data documentation.
这篇关于tf.train.string_input_producer 在循环中的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!