将时间序列元素的Tensorflow数据集转换为窗口序列的数据集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将时间序列元素的Tensorflow数据集转换为窗口序列的数据集相关的知识,希望对你有一定的参考价值。
我有一个tf.data.Dataset(r1.4),其元素代表一个时间序列。例如(换行符分隔元素):
1
2
3
4
5
6
7
8
9
现在我想对它运行一个窗口操作,这样我就可以得到一个长度为WINDOW SIZE的子序列数据集,用于训练RNN。例如,对于WINDOW SIZE = 4:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
我能找到的最接近的数据集操作是tf.contrib.data.group_by_window,但不知道如何将其应用于此用例。 另一种方法是使用tf.contrib.data.batch_and_drop_remainder,但它会将元素划分为桶,并且不会包含所有子序列。 我想到的第三个选项是创建WINDOW_SIZE迭代器,并单独运行它们,使它们指向连续的元素,然后开始按顺序使用它们。但是,这看起来非常直观。
答案
在TensorFlow 2.0中,Dataset
类现在有一个window()
方法。你可以像这样使用它:
import tensorflow as tf
dataset = tf.data.Dataset.from_tensor_slices(tf.range(10))
dataset = dataset.window(5, shift=1, drop_remainder=True)
for window in dataset:
print([elem.numpy() for elem in window])
它将输出:
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
另一答案
我在类似的情况下发现自己,并且我以这种方式解决了(我在每个步骤中的注释数据集值中写道,以使其足够清晰):
length = 12
components = np.array([[i] for i in range(length)], dtype=np.int64)
# components = np.arange(6 * 4, dtype=np.int64).reshape((-1, 4))
dataset = dataset_ops.Dataset.from_tensor_slices(components)
window_size = 4
# window consecutive elements with batch
dataset = dataset.apply(tf.contrib.data.batch_and_drop_remainder(window_size))
# [[0][1][2][3]]
# [[4][5][6][7]]
# [[8][9][10][11]]
# Skip first row and duplicate all rows, this allows the creation of overlapping window
dataset1 = dataset.apply(tf.contrib.data.group_by_window(lambda x: 0, lambda k, d: d.repeat(2), window_size=1)).skip(1)
# [[0][1][2][3]]
# [[4][5][6][7]]
# [[4][5][6][7]]
# [[8][9][10][11]]
# [[8][9][10][11]]
# Use batch to merge duplicate rows into a single row with both value from window(i) and window(i+1)
dataset1 = dataset1.apply(tf.contrib.data.batch_and_drop_remainder(2))
# [ [[0][1][2][3]] [[4][5][6][7]] ]
# [ [[4][5][6][7]] [[8][9][10][11]] ]
# filter with slice only useful values for overlapping windows
dataset1 = dataset1.map(lambda x: filter_overlapping_values(x, window_size))
# [[2][3][4][5]]
# [[6][7][8][9]]
# Now insert overlapping window into the dataset at the right position
dataset = tf.data.Dataset.zip((dataset, dataset1))
# x0: [[0][1][2][3]] x1: [[2][3][4][5]]
# x0: [[4][5][6][7]] x1: [[6][7][8][9]]
# Flat the dataset with original window and the dataset with overlapping window into a single dataset and flat it
dataset = dataset.flat_map(lambda x0, x1: tf.data.Dataset.from_tensors(x0).concatenate(tf.data.Dataset.from_tensors(x1)))
# [[0][1][2][3]]
# [[2][3][4][5]]
# [[4][5][6][7]]
# [[6][7][8][9]]
在最后一步中,您需要将重叠窗口合并为:
def filter_overlapping_values(x, window_size):
s1 = tf.slice(x[0], [window_size//2, 0], [-1, -1])
s2 = tf.slice(x[1], [0, 0], [window_size//2, -1])
return tf.concat((s1, s2), axis=0)
这种方法只适用于window_size
以上是关于将时间序列元素的Tensorflow数据集转换为窗口序列的数据集的主要内容,如果未能解决你的问题,请参考以下文章
TensorFlow制作TFRecord文件方式的数据集的完整程序,最好标明怎么输入输出地址
Tensorflow1 和 Tensorflow2 中的批处理