序列预测与传统的分类和回归问题不同。
它要求您考虑观测值的顺序,并使用具有记忆能力的长短期记忆(LSTM)循环神经网络等模型,这些模型可以学习观测值之间的任何时间依赖性。
至关重要的是应用 LSTM 来学习如何在序列预测问题中使用它们,为此,您需要一套定义完善的问题,使您可以专注于不同类型和框架的问题。这至关重要,以便您可以建立对序列预测问题如何不同以及诸如 LSTM 等复杂模型如何用于解决它们的直觉。
在本教程中,您将发现一套 5 个定义明确且可扩展的序列预测问题,您可以使用它们来应用和了解更多关于 LSTM 循环神经网络的信息。
完成本教程后,您将了解:
- 简单的记忆任务,用于测试 LSTM 的学习记忆能力。
- 简单的回声任务,用于测试 LSTM 的学习时间依赖性能力。
- 简单的算术任务,用于测试 LSTM 的解释能力。
开始您的项目,阅读我的新书《Python 长短期记忆网络》,其中包含分步教程和所有示例的Python 源代码文件。
让我们开始吧。

5 个用于学习 LSTM 循环神经网络的简单序列预测问题示例
照片由 Geraint Otis Warlow 拍摄,部分权利保留。
教程概述
本教程分为 5 个部分;它们是
- 序列学习问题
- 值记忆
- 回声随机整数
- 回声随机子序列
- 序列分类
问题的属性
序列问题在设计时考虑了一些属性
- 狭窄。专注于序列预测的一个方面,例如记忆或函数逼近。
- 可扩展。可沿选定的狭窄焦点变得或多或少困难。
- 重构。每个问题的两种或多种框架都将呈现,以支持探索不同的算法学习能力。
我试图提供狭窄焦点、问题难度和所需网络架构的混合。
如果您对进一步的扩展或类似精心设计的问题有任何想法,请在下面的评论中告诉我。
需要 LSTM 帮助进行序列预测吗?
参加我的免费7天电子邮件课程,了解6种不同的LSTM架构(附代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
1. 序列学习问题
在此问题中,会生成一个介于 0.0 和 1.0 之间的连续实值序列。给定一个或多个时间步长的过去值,模型必须预测序列中的下一个项。
我们可以直接生成此序列,如下所示
1 2 3 4 5 6 7 |
from numpy import array # 生成一个介于 0 和 1 之间的实值序列。 def generate_sequence(length=10): return array([i/float(length) for i in range(length)]) print(generate_sequence()) |
运行此示例会打印生成的序列
1 |
[ 0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9] |
这可以被看作是一个记忆挑战,即给定上一个时间步长的观测值,模型必须预测下一个值
1 2 3 4 5 |
X(样本),y 0.0, 0.1 0.1, 0.2 0.2, 0.3 ... |
网络可以记忆输入-输出对,这相当无聊,但可以展示网络的功能逼近能力。
该问题可以被构建为随机选择的连续子序列作为输入时间步长,并将序列中的下一个值作为输出。
1 2 3 4 5 |
X(时间步长),y 0.4, 0.5, 0.6, 0.7 0.0, 0.2, 0.3, 0.4 0.3, 0.4, 0.5, 0.6 ... |
这将要求网络学习为最后一个观测值添加固定值或记忆生成问题的所有可能子序列。
该问题的此构建将被建模为许多对一序列预测问题。
这是一个测试序列学习原始特征的简单问题。这个问题可以通过多层感知器网络来解决。
2. 值记忆
该问题是记住序列中的第一个值,并在序列末尾重复它。
这个问题基于 1997 年的论文 长短期记忆 中用于演示 LSTM 的“实验 2”。
这可以被构建为一个单步预测问题。
给定序列中的一个值,模型必须预测序列中的下一个值。例如,给定“0”作为输入,模型必须预测“1”。
考虑以下两个长度为 5 的整数序列
1 2 |
3, 0, 1, 2, 3 4, 0, 1, 2, 4 |
Python 代码将生成两个任意长度的序列。如果需要,您可以进一步推广它。
1 2 3 4 5 6 7 8 9 10 11 |
def generate_sequence(length=5): return [i for i in range(length)] # 序列 1 seq1 = generate_sequence() seq1[0] = seq1[-1] = seq1[-2] print(seq1) # 序列 2 seq1 = generate_sequence() seq1[0] = seq1[-1] print(seq1) |
运行此示例会生成并打印上述两个序列。
1 2 |
[3, 1, 2, 3, 3] [4, 1, 2, 3, 4] |
这些整数可以被归一化,或者更优选地进行独热编码。
这些模式引入了一个棘手之处,因为两个序列之间存在冲突信息,并且模型必须知道每个单步预测的上下文(例如,它正在预测的序列),以便正确预测每个完整序列。
我们可以看到序列的第一个值在序列的最后一个值处重复。这是提供上下文给模型它正在处理哪个序列的指示器。
冲突在于每个序列中倒数第二个项到最后一个项的转换。在序列一中,输入为“2”,输出必须为“3”;而在序列二中,输入为“2”,输出必须为“4”。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
序列 1 X(样本),y ... 1, 2 2, 3 序列 2 X(样本),y ... 1, 2 2, 4 |
这个棘手之处对于防止模型记忆每个序列中的每个单步输入-输出对很重要,因为一个不了解序列的模型可能会这样做。
这种构建将被建模为一个一对一序列预测问题。
这是一个多层感知器和其他非循环神经网络无法学习的问题。序列中的第一个值必须在多个样本中被记住。
这个问题可以被构建为将除了最后一个值之外的整个序列作为输入时间步长,并预测最后一个值。
1 2 3 |
X(时间步长),y 3, 0, 1, 2, 3 4, 0, 1, 2, 4 |
每个时间步长仍然一次显示给网络,但网络必须记住第一个时间步长的值。区别在于,通过时间反向传播,网络可以更好地学习序列之间的差异以及长序列之间的差异。
该问题的此构建将被建模为许多对一序列预测问题。
同样,多层感知器也无法学习这个问题。
3. 回声随机整数
在此问题中,会生成随机整数序列。模型必须在特定的延迟时间记住一个整数,并在序列末尾回显它。
例如,一个长度为 10 的随机整数序列可能是
1 |
5, 3, 2, 1, 9, 9, 2, 7, 1, 6 |
该问题可以被构建为回显第 5 个时间步长的值,在本例中是 9。
下面的代码将生成随机整数序列。
1 2 3 4 5 6 7 |
from random import randint # 生成 [0, 99] 中的随机数序列 def generate_sequence(length=10): return [randint(0, 99) for _ in range(length)] print(generate_sequence()) |
运行此示例会生成并打印一个随机序列,例如
1 |
[47, 69, 76, 9, 71, 87, 8, 16, 32, 81] |
这些整数可以被归一化,但更优选的是可以使用独热编码。
该问题的一个简单构建是回显当前输入值。
1 |
yhat(t) = f(X(t)) |
例如
1 2 |
X(时间步长),y 5, 3, 2, 1, 9, 9 |
这个问题很容易被多层感知器解决,并且可以用于测试平台的校准或诊断。
一个更具挑战性的构建是回显前一个时间步长的值。
1 |
yhat(t) = f(X(t-1)) |
例如
1 2 |
X(时间步长),y 5, 3, 2, 1, 9, 1 |
这是一个多层感知器无法解决的问题。
回显的索引可以被推得更远,从而对 LSTM 的记忆提出更高的要求。
与上面的“值记忆”问题不同,每次训练时期都会生成一个新的序列。这将要求模型学习一个泛化回声解决方案,而不是记忆特定的序列或随机数序列。
在这两种情况下,该问题都将被建模为一个许多对一序列预测问题。
4. 回声随机子序列
这个问题也涉及到随机整数序列的生成。
与前一个问题回显单个前一个时间步长不同,这个问题要求模型记住并输出输入序列的部分子序列。
最简单的构建将是前一个部分的回声问题。相反,我们将专注于一个序列输出,其中最简单的构建是让模型记住并直接输出整个输入序列。
例如
1 2 |
X(时间步长),y 5, 3, 2, 4, 1, 5, 3, 2, 4, 1 |
这可以被建模为一个许多对一序列预测问题,其中输出序列直接在输入序列的最后一个值处输出。
这也可以被建模为网络为每个输入时间步长输出一个值,例如,一对一模型。
一个更具挑战性的构建是输出输入序列的部分连续子序列。
例如
1 2 |
X(时间步长),y 5, 3, 2, 4, 1, 5, 3, 2 |
这更具挑战性,因为输入的数量不等于输出的数量。对此问题的许多对多模型需要更高级的架构,例如编码器-解码器 LSTM。
同样,最好使用独热编码,尽管这个问题可以被建模为归一化整数值。
5. 序列分类
该问题被定义为介于 0 和 1 之间的随机值序列。该序列被用作问题的输入,每个数字在一个时间步长中提供。
每个输入都关联一个二元标签(0 或 1)。输出值全为 0。一旦序列中输入值的累积和超过阈值,输出值就会从 0 翻转为 1。
使用的阈值是序列长度的 1/4。
例如,下面是一个 10 个输入时间步长 (X) 的序列
1 |
0.63144003 0.29414551 0.91587952 0.95189228 0.32195638 0.60742236 0.83895793 0.18023048 0.84762691 0.29165514 |
相应的分类输出 (y) 将是
1 |
0 0 0 1 1 1 1 1 1 1 |
我们可以在 Python 中实现这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from random import random from numpy import array from numpy import cumsum # 创建一个序列分类实例 def get_sequence(n_timesteps): # 创建一个 [0,1] 范围内的随机数序列 X = array([random() for _ in range(n_timesteps)]) # 计算改变类别值的截止值 limit = n_timesteps/4.0 # 确定累积序列中每个项的类别结果 y = array([0 if x < limit else 1 for x in cumsum(X)]) 返回 X, y X, y = get_sequence(10) print(X) print(y) |
运行此示例会生成一个随机输入序列并计算相应的二进制值输出序列。
1 2 3 |
[ 0.31102339 0.66591885 0.7211718 0.78159441 0.50496384 0.56941485 0.60775583 0.36833139 0.180908 0.80614878] [0 0 0 0 1 1 1 1 1 1] |
这是一个序列分类问题,可以被建模为一对一。状态对于解释过去的时间步长以正确预测输出序列何时从 0 变为 1 是必需的。
进一步阅读
如果您想深入了解此主题,本节提供了更多资源。
- 长短期记忆网络, 1997
- 如何在 Keras 中为训练和预测使用不同的批次大小
- 使用 Python 中的长短期记忆网络演示内存
- 如何使用长短期记忆循环神经网络学习回声随机整数
- 如何使用编码器-解码器 LSTM 回显随机整数序列
- 如何在 Python 中使用 Keras 开发用于序列分类的双向 LSTM
总结
在本教程中,您发现了精心设计的、人为设计的序列预测问题集,您可以使用它们来探索 LSTM 循环神经网络的学习和记忆能力。
具体来说,你学到了:
- 简单的记忆任务,用于测试 LSTM 的学习记忆能力。
- 简单的回声任务,用于测试 LSTM 的学习时间依赖性能力。
- 简单的算术任务,用于测试 LSTM 的解释能力。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
非常感谢您关于 LSTM 的宝贵见解。您的博客是一个很棒的学习平台。
我最近一直在尝试使用 LSTM 进行时间序列预测的不同架构。
在 Keras 中,输入张量的默认形状由 [batch size, timesteps, features] 给出。
您认为滞后/百分比变化是否应该作为特征或时间步长传入,以重塑输入张量?
例如:假设我们使用过去 4 天的滞后/滞后百分比变化作为特征(假设没有发现其他特征)
对于 5 个输入和 1 个输出
它应该建模为 [1,5] 还是 [5,1]?
张量的输入形状应该是 [batch size, 1, 5 (当前日期的值:过去 4 天的值)] 还是
[batch size, 5, 1]?
在更高层次上,您是否认为 LSTM 在时间步长之间学习得更好,还是在时间步长内的特征之间学习得更好?
谢谢
好问题。一个好的通用答案是头脑风暴,然后尝试/比较所有模型技能。
在规范用法方面,我建议您将一个样本视为一个具有多个时间步长的系列,在每个时间步长上有一个或多个特征。
另外,我发现 LSTM 在自回归任务方面不是特别出色。请使用经过良好调整的 MLP 来基准化性能。
这有帮助吗?
感谢您的反馈。我一直在测试多种架构设置(仍在进行中)。我希望我能有更多的特征。
LSTM 和其他时间序列方法(ARIMA、ETS、HW)在许多对一输入输出设置中表现良好。但是它们在长期预测方面却糟糕透顶。
我热切期待您关于贝叶斯超参数优化的博客。
(附注:我需要优化超过 1000 个网络)
非常感谢!🙂
哇,这么多网络!
误差在更长的预测期内累积。这个问题很难。
我需要实现一个 ANN 算法,该算法使用其不确定性来估计未知的状态变量。基本上,它应该分为 2 个步骤:在预测步骤中,根据前一个时间步长的状态创建当前状态的估计。在更新步骤中,使用当前时间步长的测量信息来产生新的精确状态估计。所以,如果我将我的系统视为一个黑匣子,那么我得到的是
输入 U = 控制向量,表示控制系统对情况的影响程度
输入 Z = 测量向量,它包含我们在时间步长中收到的真实世界测量值
输出 Xn = 当前“真实”状态的最新估计
输出 Pn = 每个状态部分的平均误差的最新估计 必须实现的算法必须依赖于 RNN 架构,更具体地说,是 LSTM。我遇到的困难是如何将这些输入/输出与 LSTM 结构中的输入/输出相关联。我如何馈送网络,使其符合我的状态估计问题?
感谢任何帮助!
也许这篇博文将帮助您准备数据
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
我建议您使用卡尔曼滤波器或粒子滤波器。看看无迹卡尔曼滤波器,它对非线性系统效果很好,而且足够快
谢谢。
感谢您提供您博客上的优质资源。
这里有一个问题,我不知道如何用神经网络来解决。问题是:假设有一个包含许多单个单词的词典。我有许多有意义的短语,它们是词典单词的组合。问题是,当给定一组单词(来自词典)时,如何训练一个神经网络来组合这些单词(调整它们的顺序)并生成有意义的短语?如何对输入和输出进行建模?
如果您能提供任何建议,我将非常感激。
也许这个框架可以帮助您将问题定义为监督学习问题
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
我正在处理需要根据随时间进行的医学测试来分类患者未来是否会患癌症的数据。测试之间具有顺序关系。A,然后 B,然后 C,依此类推。例如
| 病人 ID | 测试 ID | 红细胞计数 | 白细胞计数 | 标签
| 1 | A | 4.2 | 7000 | 0
| 1 | B | 5.3 | 12000 | 0
| 1 | C | 2.4 | 15000 | 1
| 2 | A | 7.6 | 8000 | 0
| 2 | A | 7.4 | 7500 | 0
每个点都不是在固定的时间间隔内采集的,因此这可能不被视为时间序列数据。我尝试过聚合特征并使用随机森林等集成方法。我能应用 RNN 吗?如果能,怎么应用?
也许可以将其建模为一个序列分类问题?
这篇博文将有助于理解概念
https://machinelearning.org.cn/models-sequence-prediction-recurrent-neural-networks/
嗨。我总是看到您写得很好。
我认为第 2 节的示例中有一个小笔误。第一个序列是 [3,1,2,3,3],第二个序列是 [4,1,2,3,4]。第一个序列中的示例 1 -> 2, 2 -> 3 是正确的,但是第二个序列与 1 -> 2, 2 -> 3 相同。如果目标是显示第一个序列和第二个序列之间的区别,我认为比较第一个序列的 2-> 3, 3-> 3 和第二个序列的 2-> 3, 3-> 4 是一个正确的例子。我可能理解错了,但如果这有帮助,我会留下评论。
我相信它是正确的。
每个示例都有 4 个输入时间步长,用于 1 个样本,该样本必须输出序列中的第一个值,“3”或“4”。
哦,我错过了这句话。“冲突在于每个序列中倒数第二个项到最后一个项的转换。”我以为这是一个预测下一个时间步长的问题。感谢您的回复。
不客气。
Jason,
您是否有“连续子序列”或许多对一模型的示例?这个序列
X(时间步长),y
0.4, 0.5, 0.6, 0.7
0.0, 0.2, 0.3, 0.4
0.3, 0.4, 0.5, 0.6
提前感谢
我相信这里的例子会有帮助
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
你好!这是关于LSTM的绝佳信息。我正在处理一个准周期信号的模式识别问题。在这种情况下,ANN或LSTM哪个更有益?众所周知,ANN模型中没有记忆概念,而基本的LSTM有。但是,模式识别是否真的需要“记忆概念”,或者仅仅通过训练进行学习就足够了?
或许可以测试一下看看?
你好,感谢提供的精彩资源!我遇到了一个问题,我认为它可能是一个序列预测问题,但我无法将其与上面的示例联系起来。
问题是我有一个混合文本,比如一份带有标题的合同。我想将其分割成块。
训练数据集
x:混合合同文本
y:标题,章节1,章节2,……,章节N
测试数据集
x:混合合同文本。
预测y:标题,章节1,章节2,……,章节N。
你能帮我解决这个问题吗?
也许可以使用多输入模型,一个用于标题,一个用于内容?
谢谢你的回复。但当我进行预测时,我只有一个混合合同文本,我无法将其分割成标题、内容作为多输入。
我明白了。也许可以根据预测时你将拥有的数据和需要的数据来建模。
谢谢你的帮助!
我在Medium上找到了一个解决这个问题的方法。
https://medium.com/illuin/https-medium-com-illuin-nested-bi-lstm-for-supervised-document-parsing-1e01d0330920.
这个问题是关于文本分割的。有一些论文关注这个问题。
我会尝试的。再次感谢!
干得好!
嗨 Jason
我有一个问题,我试图预测一只股票是否会最终“赚钱”或不赚钱。所以,在我的例子中,它是以一个行权价卖出一个看跌期权,比如10,而卖出期权时股票价格是12。我想使用一些参数作为特征。然后我的因变量是:是或否(赚钱或不赚钱)。
对于训练数据,我有历史期权价格、希腊字母(如Delta、Theta)、隐含波动率、股票价格等。如果我试图预测“赚钱”或“不赚钱”,那么我认为可以将其视为一个从卖出期权周一开始到周二、周二到周三、周三到周四、周四到周五(周五是到期日)的1和0序列(假设是周度期权)。
另一种方法是将每天的收盘价视为序列的一部分。
还有一种看待序列的方式是:M、T、W、Th作为序列的前4个值,同时尝试预测周五的值(股票价格)。
LTSM是这类事情的好模型吗?如果是,关于模型特性,你有什么更具体的建议吗?有什么阅读材料也让你想到了吗?
总的来说,我没有金融背景
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
这听起来像一个时间序列分类问题,我建议测试一套不同的模型
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/