slim.dataset_data_provider.DatasetDataProvider with num_epochs=1 抛出错误

Posted

技术标签:

【中文标题】slim.dataset_data_provider.DatasetDataProvider with num_epochs=1 抛出错误【英文标题】:slim.dataset_data_provider.DatasetDataProvider with num_epochs=1 throws error 【发布时间】:2018-07-07 19:01:11 【问题描述】:

我正在使用相对较新的 tf.slim 数据集,DatasetDataProvider 模式。以下代码显示了关键片段:

with tf.Graph().as_default():    

    # get the dataset split
    dataset = util.get_split(train_or_eval,
                             args.tfrecord_folder, 
                             0, 
                             args.eval_set_size,
                             crop_size, 
                             file_pattern=file_pattern)


    features, labels = util.load_batch(dataset,
                                       batch_size=args.eval_batch_size, 
                                       num_readers=10,
                                       num_epochs=1,
                                       is_training=True)

    with tf.Session() as sess:

        sess.run(tf.global_variables_initializer())
        sess.run(tf.local_variables_initializer())

        # start the queue runner
        with slim.queues.QueueRunners(sess): 

               ...run some ops...

下面是 load_batch 的定义:

def load_batch(dataset, batch_size=64, is_training=False, 
               num_epochs=None, common_queue_capacity=256,
               common_queue_min=32, num_readers=None):

     shuffle = True

     # create the data provider
     data_provider = slim.dataset_data_provider.DatasetDataProvider(
                              dataset, 
                              num_readers=num_readers,
                              shuffle=shuffle, 
                              num_epochs=num_epochs, 
                              common_queue_capacity= 
                                  common_queue_capacity, 
                              common_queue_min= common_queue_min, 
                              seed=5)

     # get the tensors from the data provider
     images, labels = data_provider.get(['image_raw','label'])

     # batch up some training data
     images, labels = tf.train.batch([image_raw, label],
                                      batch_size=batch_size,
                                      num_threads=5,
                                      allow_smaller_final_batch=True,
                                      capacity=2 * batch_size)

     return images, labels

这在 num_epochs=None 时工作正常(根据源中的 cmets 意味着可以无限次读取 tfrecords 文件),但在 num_epochs=1 时失败。这是错误消息:

Out of range: FIFOQueue '_9_batch/fifo_queue' is closed and has insufficient elements (requested 32, current size 0)

显然,我需要能够在不重复示例的情况下运行 eval 步骤,以获得良好的准确性和混淆矩阵数。任何想法将不胜感激......

根据 cmets 中的请求,我正在添加堆栈跟踪。我在 Google Cloud ML 中运行这项工作,因此以这种方式显示它最容易。日志有一系列成对的消息如下:

超出范围:FIFOQueue '_6_batch/fifo_queue' 已关闭并且有 元素不足(请求 32,当前大小 0)[[节点:batch = QueueDequeueUpToV2[component_types=[DT_UINT8, DT_INT64, DT_STRING, DT_STRING],timeout_ms=-1, _device="/job:localhost/replica:0/task:0/cpu:0"](batch/fifo_queue, batch/n)]]

[[节点:批次= QueueDequeueUpToV2[component_types=[DT_UINT8, DT_INT64, DT_STRING, DT_STRING],timeout_ms=-1, _device="/job:localhost/replica:0/task:0/cpu:0"](batch/fifo_queue, batch/n)]]

最终堆栈跟踪是

"副本主控 0 以非零状态 1 退出。终止 原因:Error.Traceback(最近一次调用最后一次):[...] 文件 “/root/.local/lib/python2.7/site-packages/trainer/task.py”,第 509 行, 在 main() 文件“/root/.local/lib/python2.7/site-packages/trainer/task.py”,第 505 行, 主要是 run() 文件“/root/.local/lib/python2.7/site-packages/trainer/task.py”,第 113 行, 运行中 run_eval(args) 文件“/root/.local/lib/python2.7/site-packages/trainer/task.py”,第 285 行, 在 run_eval is_training=True) 文件“/root/.local/lib/python2.7/site-packages/trainer/util.py”,第 210 行, 在 load_batch 容量=3 * batch_size)文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/input.py”, 第 872 行,批量 名称=名称)文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/input.py”, 第 665 行,在 _batch 中 dequeued = queue.dequeue_up_to(batch_size, name=name) 文件 "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/data_flow_ops.py", 第 499 行,在 dequeue_up_to 中 self._queue_ref, n=n, component_types=self._dtypes, name=name) 文件 "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_data_flow_ops.py", 第 1402 行,在 _queue_dequeue_up_to_v2 timeout_ms=timeout_ms, name=name) 文件 "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py", 第 763 行,在 apply_op 中 op_def=op_def) 文件 "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", 第 2327 行,在 create_op 中 original_op=self._default_original_op, op_def=op_def) 文件 "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", 第 1226 行,在 init 中 self._traceback = _extract_stack()

OutOfRangeError(参见上面的回溯):FIFOQueue '_6_batch/fifo_queue' 已关闭且元素不足 (请求 32,当前大小 0)[[节点:批处理 = QueueDequeueUpToV2[component_types=[DT_UINT8, DT_INT64, DT_STRING, DT_STRING],timeout_ms=-1, _device="/job:localhost/replica:0/task:0/cpu:0"](batch/fifo_queue, batch/n)]] 要了解有关您的工作退出原因的更多信息,请查看日志: https://console.cloud.google.com/logs/viewer?...

【问题讨论】:

你能发布完整的堆栈跟踪吗? 我在上面添加了完整的堆栈跟踪。感谢您的任何想法... 【参考方案1】:

在对 Github 进行广泛研究和阅读后,许多人报告说,消除这个问题是确保本地和全局变量的初始化程序在会话顶部运行。喜欢this one 使用以下内容:

tf.group(tf.local_variables_initializer(), tf.global_variables_initializer

但是,对于许多人(包括我)来说,这并没有解决问题,我怀疑对于那些确实有效的人来说,还有其他问题导致空 FIFO 队列。

经过大量阅读,似乎这是一个没有明显修复的缺陷。提出了几种解决方法。我正在运行一个完整的训练、评估和预测周期。这是对我有用的方法:

1) 在训练中,我设置了 num_epochs=None。这会无限次地循环数据,如果文档正确,则每个示例在每个 epoch 仅显示一次。我进行了抽查以确认这一点,但我的数据集太大而无法保证文档是正确的。也就是说,我的模型并没有过度拟合。训练、测试和验证在准确性方面都相当接近。

2) 在评估时,我正在构建一个 15 模型集合,我想在提交未标记数据进行验证之前将提案选择与基本事实进行比较。我从 k 折交叉验证运行中保留了一个额外的保留集,并且需要确保保留集中的每个示例都被预测一次且仅一次。因此,为了完成这项工作,我:a) 设置 num_epochs=1,b) 消除 eval 图中除预测之外的所有计算,c) 将 eval 集的大小减少到 ~3000 个示例,d) 设置 shuffle_batch=False,e ) 设置批量大小,以便队列有一些额外的示例

在这些条件下,队列运行器在我的图表完成并获得测试集之前没有用完示例

3) 在预测时,我再次使用了与 eval 相同的技术,只是我选择了与预测记录数完全相等的批量大小和训练步数。由于没有渐变后退道具,因此预测速度足够快,可以在排队者杀死我的工作之前完成。

问题解决了。陪审团操纵。但是,它奏效了。绝望是聪明才智之母!

【讨论】:

以上是关于slim.dataset_data_provider.DatasetDataProvider with num_epochs=1 抛出错误的主要内容,如果未能解决你的问题,请参考以下文章