LSTM预测模型:损耗值不变

时间:2018-08-20 13:35:19

标签: keras deep-learning time-series lstm

我正在尝试在keras中为时间序列实现一个简单的LSTM预测模型。我有一个带有lookback_window = 28的10个时间序列,特征数是1。我需要预测下一个值(timesteps = 28,n_features = 1)。这是我的模型以及尝试训练的方法:

model = Sequential()
model.add(LSTM(28, batch_input_shape=(49,28,1), stateful=True, return_sequences=True))
model.add(LSTM(14, stateful=True))
model.add(Dense(1, activation='relu'))

earlyStopping = callbacks.EarlyStopping(monitor='val_loss', patience=100, verbose=1, mode='auto')

model.compile(loss='mean_squared_error', optimizer='adam')
history = model.fit(train_data, train_y,
                    epochs=1000,
                    callbacks=[earlyStopping],
                    batch_size=49,
                    validation_data=(validation_data, validation_y),
                    verbose=1,
                    shuffle=False)
prediction_result = model.predict(test_data, batch_size=49)

我不会在某个时期后重置状态,也不会使用混洗,因为时间序列中的顺序很重要,而且它们之间也有联系。问题在于,损失值有时仅在第一个时期之后才略有变化,然后保持恒定并且根本不发生变化,在大多数情况下它根本不发生变化。我尝试使用RMSprop之类的其他优化方法,更改了学习速度,删除了earearstope以使其训练更长,更改batch_size甚至没有批次就进行了尝试,尝试了相同的模型无状态,设置了shuffle=True,层数更多,并使其更深,……但是它们都没有任何区别!我不知道我在做什么错!有什么建议吗?

P.S。我的数据包含10个时间序列,每个时间序列的长度为567:

timeseries#1: 451, 318, 404, 199, 225, 158, 357, 298, 339, 155, 135, 239, 306, ....
timeseries#2: 304, 274, 150, 143, 391, 357, 278, 557, 98, 106, 305, 288, 325, ....
...
timeseries#10: 208, 138, 201, 342, 280, 282, 280, 140, 124, 261, 193, .....

我的回溯窗口为28。因此我以28个时间步生成了以下序列:

[451, 318, 404, 199, 225, 158, 357, 298, 339, 155, 135, 239, 306, .... ]
[318, 404, 199, 225, 158, 357, 298, 339, 155, 135, 239, 306, 56, ....]
[404, 199, 225, 158, 357, 298, 339, 155, 135, 239, 306, 56, 890, ....]
...
[304, 274, 150, 143, 391, 357, 278, 557, 98, 106, 305, 288, 325, ....]
[274, 150, 143, 391, 357, 278, 557, 98, 106, 305, 288, 325, 127, ....]
[150, 143, 391, 357, 278, 557, 98, 106, 305, 288, 325, 127, 798, ....]
...
[208, 138, 201, 342, 280, 282, 280, 140, 124, 261, 193, .....]
[138, 201, 342, 280, 282, 280, 140, 124, 261, 193, 854, .....]

然后,我按如下方式拆分数据(data.shape =(5390,28,1)为5390,共10次):

num_training_ts = int(data.shape[0] / 539 * (1 - config['validation_split_ratio']))
train_size = num_training_ts * 539
train_data = data[:train_size, :, :]
train_y = y[:train_size]

validation_data = data[train_size:-1*539, :, :]
validation_y = y[train_size:-1*539]

test_data = data[-1*539:, :, :]  # The last timeseries
test_y = y[-1*539:]

我使用minMaxScale在-1和1之间缩放数据,但为简单起见,我使用的是实际值。最后,我有以下内容:

train_data.shape=(3234,28,1)
train_y.shape=(3234,)
test_data.shape=(539,28,1)
test_y.shape=(539,)
validation_data.shape=(1617,28,1)
validation_y.shape=(1617,)

1 个答案:

答案 0 :(得分:1)

当我首先发现此类问题时,我将重点放在数据上:我的数据已缩放?我有足够的数据用于此模型吗?

然后我传递给模型。在您的情况下,似乎所有学习都是在第一次迭代中完成的。那么,为什么不尝试更改优化器的学习率衰减

有了keras,就这么简单。首先定义您的优化器(在您的代码中,我看到您使用了“ Adam”):

my_adam_optimizer = keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)

然后在complie函数中使用它:

model.compile(loss='mean_squared_error', optimizer=my_adam_compiler)

更新:

最后一个relu层“剪切”负值,因此,如果目标包含负值,则无法预测负值。您在主题中的某个地方说过,您在-1和1之间使用了minmaxScaler,并且可以肯定会给您带来问题。通过删除激活参数,您可以使用默认值,我认为这是“线性的”。 从最后一层删除relu激活可以解决问题!