如何使用 tf.data 创建多元时间序列数据集?
How to create a multivariate timeseries dataset with tf.data?
我正在尝试为我的 LSTM 模型创建一个输入管道。我正在使用 tf.data.Dataset.from_generator
API 来做到这一点。在 guide 之后,我当前的最小示例如下所示:
class generator:
def __init__(self, n=5):
self.n = n
def __call__(self):
for i in range(self.n):
yield (i, 10*i)
dataset = tf.data.Dataset.from_generator(generator(),
output_signature=(tf.TensorSpec(shape=(), dtype=tf.uint16), tf.TensorSpec(shape=(), dtype=tf.int32)))
window_size = 3
windows = dataset.window(window_size, shift=1)
def sub_to_batch(sub):
return sub.batch(window_size, drop_remainder=True)
final_dset = windows.flat_map(sub_to_batch)
print(list(final_dset.as_numpy_iterator()))
错误信息
TypeError: tf__sub_to_batch() takes 1 positional argument but 2 were given
只有在生成器中使用多个功能时才会出现此问题(例如更改以下行)。
yield (i)
dataset = tf.data.Dataset.from_generator(generator(),
output_signature=(tf.TensorSpec(shape=(), dtype=tf.uint16)))
在只有 1 个功能的版本中,输出看起来像 shape=(3, 3, 1)
[ [ [0], [1], [2] ],
[ [1], [2], [3] ],
[ [2], [3], [4] ] ]
我基本上尝试实现单个功能的压缩,以便我得到 shape=(3, 3, 2)
:
[ [ [0, 0], [1, 10], [2, 20] ],
[ [1, 10], [2, 20], [3, 30] ],
[ [2, 20], [3, 30], [4, 40] ] ]
如何做到这一点?
您可以尝试以下操作;但是,我不确定它的效率如何:
import tensorflow as tf
class generator:
def __init__(self, n=7):
self.n = n
def __call__(self):
for i in range(self.n):
yield (i, 10*i)
dataset = tf.data.Dataset.from_generator(generator(),
output_signature=(tf.TensorSpec(shape=(), dtype=tf.int32), tf.TensorSpec(shape=(), dtype=tf.int32)))
window_size = 5
windows = dataset.window(window_size, shift=1)
def stack(x, y):
x = tf.expand_dims(x, axis=1)
y = tf.expand_dims(y, axis=1)
result = tf.concat((x, y), axis=1)
ta = tf.TensorArray(tf.int32, size=0, dynamic_size=True)
for w in tf.range(3):
ta = ta.write(w, result[w: w + 3])
return ta.stack()
def sub_to_batch(sub1, sub2):
sub1 = sub1.batch(5, drop_remainder=True)
sub2 = sub2.batch(5, drop_remainder=True)
return tf.data.Dataset.zip((sub1, sub2)).map(stack)
final_dset = windows.flat_map(sub_to_batch)
for s in final_dset.take(1):
print(s)
tf.Tensor(
[[[ 0 0]
[ 1 10]
[ 2 20]]
[[ 1 10]
[ 2 20]
[ 3 30]]
[[ 2 20]
[ 3 30]
[ 4 40]]], shape=(3, 3, 2), dtype=int32)
如果您愿意,您也可以对索引进行硬编码,结果将是相同的:
def stack(x, y):
x = tf.expand_dims(x, axis=1)
y = tf.expand_dims(y, axis=1)
result = tf.concat((x, y), axis=1)
return tf.stack([result[0: 3], result[1: 4], result[2: 5]])
我正在尝试为我的 LSTM 模型创建一个输入管道。我正在使用 tf.data.Dataset.from_generator
API 来做到这一点。在 guide 之后,我当前的最小示例如下所示:
class generator:
def __init__(self, n=5):
self.n = n
def __call__(self):
for i in range(self.n):
yield (i, 10*i)
dataset = tf.data.Dataset.from_generator(generator(),
output_signature=(tf.TensorSpec(shape=(), dtype=tf.uint16), tf.TensorSpec(shape=(), dtype=tf.int32)))
window_size = 3
windows = dataset.window(window_size, shift=1)
def sub_to_batch(sub):
return sub.batch(window_size, drop_remainder=True)
final_dset = windows.flat_map(sub_to_batch)
print(list(final_dset.as_numpy_iterator()))
错误信息
TypeError: tf__sub_to_batch() takes 1 positional argument but 2 were given
只有在生成器中使用多个功能时才会出现此问题(例如更改以下行)。
yield (i)
dataset = tf.data.Dataset.from_generator(generator(),
output_signature=(tf.TensorSpec(shape=(), dtype=tf.uint16)))
在只有 1 个功能的版本中,输出看起来像 shape=(3, 3, 1)
[ [ [0], [1], [2] ],
[ [1], [2], [3] ],
[ [2], [3], [4] ] ]
我基本上尝试实现单个功能的压缩,以便我得到 shape=(3, 3, 2)
:
[ [ [0, 0], [1, 10], [2, 20] ],
[ [1, 10], [2, 20], [3, 30] ],
[ [2, 20], [3, 30], [4, 40] ] ]
如何做到这一点?
您可以尝试以下操作;但是,我不确定它的效率如何:
import tensorflow as tf
class generator:
def __init__(self, n=7):
self.n = n
def __call__(self):
for i in range(self.n):
yield (i, 10*i)
dataset = tf.data.Dataset.from_generator(generator(),
output_signature=(tf.TensorSpec(shape=(), dtype=tf.int32), tf.TensorSpec(shape=(), dtype=tf.int32)))
window_size = 5
windows = dataset.window(window_size, shift=1)
def stack(x, y):
x = tf.expand_dims(x, axis=1)
y = tf.expand_dims(y, axis=1)
result = tf.concat((x, y), axis=1)
ta = tf.TensorArray(tf.int32, size=0, dynamic_size=True)
for w in tf.range(3):
ta = ta.write(w, result[w: w + 3])
return ta.stack()
def sub_to_batch(sub1, sub2):
sub1 = sub1.batch(5, drop_remainder=True)
sub2 = sub2.batch(5, drop_remainder=True)
return tf.data.Dataset.zip((sub1, sub2)).map(stack)
final_dset = windows.flat_map(sub_to_batch)
for s in final_dset.take(1):
print(s)
tf.Tensor(
[[[ 0 0]
[ 1 10]
[ 2 20]]
[[ 1 10]
[ 2 20]
[ 3 30]]
[[ 2 20]
[ 3 30]
[ 4 40]]], shape=(3, 3, 2), dtype=int32)
如果您愿意,您也可以对索引进行硬编码,结果将是相同的:
def stack(x, y):
x = tf.expand_dims(x, axis=1)
y = tf.expand_dims(y, axis=1)
result = tf.concat((x, y), axis=1)
return tf.stack([result[0: 3], result[1: 4], result[2: 5]])