我想用非常长的数据序列(数千万个条目)为stride-1窗口提供模型。这类似于this线程中提出的目标,只是我的数据序列可能包含几个要开始的功能,因此最终的功能数量是n_features * window_size。即具有两个原始特征和窗口大小为3,这将意味着改变这个:
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
为:
[[1, 2, 3, 6, 7, 8], [2, 3, 4, 7, 8, 9], [3, 4, 5, 8, 9, 10]]
我试图使用map_fn或Dataset.map进行切片,应用于一系列索引(根据上述线程中的答案),如:
ti = tf.range(data.shape[0] - window_size)
train_dataset = tf.data.Dataset.from_tensor_slices((ti, labels))
def get_window(l, label):
wnd = tf.reshape(data_tensor[l:(l + window_size), :], (-1, window_size * n_features))
wnd = tf.squeeze(wnd)
return (wnd, label)
train_dataset = train_dataset.map(get_window)
train_dataset = train_dataset.batch(batch_size)
...
原则上这是有效的,但是训练非常慢,GPU利用率最低(1-5%,可能部分原因是映射是在CPU中完成的)。
当尝试对tf.map_fn做同样的事情时,图形构建变得非常冗长,具有巨大的内存利用率。
我尝试的另一个选项是在将其加载到Tensorflow之前提前转换所有数据。这样工作得更快(即使在考虑预处理时间时,我想知道为什么 - 它不应该与训练期间的映射操作相同?)但是在内存和存储方面效率非常低,因为数据变为window_size-fold更大。这对我的大型数据集来说是一个交易破坏者。 我想过将这些变形的膨胀数据集拆分成几个文件("超级批次")并按顺序浏览每个时代,但这似乎非常低效,我想知道是否有更好的方法来实现这个简单的转变。