LSTM预测直线

时间:2019-10-15 16:35:35

标签: python keras lstm forecasting

我在Keras建立了一个LSTM。它读取9个时滞的观测值,并预测下一个标签。由于某种原因,我训练的模型预测的结果几乎是一条直线。 在模型架构中可能会出现什么问题,从而造成如此糟糕的回归结果?

输入数据:每小时财务时间序列,有1200多个记录的明显上升趋势

输入数据尺寸:
-最初:

X_train.shape (1212, 9)

-为LSTM重塑:

Z_train.shape (1212, 1, 9)


array([[[0.45073171, 0.46783444, 0.46226164, ..., 0.47164819,
         0.47649667, 0.46017738]],

       [[0.46783444, 0.46226164, 0.4553289 , ..., 0.47649667,
         0.46017738, 0.47167775]],

目标数据:y_train

69200    0.471678
69140    0.476364
69080    0.467761
       ...   
7055     0.924937
7017     0.923651
7003     0.906253
Name: Close, Length: 1212, dtype: float64

type(y_train)
<class 'pandas.core.series.Series'>

LSTM设计:

my = Sequential()
my.add(LSTM((20),batch_input_shape=(None,1,9), return_sequences=True))
my.add(LSTM(20, return_sequences=True))
my.add(LSTM(20, return_sequences=True))
my.add(LSTM(1))

9个节点的输入层。 3个隐藏层,每个20个单元。 1个单位的1个输出层。

  

Keras的默认值为return_sequences = False

模型的损失为mse,并且优化器为adamsgd

curr_model.compile(optimizer=optmfunc, loss="mse")

以这种方式拟合模型。批次为32,随机播放可以为True / False

curr_model.fit(Z_train, y_train,
                           validation_data=(Z_validation,y_validation),
                           epochs=noepoch, verbose=0,
                           batch_size=btchsize,
                           shuffle=shufBOOL)

配置和权重保存到磁盘。由于我正在训练多个模型,因此以后加载它们以测试某些性能指标。

spec_model.model.save_weights(mname_trn)
mkerascfg = spec_model.model.to_json()
    with open(mname_cfg, "w") as json_file:
        json_file.write(mkerascfg)


训练MLP时,我是根据验证集得到此结果的:

enter image description here

我已经训练了多个LSTM,但是针对验证集的结果如下:

enter image description here

第二个图(LSTM图)是验证数据。这是y_validation对Z_validation的预测。它们是相应阵列中的最后135条记录。它们被从完整数据中分离出来(即验证),并且具有与Z_train和y_train相同的类型/属性。 x轴仅在索引的0到134之间编号,y轴则是y_validation或预测值。单位在两个数组中均被标准化。因此,所有单位都相同。 “直线”是预测。

对于这种情况,您有何建议? -我已经更改了批量大小。结果相似。 -我尝试过更改return_sequences,但会导致后续图层的形状出现各种错误,等等。

有关MSTM丢失的LSTM进展的信息

有4种模型经过训练,当然都具有相同的问题。我们将仅关注3个隐藏层,即每层20个单位LSTM,如上所定义。批处理大小为32,并且禁用了改组功能。但是启用并没有改变任何内容。

这是第一个模型(adam优化器)的损失进度的放大图像

enter image description here

从我弄乱索引可以看出,损失值的反弹(创建粗线区域)是在500纪之后开始的。

enter image description here

2 个答案:

答案 0 :(得分:2)

您的代码有一个关键问题:维度改组。 LSTM期望输入的形状为(batch_size, timesteps, channels)(或(num_samples, timesteps, features))-而您正在使用9个通道输入一个时间步。永远不会进行反向传播。

修复:将输入重塑为(1212, 9, 1)


建议:阅读this answer。它很长,但是可以节省您调试的时间;这些信息在其他地方无法以如此紧凑的形式提供,我希望在LSTM入门时能得到它。

回答related question可能也很有用-但上一个链接更重要。

答案 1 :(得分:0)

OverLordGoldDragon是正确的:问题在于输入的维数。

正如您在Keras documentation中所看到的那样,所有循环图层都希望输入为形状为(batch_size, timesteps, input_dim)的3D张量。

在您的情况下:

  • 输入有9个时滞,需要按顺序输入LSTM,因此它们是timesteps
  • 时间序列仅包含一种金融工具,因此input_dim为1

因此,重塑它的正确方法是:(1212, 9, 1)

此外,请确保遵守将数据馈送到LSTM的顺序。为了预测问题,最好从最古老的到最新的延迟,因为我们将预测最近的延迟。

由于LSTM从左至右读取输入,因此9个值的顺序应为:x_t-9, x_t-8, ...., x_t-1从左至右,即输入和输出张量应如下所示:

Z = [[[0], [1], [2], [3], [4], [5], [6], [7], [8]],
     [[1], [2], [3], [4], [5], [6], [7], [8], [9]],
     ...
    ]
y = [9, 10, ...]

如果它们的方向不正确,则可以始终将LSTM标志go_backwards=True设置为从右到左读取LSTM。

此外,请确保传递numpy数组,而不传递pandas系列作为Xy,因为Keras有时会被熊猫弄糊涂。

有关使用Keras进行时间序列预测的完整示例,请查看this notebook