将时间序列元素的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-js 格式

TensorFlow制作TFRecord文件方式的数据集的完整程序,最好标明怎么输入输出地址

Tensorflow1 和 Tensorflow2 中的批处理

自己的数据集:ValueError:无法将 NumPy 数组转换为张量(不支持的对象类型 int)

AI - TensorFlow - 示例:影评文本分类

使用 tensorflow 将数据集拆分为训练和测试