首页 > 解决方案 > 当使用多个样本时,如何在 Keras 中使用多元时间序列预测

问题描述

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

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

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

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

标签: pythontensorflowkerastime-serieslstm

解决方案


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

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

注意:上面和机器学习中的“样本”是指独立的示例/观察,而不是测量的信号数据点(称为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)

推荐阅读