首页 文章

不能使用估算器数据集并训练不到一个纪元

提问于
浏览
7

TensorFlow 1.4将TF数据集移动到核心( tf.data.Dataset ),doc / tutorial建议使用 tf.estimator 来训练模型 .

但是,正如在this page结尾处所建议的那样,必须在 input_fn 函数内实例化数据集对象及其迭代器 . 这意味着每次调用 estimator.train(input_fn, steps) 时,数据集的迭代都将重新开始 . 因此,调用步骤<在纪元中的样本数量,将导致在数据集的子集上训练模型 .

因此我的问题 . 是否可以使用Estimator Dataset实现类似的功能:

for i in range(num_epochs):
    # Train for some steps
    estimator.train(input_fn=train_input_fn, steps=valid_freq)

    validation_iterator.
    # Evaluate on the validation set (steps=None, we evaluate on the full validation set)
    estimator.evaluate(input_fn=valid_input_fn)

没有开始训练样本迭代从每次调用 estimator.train(input_fn=train_input_fn, steps=valid_freq)

例如,与here不同,在 input_fn 之外实例化数据集及其迭代器?我尝试过但它不起作用,因为输入(来自数据集迭代器)和模型(来自估算器 model_fn )不是同一个图的一部分 .

谢谢

相关github问题:https://github.com/tensorflow/tensorflow/issues/14283

2 回答

  • 0

    我不知道如何使训练在 estimator.train() 的运行中保持一致 .

    但是,你可以做的是确保你构建 train_input_fn ,使其足够随机以获得相同的效果 .


    例如,假设您有一个值为 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 的数据集,并且您只能在每次调用 estimator.train 时训练一半数据集 .
    如果你没有足够好地洗牌,你将继续训练 Value [0, 1, 2, 3, 4]

    train_size = 10
    dataset = tf.data.Dataset.range(train_size)
    x = dataset.make_one_shot_iterator().get_next()
    
    sess = tf.Session()
    for i in range(train_size // 2):
        print(sess.run(x))
    

    但是,如果使用 buffer_size 调用tf.data.Dataset.shuffle()至少与数据集一样大,则会获得随机值 . 多次调用 estimator.train 相当于用多个纪元调用它一次 .

    train_size = 10
    dataset = tf.data.Dataset.range(train_size)
    dataset = dataset.shuffle(buffer_size=train_size)
    x = dataset.make_one_shot_iterator().get_next()
    
    sess = tf.Session()
    for i in range(train_size // 2):
        print(sess.run(x))
    

    我写了另一个答案来解释 buffer_size here的重要性 .

  • 1

    您可以从input_fn返回 dataset . 就像是:

    def input_fn():
      dataset = ...
      return dataset
    

    要在不停止培训过程的情况下运行评估,您可以使用tf.contrib.estimator.InMemoryEvaluatorHook

相关问题