我在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
,并且优化器为adam
或sgd
。
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)
我已经训练了多个LSTM,但是针对验证集的结果如下:
第二个图(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优化器)的损失进度的放大图像
从我弄乱索引可以看出,损失值的反弹(创建粗线区域)是在500纪之后开始的。
答案 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张量。
在您的情况下:
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
系列作为X
和y
,因为Keras有时会被熊猫弄糊涂。
有关使用Keras进行时间序列预测的完整示例,请查看this notebook