python - 当使用多个样本时,如何在 Keras 中使用多元时间序列预测
问题描述
正如标题所述,我正在做多元时间序列预测。我对这种情况有一些经验,并且能够在 TF Keras 中成功设置和训练一个工作模型。
但是,我不知道处理多个不相关的时间序列样本的“正确”方法。我有大约 8000 个独特的样本“块”,每个样本有 800 个时间步长到 30,000 个时间步长。当然,我不能将它们全部连接成一个时间序列,因为样本 2 的第一个点与样本 1 的最后一个点在时间上不相关。
因此,我的解决方案是将每个样本单独放入一个循环中(效率极低)。
我的新想法是我可以/应该用空的时间步长填充每个样本的开始= RNN的回顾量,然后将填充的样本连接成一个时间序列?这意味着第一个时间步将有一个大部分为 0 的回顾数据,这听起来像是我的问题的另一个“黑客”,而不是正确的方法。
解决方案
主要挑战是 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)
推荐阅读
- java - Java 词频按长度排序,然后按字母顺序排序
- javascript - 使用 AJAX 将数据从 Javascript 发送到 PHP 以更新现有的 Mysql 数据库
- swiftui - 有什么方法可以在 SwiftUI 中调用子视图的功能?
- javascript - 在循环中使用逻辑或运算符对数组进行排序
- javascript - 如何防止组件在位于组件外部的悬停事件上重新渲染?
- mongodb - 用户可以更改管理员权限
- java - 如何“同步”线程依次运行?
- discord.js - 如何检测何时提到机器人
- reactjs - react-i18next - 初始化后如何向 i18n 添加后端?
- ruby-on-rails - 覆盖设计控制器的 SessionsController#create 操作时如何设置标题?