如何在第一个时期正确地缓存数据(Tensorflow,数据集)?

Mao*_*hen 3 tensorflow tensorflow-datasets

我正在尝试将cache转换用于dataset。这是我当前的代码(简体):

dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=1)
dataset = dataset.apply(tf.contrib.data.shuffle_and_repeat(buffer_size=5000, count=1))
dataset = dataset.map(_parser_a, num_parallel_calls=12)
dataset = dataset.padded_batch(
    20, 
    padded_shapes=padded_shapes,
    padding_values=padding_values
)
dataset = dataset.prefetch(buffer_size=1)
dataset = dataset.cache()
Run Code Online (Sandbox Code Playgroud)

在第一个时期之后,我收到以下错误消息:

调用迭代器没有完全读取我们尝试缓存的数据集。为了避免序列的意外截断,将丢弃当前的[部分缓存]序列。如果您的序列与相似,则会发生这种情况dataset.cache().take(k).repeat()。相反,请交换订单(即dataset.take(k).cache().repeat()

然后,代码继续进行,仍然从硬盘驱动器而不是从缓存读取数据。那么,应该在哪里放置dataset.cache()以避免该错误?谢谢。

mrr*_*rry 6

Dataset.cache()转换的实现非常简单:在您第一次完全迭代时,它会构建一个通过它的元素列表,并且在后续尝试对其进行迭代时,它将返回该列表中的元素。如果第一遍仅对数据执行部分遍历,则列表不完整,并且TensorFlow不会尝试使用缓存的数据,因为它不知道是否需要其余元素,并且通常可能需要重新处理所有前面的元素以计算其余元素。

通过修改程序以使用整个数据集,并对其进行迭代直到tf.errors.OutOfRangeError引发它,缓存将具有数据集中元素的完整列表,并将在所有后续迭代中使用。

  • 没错:如果将* cache()*放在*随机后的map()之后,那么它将缓存第一组随机决策。将“ cache()”放在“ *”之前,随机的“ map()”应该可以正常工作。(请注意,这意味着您可能希望将map()分为两部分,确定性部分在cache()之前,随机部分在cache()之后。) (2认同)
  • @SamueleCornell 是的,现在文档中已说明。检查此[链接](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#cache)。它说“缓存将在数据集的每次迭代期间产生完全相同的元素。如果您希望随机化迭代顺序,请确保在调用缓存之后**调用shuffle。” (2认同)