关于 LSTM 模型中输入形状的困惑

时间:2021-02-24 15:21:48

标签: python tensorflow lstm

我正在尝试构建一个 LSTM 模型,该模型使用货币汇率的时间序列数据以及同一日期范围的情绪得分来预测第二天的汇率。现在我有 x_train 日期,它是一个熊猫数据框 The first column is the rate and second column is the score。 y_train 数据是只有汇率,偏移了一天的数据。数据为2016-01-01至2017-07-06。

所以 X_train 的形状为 (486,2),y_train 的形状为 (486,)。我按照一些教程将 X_train 重塑为 (486,1,2),输入形状为 (1,2),batch size 为 200,epoch 为 1000。我在这里有点困惑。

这是否意味着在每个epoch中,模型都会从索引1开始,将形状为(200,1,2)的数据放入LSTM进行训练,直到索引286?还是只是随机选择批次?如何确保当前批次与下一个批次相关?

另一个问题是关于单位数,这是另一个参数。我将它设置为 4,我认为它是每个时间步的输出和下一个密集层的输入,输出大小为 1,这是正确的吗?所以这是关于预测过程,对吗?

1 个答案:

答案 0 :(得分:0)

如果您拥有的训练数据量为 486 个时间序列点,您可能希望获得更多数据。话虽如此,通常如何进行时间序列预测是您选择一个小于您的数据集的窗口大小并说“如果我在这个 RNN 中放入最后 N 天的数据,它可以预测第 N+1 天吗? ”。然后遍历整个时间序列,为 X 选择 N 个大小的时间序列夹头并将第 N+1 个设置为所需的预测 (y)。

示例

import numpy as np
import pandas as pd
import tensorflow as tf

# fake data.
cny = 8.0 * np.abs(np.random.normal(size=486))
compound = np.random.normal(0, 0.1, size=486)

# make a pandas data-frame
df = pd.DataFrame({'cny': cny, 'compound': compound})

# shift `cny` by one into the future and set that as the label
df['next_cny'] = df['cny'].shift(-1)

# drop the nan that shifting creates
df = df.dropna()

# check the data
print(df.head())

#          cny  compound   next_cny
# 0  10.827493 -0.127950   0.923700
# 1   0.923700  0.039958  12.787946
# 2  12.787946  0.024724  15.817607
# 3  15.817607 -0.065448   5.866374
# 4   5.866374  0.143691   8.864016

# choose a window
window = 16  # <= you can make this whatever you want
num_windows = len(df) - window + 1

# make slices of data
Xs, ys = [], []

for w in range(num_windows):
    current_slice = df.iloc[w:w+window]
    X = current_slice[['cny', 'compound']].values
    y = current_slice['next_cny'].values[-1]
    Xs.append(X)
    ys.append(y)

X = np.stack(Xs)
y = np.stack(ys)

# check the shape
print(X.shape)
print(y.shape)

# (470, 16, 2)
# (470,)

# make a network
x_in = tf.keras.Input([16, 2])
x, *_ = tf.keras.layers.LSTM(128, return_state=True)(x_in)
x_out = tf.keras.layers.Dense(1)(x)

# create model
model = tf.keras.Model(x_in, x_out)

# load data into tensorflow
ds = tf.data.Dataset.from_tensor_slices((X, y))
ds = ds.shuffle(1 << 6).batch(32)

# compile the model
model.compile(optimizer='Adam', loss=tf.keras.losses.MSE)

# train
model.fit(ds, epochs=10)

# Epoch 1/10
# 15/15 [==============================] - 2s 12ms/step - loss: 40.0351
# Epoch 2/10
# 15/15 [==============================] - 0s 10ms/step - loss: 21.3910
# ...

在预测时间序列数据时要注意的一件事是,由于数据的有序性,模型可以从未来数据中学习模式,并使用它们来预测过去。这是关于 cross validated 的一篇很好的文章,解释了如何将时间序列数据拆分为训练/测试集。这是 scikit-learn 中的 time-series splitter