使用多个样本时,如何使用 Keras 进行多变量时间序列预测

Gra*_*ien 3 python time-series lstm keras tensorflow

正如标题所述,我正在做多元时间序列预测。我对这种情况有一些经验,并且能够在 TF Keras 中成功设置和训练一个工作模型。

但是,我不知道处理多个不相关的时间序列样本的“正确”方法。我有大约 8000 个独特的样本“块”,每个样本有 800 个时间步到 30,000 个时间步。当然,我无法将它们全部连接成一个时间序列,因为样本 2 的第一个点与样本 1 的最后一个点在时间上没有关系。

因此,我的解决方案是将每个样本单独放入一个循环中(效率极低)。

我的新想法是可以/应该我用空的时间步长填充每个样本的开始= RNN 的回顾量,然后将填充的样本连接成一个时间序列?这意味着第一个时间步将有一个主要为 0 的回溯数据,这听起来像是针对我的问题的另一个“黑客”,而不是正确的方法。

Ove*_*gon 5

主要挑战是 800 对 30,000 时间步长,但没有什么是你做不到的。

  • 模型设计:将序列分组为块——例如,800 到 900 时间步长的 30 个序列,填充,然后 900 到 1000 的 60 个序列等等——不必是连续的(即下一个可以是 1200-到-1500)
  • 输入形状(samples, timesteps, channels)- 或等效地,(sequences, timesteps, features)
  • Conv1D和/或 RNNs - 例如GRU, LSTM。每个都可以处理可变的时间步长
  • 串联不要这样做。如果您的每个序列都是独立的,那么每个序列都必须沿 Keras 中的第 0 维 -批次样本维度提供。如果它们是相关的,例如多元时间序列,就像信号中的许多通道一样 - 然后沿着channels维度(dim 2)馈送它们。但永远不要沿时间序列维度串联,因为它意味着不存在的因果连续性。
  • 有状态的 RNN:可以帮助处理长序列 - 有关它们如何在这里工作的信息
  • RNN 能力:对于长序列是有限的,即使对于 LSTM 来说,800 已经处于危险区域;我建议通过自动编码器或带有strides > 1输入的CNN 进行降维,然后将它们的输出提供给 RNN。
  • RNN 训练:很难。训练时间长、超参数敏感性、梯度消失——但是,通过适当的正则化,它们可以很强大。更多信息在这里
  • 零填充:之前/之后/两者- 有争议,可以阅读它,但可能要远离“两者”,因为在一个地方学习忽略填充更容易;我个人使用“之前”
  • RNN 变体:尽可能使用CuDNNLSTMCuDNNGRU,因为它们快 10 倍

注意:上面的“样本”在机器学习中是指独立的示例/观察,而不是测量的信号数据点(称为timesteps)。


以下是适合时间序列的模型的最小代码:

from tensorflow.keras.layers import Input, Conv1D, LSTM, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
import numpy as np

def make_data(batch_shape):  # dummy data
    return (np.random.randn(*batch_shape),
            np.random.randint(0, 2, (batch_shape[0], 1)))

def make_model(batch_shape):  # example model
    ipt = Input(batch_shape=batch_shape)
    x   = Conv1D(filters=16, kernel_size=10, strides=2, padding='valid')(ipt)
    x   = LSTM(units=16)(x)
    out = Dense(1, activation='sigmoid')(x)  # assuming binary classification

    model = Model(ipt, out)
    model.compile(Adam(lr=1e-3), 'binary_crossentropy')
    return model

batch_shape = (32, 100, 16)  # 32 samples, 100 timesteps, 16 channels
x, y  = make_data(batch_shape)
model = make_model(batch_shape)

model.train_on_batch(x, y)
Run Code Online (Sandbox Code Playgroud)