张量流数据集"预取"方法是否为我的数据添加维度?为什么?



下面是一个例子,这个函数用于将时间序列剪切到窗口中:

def window_dataset(tensor, window_size, batch_size=32,
shuffle_buffer=1000):
dataset = tf.data.Dataset.from_tensor_slices(tensor)
print(dataset.element_spec)
dataset = dataset.window(window_size + 1, shift=1, drop_remainder=True)
print(dataset.element_spec)
dataset = dataset.flat_map(lambda window: window.batch(window_size + 1))
print(dataset.element_spec)
dataset = dataset.shuffle(shuffle_buffer)
print(dataset.element_spec)
dataset = dataset.map(lambda window: (window[:-1], window[-1]))
print(dataset.element_spec)
dataset = dataset.batch(batch_size).prefetch(1)
print(dataset.element_spec)
return dataset

呼叫&输出:

list_a = np.random.random(184)
window_dataset(list_a, 30)
TensorSpec(shape=(), dtype=tf.float64, name=None)
DatasetSpec(TensorSpec(shape=(), dtype=tf.float64, name=None), TensorShape([]))
TensorSpec(shape=(None,), dtype=tf.float64, name=None)
TensorSpec(shape=(None,), dtype=tf.float64, name=None)
(TensorSpec(shape=(None,), dtype=tf.float64, name=None), TensorSpec(shape=(), dtype=tf.float64, name=None))
(TensorSpec(shape=(None, None), dtype=tf.float64, name=None), TensorSpec(shape=(None,), dtype=tf.float64, name=None))

数据集在预取后似乎多了一个秩,是吗?我没有找到任何医生来描述这种现象,如果有人能提供帮助,我将不胜感激。

============================================================更新时间:2021-03-25 12:28:16 UTC+0

我发现这是一个有点尴尬的误解,感谢@Lescurel指出了这一点。事实上,prefetch不会影响维度,batch会添加一个维度。修改示例如下:

def window_dataset(tensor, window_size, batch_size=32,
shuffle_buffer=1000):
dataset = tf.data.Dataset.from_tensor_slices(tensor)
print(dataset.element_spec)
dataset = dataset.window(window_size + 1, shift=1, drop_remainder=True)
print(dataset.element_spec)
dataset = dataset.flat_map(lambda window: window.batch(window_size + 1))
print(dataset.element_spec)
dataset = dataset.shuffle(shuffle_buffer)
print(dataset.element_spec)
dataset = dataset.map(lambda window: (window[:-1], window[-1]))
print(dataset.element_spec)
dataset = dataset.batch(batch_size)
print(dataset.element_spec)


dataset = dataset.prefetch(1)
print(dataset.element_spec)
return dataset

呼叫&输出:

list_a = np.random.random(184)
window_dataset(list_a, 30)
TensorSpec(shape=(), dtype=tf.float64, name=None)
DatasetSpec(TensorSpec(shape=(), dtype=tf.float64, name=None), TensorShape([]))
TensorSpec(shape=(None,), dtype=tf.float64, name=None)
TensorSpec(shape=(None,), dtype=tf.float64, name=None)
(TensorSpec(shape=(None,), dtype=tf.float64, name=None), TensorSpec(shape=(), dtype=tf.float64, name=None))
# after batch
(TensorSpec(shape=(None, None), dtype=tf.float64, name=None), TensorSpec(shape=(None,), dtype=tf.float64, name=None))
# after prefetch
(TensorSpec(shape=(None, None), dtype=tf.float64, name=None), TensorSpec(shape=(None,), dtype=tf.float64, name=None))

现在已经很清楚了。

prefetch允许在处理当前元素时准备后续元素。这通常以使用额外的内存来存储预取的元素为代价来提高延迟和吞吐量。

其中,由于batch是基于batch_size将数据集的连续元素组合成批。

它没有示例与批次的概念。examples.prefetch(2)将预取two elements (2 examples),而examples.batch(20).prefetch(2)将预取2 elements (2 batches, of 20 examples each)

有关更多详细信息,您可以参考tf.data.Dataset.的方法

相关内容

  • 没有找到相关文章

最新更新