使用tf.estimator和tf.data时序列结束错误

时间:2018-05-24 16:50:02

标签: tensorflow tensorflow-datasets

我正在使用tf.estimator.train_and_evaluatetf.data.Dataset将数据提供给估算工具:

输入数据功能:

    def data_fn(data_dict, batch_size, mode, num_epochs=10):
        dataset = {}
        if mode == tf.estimator.ModeKeys.TRAIN:
            dataset = tf.data.Dataset.from_tensor_slices(data_dict['train_data'].astype(np.float32))
            dataset = dataset.cache()
            dataset = dataset.shuffle(buffer_size= batch_size * 10).repeat(num_epochs).batch(batch_size)
        else:
            dataset = tf.data.Dataset.from_tensor_slices(data_dict['valid_data'].astype(np.float32))
            dataset = dataset.cache()
            dataset = dataset.batch(batch_size)

        iterator = dataset.make_one_shot_iterator()
        next_element = iterator.get_next()

    return next_element

训练功能:

def train_model(data):
    tf.logging.set_verbosity(tf.logging.INFO)
    config = tf.ConfigProto(allow_soft_placement=True,
                            log_device_placement=False)
    config.gpu_options.allow_growth = True
    run_config = tf.contrib.learn.RunConfig(
        save_checkpoints_steps=10,
        keep_checkpoint_max=10,
        session_config=config
    )

    train_input = lambda: data_fn(data, 100, tf.estimator.ModeKeys.TRAIN, num_epochs=1)
    eval_input = lambda: data_fn(data, 1000, tf.estimator.ModeKeys.EVAL)
    estimator = tf.estimator.Estimator(model_fn=model_fn, params=hps, config=run_config)
    train_spec = tf.estimator.TrainSpec(train_input, max_steps=100)
    eval_spec = tf.estimator.EvalSpec(eval_input,
                                      steps=None,
                                      throttle_secs = 30)

    tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

培训很顺利,但在评估方面我得到了这个错误:

OutOfRangeError (see above for traceback): End of sequence 

如果我不在评估数据集上使用Dataset.batch(通过省略dataset[name] = dataset[name].batch(batch_size)中的行data_fn),我会得到相同的错误但是经过更长的时间后。

如果我不批量处理数据并使用steps=1进行评估,我只能避免此错误,但这会对整个数据集执行评估吗?

我不明白导致此错误的原因,因为文档显示我也应该能够对批次进行评估。

注意:在数据批次上使用tf.estimator.evaluate时会出现相同的错误。

1 个答案:

答案 0 :(得分:0)

我将此问题发布为github问题,以下是Tensorflow团队的回复:

https://github.com/tensorflow/tensorflow/issues/19541

从“xiejw”复制以获得完整性:

  

如果我理解正确,这个问题是“一旦给估算器一个带有数据集的input_fn,评估过程就会出现OutOfRangeError错误。”

     

Estimator实际上可以正确处理这个问题。但是,已知的常见根本原因是model_fn中定义的度量标准有bug。我们需要首先排除这一部分。

     

@mrezak如果可能的话,你能展示一下关于model_fn的代码吗?或者,如果您有一个可重现性最小的脚本,那将非常有用。 - 提前致谢。

     

常见问题是:tensorflow中的metric应返回两个Ops:update_op和value_op。 Estimator为输入源中的每批数据调用update_op,一旦耗尽,就调用value_op来获取度量值。这里的value_op应该依赖于只读变量的依赖。

     

许多model_fn将value_op的依赖项与输入管道放在一起,因此,estimator.evaluate将再次触发输入管道,这会导致OutOfRangeError错误

问题确实是我如何定义eval_metric中的model_fn。在我的实际代码中,我要优化的总损失由多个损失(重建+ L2 + KL)组成,在评估部分我想得到重建损失(在验证数据上),这取决于输入数据管道。我的实际重建成本比MSE更复杂(也没有其他的tf.metric函数),使用tf.metric基本函数不能直接实现。

这是解决问题的“xiejw”的建议:

my_total_loss =  ... # the loss you care. Pay attention to how you reduce the loss. 
eval_metric_ops = {'total_loss: tf.metrics.mean(my_total_loss)}