为什么这个 TensorFlow 代码在测试用例中表现不同?

3

我有一个函数(下面是foo),在直接运行和在tf.test.TestCase中运行时表现不同。

该代码应该创建一个包含元素[1..5]的数据集并对其进行随机排序。然后重复3次:从数据中创建一个迭代器,并使用它打印出这5个元素。

当单独运行时,输出的所有列表都会被随机排序,例如:

[4, 0, 3, 2, 1]
[0, 2, 1, 3, 4]
[2, 3, 4, 0, 1]

但是当在测试案例中运行时,它们始终相同,即使在不同的运行之间也是如此:
[0, 4, 2, 3, 1]
[0, 4, 2, 3, 1]
[0, 4, 2, 3, 1]

我想这可能与测试用例如何处理随机种子有关,但我在TensorFlow文档中没有找到相关内容。感谢您的任何帮助!


代码:

import tensorflow as tf

def foo():
    sess = tf.Session()
    dataset = tf.data.Dataset.range(5)
    dataset = dataset.shuffle(5, reshuffle_each_iteration=False)

    for _ in range(3):
        data_iter = dataset.make_one_shot_iterator()
        next_item = data_iter.get_next()
        with sess.as_default():
            data_new = [next_item.eval() for _ in range(5)]
        print(data_new)


class DatasetTest(tf.test.TestCase):
    def testDataset(self):
        foo()

if __name__ == '__main__':
    foo()
    tf.test.main()

我正在使用Python 3.6和TensorFlow 1.4运行它,不需要其他模块。

1个回答

2

我认为你是正确的;tf.test.TestCase已被设置为使用固定的种子。

class TensorFlowTestCase(googletest.TestCase):
# ...
def setUp(self):
  self._ClearCachedSession()
  random.seed(random_seed.DEFAULT_GRAPH_SEED)
  np.random.seed(random_seed.DEFAULT_GRAPH_SEED)
  ops.reset_default_graph()
  ops.get_default_graph().seed = random_seed.DEFAULT_GRAPH_SEED

请参见tensorflow/tensorflow/python/framework/random_seed.py中的此行代码,其中DEFAULT_GRAPH_SEED = 87654321


谢谢!如果我覆盖setUp,行为看起来是一致的。感觉不太好,但我想单元测试中的不确定性通常是不被鼓励的吧? - Bridgo
1
我认为我们期望单元测试具有确定性结果。请参见https://martinfowler.com/articles/nonDeterminism.html。 - greeness
那篇文章提出了一个很好的观点。我仍然想知道是否存在有效的情况?例如,我想测试我的训练/测试数据在 epochs 之间混洗时保持分离。使用 tf.data.Dataset.shuffle 在拆分之前进行幼稚的尝试(我之前也有过)可能会导致它们很容易混合(例如,如果像上面的 foo 中创建了一个新的迭代器)。 - Bridgo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接