具有num_epochs = 1的slim.dataset_data_provider.DatasetDataProvider抛出错误

时间:2018-01-29 06:00:48

标签: tensorflow

我正在使用相对较新的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时(根据源中的注释意味着可以无限次读取tfrecords的文件)​​,这种方法正常工作,但是当num_epochs = 1时失败。这是错误消息:

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

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

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

  

超出范围: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)]]

     

[[节点:批次=   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)]]

Final Stack Trace是

  

"副本主机0退出,其非零状态为1.终止   原因:Error.Traceback(最近一次调用最后一次):[...]文件   " /root/.local/lib/python2.7/site-packages/trainer/task.py" ;,第509行,   在       main()File" /root/.local/lib/python2.7/site-packages/trainer/task.py" ;,第505行,   在主要       run()File" /root/.local/lib/python2.7/site-packages/trainer/task.py" ;,第113行,   在奔跑       run_eval(args)File" /root/.local/lib/python2.7/site-packages/trainer/task.py" ;,第285行,   在run_eval中       is_training = True)File" /root/.local/lib/python2.7/site-packages/trainer/util.py" ;,第210行,   在load_batch中       capacity = 3 * batch_size)文件" /usr/local/lib/python2.7/dist-packages/tensorflow/python/training/input.py",   第872行,批量生产       name = name)File" /usr/local/lib/python2.7/dist-packages/tensorflow/python/training/input.py",   第_ 665行,在_batch中       dequeued = queue.dequeue_up_to(batch_size,name = name)File" /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)File" /usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py",   第763行,在apply_op中       op_def = op_def)File" /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)File" /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 个答案:

答案 0 :(得分:0)

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

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

然而,这并没有为许多人(包括我)解决问题,我怀疑那些确实有效,还有其他问题导致空队列空。

经过多次阅读,看来这是一个没有明显修复的缺陷。提出了几种解决方法。我正在运行整个周期的火车,评估和预测。这是对我有用的方法:

1)在训练时,我设置num_epochs = None。这会无限次地循环数据,如果文档正确,每个示例每个时期只显示一次。我确实进行了检查以确认这一点,但我的数据集太大,无法保证文档是正确的。也就是说,我的模型并没有过度适应。在准确性方面,训练,测试和验证都非常接近。

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

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

3)在预测时,我再次使用与eval相同的技术,除了我选择的批量大小和列车步数与预测记录的数量完全相同。由于没有渐变支撑,因此在队列跑步者杀死我的工作之前,预测的速度足够快。

问题解决了。陪审团操纵。但是,它奏效了。绝望是聪明的母亲或类似的东西!