为什么tf.train.string_input_producer的num_epochs参数有时会触发OutOfRangeError?

时间:2017-08-07 05:49:14

标签: python tensorflow

我已经学会了如何使用QueueRunnerCoordinatorhere读取数据,并将其应用于读取csv文件,如下所示:

import tensorflow as tf

filename_queue = tf.train.string_input_producer(["file0.csv"],
                                                num_epochs=1)

reader = tf.TextLineReader(skip_header_lines=1)
key, value = reader.read(filename_queue)

# Default values, in case of empty columns. Also specifies the type of the
# decoded result.
record_defaults = [[1.0], [1.0], [1.0], [1.0], [1.0]]
col1, col2, col3, col4, col5 = tf.decode_csv(
    value, record_defaults=record_defaults)
features = tf.stack([col1, col2, col3, col4])

with tf.Session() as sess:
    sess.run(tf.local_variables_initializer())

    # Start populating the filename queue.
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)

    try:
        while not coord.should_stop():
            # Retrieve a single instance:
            example, label = sess.run([features, col5])
            # print(example, label)
    except tf.errors.OutOfRangeError:
        print("Epoch limit reached.")
    finally:
        coord.request_stop()
    coord.join(threads)

虽然此代码运行顺利,但我对tryexceptfinally语句的功能感到好奇。所以我删除了它们,相应的行变为:

while not coord.should_stop():
    # Retrieve a single instance:
    example, label = sess.run([features, col5])
    # print(example, label)
coord.request_stop()
coord.join(threads)

然后代码崩溃了,引发了OutOfRangeError

OutOfRangeError (see above for traceback): FIFOQueue '_0_input_producer' is closed and has insufficient elements (requested 1, current size 0)
    [[Node: ReaderReadV2 = ReaderReadV2[_device="/job:localhost/replica:0/task:0/cpu:0"](TextLineReaderV2, input_producer)]]

有趣的是,如果我更改以下代码(第3行)

filename_queue = tf.train.string_input_producer(["file0.csv"], num_epochs=1)

filename_queue = tf.train.string_input_producer(["file0.csv"])

代码不会崩溃,file0.csv中的数据可以正确读取。

设置num_epochs并删除try/except/finally语句时,代码崩溃的原因是什么?为什么在未设置num_epochs时它不会崩溃?

1 个答案:

答案 0 :(得分:0)

当您将num_epochs设置为1时,代码因队列中的元素不足而崩溃。

因为您仍在运行协调器     while not coord.should_stop():工作线程尝试从耗尽的队列中访问值。如果未设置num_epochs,则默认值为None,这意味着它可以无限次循环数据,因此没有错误。

使用try/except时,它会处理队列耗尽信号并正常停止程序,不会崩溃。