你可以在这里查看完整的源代码
https://colab.research.google.com/drive/1kk24KjpZQEZpdlBxr4D4DO-IGHJ0439v?usp=sharing
x_test
的原始数据具有非线性随机游走特性,
但新预测的20个值却呈现出线性形状。
显然,我的预测是错误的吗?
回答:
我仔细阅读了你的数据,并对你的训练和模型提出了一些评论:
1) 你特别训练了一个LSTM模型,用于从过去的20个值预测未来的一个值。你为什么期望这个模型能够从第一个值扩展预测另外19个值?你的模型没有被训练来做这件事,并且不知道这有多重要。
2) 你的模型非常小。你的模型只有491个变量(model.summary()),这非常小。你认为有多少特征会影响股市?你认为每个特征需要多少变量来建模?大多数深度学习需要数百万个变量来学习像股市这样复杂的东西。此外,这是非常复杂的领域,全世界有数百万人正在研究这个领域。
3) 你对数据的复杂性几乎没有进行任何训练。你运行了100个epoch,大约在GPU上训练了250秒。
4) 你的模型极度过拟合。我认为你犯了一个错误,认为“低损失”等于“好的预测模型”,这根本不是真的。我在谷歌上找到一个例子来说明我的意思,
https://towardsdatascience.com/regularization-the-path-to-bias-variance-trade-off-b7a7088b4577
https://miro.medium.com/max/552/1%[email protected]
在这个例子中,训练后的模型在输入数据上几乎没有损失,并且预测得非常完美。但显然模型对驱动输入数据的基本特征曲线一无所知。因此,如果你尝试用这个模型预测下一个值,将会非常不准确。
5) 我认为你误解了训练模型的作用。当你训练一个模型时,你是在趋向于一个产生低损失的“常见”答案。模型永远不会找到一些极端的权重例子来进行非常好的预测;它只会找到并慢慢趋向于一个产生低损失的常见解决方案。例如,如果稍微调整你的权重向零,使损失更小,那么这将在你的训练过程中反复强调。如果预测一个均匀的线性答案在看似随机的数据集中产生最小的损失,那么这将在训练过程中反复被强化。一般来说(如我上面评论的),当模型面对均匀随机的信息时,它倾向于偏向信息的平均值(因为这会减少批次之间的损失)。
我认为你提供的代码和得到的结果是预期之内的。
编辑:
以下是一些时间序列数据模型的例子(它们是否好,取决于你的数据):
# 基本的LSTM模型,尝试从一系列时间数据生成预测向量。
model = tf.keras.Sequential([
tf.keras.layers.LSTM(20),
])
# 也许添加几个LSTM层来帮助学习信息,增加一些维度。
model = tf.keras.Sequential([
tf.keras.layers.LSTM(5,return_sequences=True),
tf.keras.layers.LSTM(50,return_sequences=True),
tf.keras.layers.LSTM(20),
])
# 也许应该使用一些Dense层来重新排列信息。
model = tf.keras.Sequential([
tf.keras.layers.LSTM(20),
tf.keras.layers.Dense(500),
tf.keras.layers.Dense(20),
])
也许可以添加一些激活函数,relu可能会有用(有点像给层提供一个垃圾桶来去除无用值)。或者可以使用sigmoid(保持值较小)或softmax(将值视为概率)。你也可以添加一些Dropout层来防止过拟合(让你的模型保持警惕,不要让它太快安定下来)。另外,数据归一化可能有用。如果你发现权重增长得太快,可以添加一些正则化,强制模型在学习数据时使用较小的权重。
model = tf.keras.Sequential([
tf.keras.layers.LSTM(5,return_sequences=True,activation='relu'),
tf.keras.layers.Dropout(0.10),
tf.keras.layers.LSTM(50,return_sequences=True,activation='relu'),
tf.keras.layers.Dropout(0.10),
tf.keras.layers.LSTM(20),
])
如果你觉得学习效果不好,可以从“adam”切换到其他学习算法。也许你的“均方误差”损失函数对大错误过于严厉,可能会减慢学习速度;尝试使用“logcosh”代替。连续运行24小时,最好使用GPU。
如果LSTM层太慢。也许可以切换使用一些Attention或Residual层(需要谷歌搜索这些自定义想法)。
你也可以尝试使用GRU层代替LSTM。性能大致相同,但训练速度稍快。