【问题标题】:Batching in tf.data.dataset in time-series analysis时间序列分析中的 tf.data.dataset 中的批处理
【发布时间】:2020-12-11 11:41:35
【问题描述】:

我正在考虑为时间序列 LSTM 模型创建管道。我有两个输入源,我们称它们为 series1series2

我通过调用from.tensor.slices来初始化tf.data对象:

ds = tf.data.Dataset.from_tensor_slices((series1, series2))

我将它们进一步批处理到设置窗口大小的窗口中并在窗口之间移动 1:

ds = ds.window(window_size + 1, shift=1, drop_remainder=True)

在这一点上,我想尝试一下它们是如何组合在一起的。我想产生一个像下面这样的输入作为例子:

series1 = [1, 2, 3, 4, 5]
series2 = [100, 200, 300, 400, 500]

batch 1: [1, 2, 100, 200]
batch 2: [2, 3, 200, 300]
batch 3: [3, 4, 300, 400]

所以每个批次将返回 series1 的两个元素,然后是 series2 的两个元素。这段代码 sn-p 单独批处理它们:

ds = ds.map(lambda s1, s2: (s1.batch(window_size + 1), s2.batch(window_size + 1))

因为它返回两个数据集对象的映射。由于它们是对象,它们不可下标,所以这也不起作用:

ds = ds.map(lambda s1, s2: (s1[:2], s2[:2]))

我确信解决方案是使用 .apply 和自定义 lambda 函数。非常感谢任何帮助。

编辑

我也在考虑制作一个代表该系列下一个元素的标签。例如,批次将产生以下内容:

batch 1: (tf.tensor([1, 2, 100, 200]), tf.tensor([3]))
batch 2: (tf.tensor([2, 3, 200, 300]), tf.tensor([4]))
batch 3: (tf.tensor([3, 4, 300, 400]), tf.tensor([5]))

其中[3][4][5] 表示要预测的series1 的下一个元素。

【问题讨论】:

    标签: python tensorflow keras tensorflow2.0 tensorflow-datasets


    【解决方案1】:

    我认为这是你缺少的那一行:

    ds = ds.batch(2).map(lambda x, y: (tf.concat([x, y], axis=0)))
    

    完整示例:

    import tensorflow as tf
    
    series1 = tf.range(1, 16)
    series2 = tf.range(100, 1600, 100)
    
    ds = tf.data.Dataset.from_tensor_slices((series1, series2))
    
    ds = ds.batch(2).map(lambda x, y: (tf.concat([x, y], axis=0)))
    
    for row in ds:
        print(row)
    
    tf.Tensor([  1   2 100 200], shape=(4,), dtype=int32)
    tf.Tensor([  3   4 300 400], shape=(4,), dtype=int32)
    tf.Tensor([  5   6 500 600], shape=(4,), dtype=int32)
    tf.Tensor([  7   8 700 800], shape=(4,), dtype=int32)
    tf.Tensor([   9   10  900 1000], shape=(4,), dtype=int32)
    tf.Tensor([  11   12 1100 1200], shape=(4,), dtype=int32)
    tf.Tensor([  13   14 1300 1400], shape=(4,), dtype=int32)
    

    【讨论】:

    • 在正确的轨道上。不幸的是,ds.windowmethod 是必需的,因为我希望批次之间有重叠(在实际示例中它们比 2 长得多)。其次,我还想将系列 1 的另一个元素作为标签返回。例如,我想返回与系列 1 的下一个元素对应的 tf.tensor[1, 2, 100, 200], tf.tensor[3] 之类的东西作为预测标签。如果您熟悉时间序列建模,您就会明白我的意思。
    • 您的示例甚至不包含标签,这很简单
    【解决方案2】:

    解决方案是将两个数据集分别窗口化,.zip() 将它们放在一起,然后 .concat() 包含标签的元素。

    ds = tf.data.Dataset.from_tensor_slices(series1)
    ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
    ds = ds.flat_map(lambda window: window.batch(window_size + 1))
    ds = ds.map(lambda window: (window[:-1], window[-1]))
    
    ds2 = tf.data.Dataset.from_tensor_slices(series2)
    ds2 = ds2.window(window_size, shift=1, drop_remainder=True)
    ds2 = ds2.flat_map(lambda window: window.batch(window_size))
    
    ds = tf.data.Dataset.zip((ds, ds2))
    ds = ds.map(lambda i, j: (tf.concat([i[0], j], axis=0), i[-1]))
    

    返回:

    (<tf.Tensor: shape=(7,), dtype=int32, numpy=array([  1,   2,   3, 100, 200, 300])>, <tf.Tensor: shape=(), dtype=int32, numpy=4>)
    (<tf.Tensor: shape=(7,), dtype=int32, numpy=array([  2,   3,   4, 200, 300, 400])>, <tf.Tensor: shape=(), dtype=int32, numpy=5>)
    (<tf.Tensor: shape=(7,), dtype=int32, numpy=array([  3,   4,   5, 300, 400, 500])>, <tf.Tensor: shape=(), dtype=int32, numpy=6>)
    

    【讨论】:

      【解决方案3】:

      这是我在处理时间序列数据时的解决方案。

      dataset = tf.data.Dataset.from_tensor_slices(series)
      dataset = dataset.window(window_size + 1, shift=1, drop_remainder=True)
      dataset = dataset.flat_map(lambda window: window.batch(window_size + 1))
      dataset = dataset.shuffle(shuffle_buffer).map(lambda window: (window[:-1], window[-1]))
      dataset = dataset.batch(batch_size).prefetch(1)
      

      以下行对于将窗口拆分为 xs 和 ys 很重要。

      dataset.shuffle(shuffle_buffer).map(lambda window: (window[:-1], window[-1]))
      

      虽然使用shuffle并不重要,但只能使用map函数将窗口分割成xs和ys。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-20
        • 2014-07-10
        • 1970-01-01
        • 2019-10-07
        • 1970-01-01
        • 2017-07-16
        • 2017-05-02
        • 1970-01-01
        相关资源
        最近更新 更多