如何使用功能 api 构建 lstm?

数据挖掘 Python 喀拉斯 lstm
2022-03-12 16:19:11

我有一个时间序列预测问题,数据集有 4 个变量。

我的数据集如下:

import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
df.columns=['var1','var2','var3','var4']

时间戳是我原始数据帧的索引,我只按排序顺序取值。

var1是我要预测的目标变量。我还需要输入 3 次滞后,所以我通过以下函数准备数据集:

# convert series to supervised learning
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = pd.DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = pd.concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg

#take the 3 lags for each row
reframed = series_to_supervised(df,3, 1)
train_X=reframed.drop(['var1(t)'],axis=1)
train_y=reframed[['var1(t)']]

# design network
model = Sequential()
model.add(LSTM(20, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')

所以这里的形状将是(97, 16)97 是行数,因为前三个时间步不会有 3 个滞后,而 16 是具有 3 个滞后加上当前时间戳的总列。

现在在我的例子中, 的值var1(t)也受var2(t), var3(t),的影响var4(t)所以我的数据训练形状将是

   train_X shape  (97, 15)
   train_y shape  (97, 1)

现在的问题是如何将其重塑为[samples, timesteps, features]. 因为我只能在删除var2(t),时才能做到这一点var3(t)var4(t)然后我可以将其重塑为 [97,3,4] 但在我的情况下,我还想包括当前时间戳的剩余变量。

所以后来我发现我可以使用 keras 功能 API 来克服这个问题。

我使用 keras 功能 API 创建了模型,但张量的形状有问题。

def createFunctionalKerasLSTM():
    visible = Input(shape=(train_X.shape[0],train_X.shape[1]))
    hidden1 = LSTM(20)(visible)
    hidden2 = Dense(10, activation='relu')(hidden1)
    output = Dense(1, activation='sigmoid')(hidden2)
    model = Model(inputs=visible, outputs=output)
    model.compile(loss='mean_absolute_error', optimizer='adam', metrics=['mean_squared_error'])
    return model

错误

ValueError: 层 lstm_14 的输入 0 与层不兼容:预期 ndim=3,发现 ndim=2。收到的完整形状:[无,15]

我不知道在这种情况下如何重塑。因为对于普通 LSTM,我可以删除var2(t), var3(t)var4(t)然后将其 (97,12) 重塑为 (97,3,4) 但这里的 y 形状是 (97,15) 所以有点困惑如何将其正确地重塑为网络的输入。

任何帮助表示赞赏!

0个回答
没有发现任何回复~