神经网络

LSTM循环神经网络-如何教一个网络记住过去

用双向LSTM实例直观解释长短时记忆,解决多对多序列问题

长短时记忆(LSTM)神经网络。作者形象。

介绍

标准循环神经网络(rnn)由于在处理较长数据序列时出现的消失梯度问题而遭受短期记忆的困扰。

幸运的是,我们有更高级的rnn版本,可以保存序列早期部分的重要信息,并将其向前推进。最著名的两个版本是长短时记忆(LSTM)而且门控循环病房(GRU)

在这篇文章中,我着重于的结构LSTM并提供一个详细的Python示例供您使用。

内容

  • LSTM在机器学习领域处于什么位置?
  • LSTM与标准rnn的区别是什么? LSTM是如何工作的?
  • 一个完整的Python示例,向您展示如何构建和训练您自己的LSTM模型

LSTM在机器学习领域处于什么位置?

下表是我对最常见的机器学习算法的分类。

While我们经常以有监督的方式使用神经网络,并标记训练数据,我觉得他们独特的机器学习方法值得一个单独的类别。

因此,我的图显示了神经网络(nn)从机器学习宇宙的核心分支出来。循环神经网络是神经网络的一个分支,包含标准rnn、LSTMs和gru等算法。

下图是互动,所以请点击不同的类别放大并显示更多

机器学习算法分类。创建的交互式图表作者

如果你喜欢数据科学和机器学习,请订阅收到我的新文章的邮件。

LSTM与标准rnn的区别是什么? LSTM是如何工作的?

让我们先快速回顾一下简单的RNN结构。RNN由多个层组成,类似于前馈神经网络:输入层、隐藏层和输出层。

递归神经网络结构示意图。
递归神经网络结构示意图。
标准的循环神经网络架构。图像中作者

然而,RNN包含复发性单位在它的隐藏层中,它允许算法处理序列数据.它通过循环传递来自前一个对象的隐藏状态来实现这一点步伐把它和当前的输入结合起来。

时间步-单次处理输入通过循环单元。时间步数等于序列的长度。

你可以在我的网站中找到标准rnn的详细解释前一篇文章如果需要的话。

LSTM与标准RNN有何不同?

我们知道rnn利用复发性单位从序列数据中学习。LSTMs也是如此。然而,在循环单元内发生的事情在两者之间是非常不同的。

查看标准RNN的简化循环单元图(没有显示权重和偏差),我们注意到只有两个主要操作:将之前的隐藏状态与新的输入结合起来,并将其通过激活函数:

标准RNN循环单元。图像中作者

在时间步t处计算隐藏状态后,为被送回了循环病房结合时间步t+1处的输入来计算时间步t+1处新的隐藏状态。这个过程重复t+2, t+3,…,t+n,直到达到预定义的时间步数(n)。

同时,LSTM使用各种门来决定保留或丢弃哪些信息。它还加了a细胞状态,就像是LSTM的长期记忆。让我们仔细看看。

LSTM是如何工作的?

LSTM的循环单元比RNN的循环单元复杂得多,提高了学习效率,但需要更多的计算资源。

LSTM复发性单位。图像中作者

让我们通过简化的图表(没有显示权重和偏差)来了解LSTM循环单元如何处理信息。

  1. 隐藏状态和新输入-将前一个时间步的隐藏状态(h_t-1)和当前时间步的输入(x_t)结合起来,然后将其副本通过各种门传递。
  2. 忘记门-这个门控制着哪些信息应该被遗忘。由于sigmoid函数的范围在0到1之间,它设置了单元格状态中的哪些值应该被丢弃(乘以0)、记住(乘以1)或部分记住(乘以0到1之间的某个值)。
  3. 输入门帮助识别需要添加到单元格状态的重要元素。注意,输入门的结果乘以单元格状态候选项,只有输入门认为重要的信息被添加到单元格状态中。
  4. 更新细胞状态-首先,前一个单元格状态(c_t-1)乘以忘记门的结果。然后我们从[input gate × cell state candidate]中添加新信息,得到最新的cell state (c_t)。
  5. 更新隐藏状态-最后一部分是更新隐藏状态。最新的单元状态(c_t)通过tanh激活函数并乘以输出门的结果。

最后,最新的单元格状态(c_t)和隐藏状态(h_t)返回到循环单元中过程在时间步t+1重复.循环继续,直到到达序列的末尾。

一个完整的Python示例,向您展示如何构建和训练您自己的LSTM模型

我们可以以四种不同的方式使用lstm:

  • 一对一的理论上是可能的,但如果一个物品不是一个序列,你就得不到LSTMs提供的任何好处。因此,最好使用前馈神经网络相反,在这种情况下。
  • 多对一-使用一系列值来预测下一个值。您可以在我的文档中找到此类设置的Python示例RNN的文章
  • 一对多-使用一个值来预测一系列的值。
  • 多对多-使用一个值序列来预测下一个值序列。现在我们将构建一个多对多LSTM。

设置

获取以下数据和库:

让我们导入所有的库:

上面的代码打印了我在这个例子中使用的包版本:

Tensorflow / Keras: 2.7.0
熊猫:1.3.4
numpy: 1.21.4
sklearn: 1.0.1
情节:5.4.0

接下来,下载并摄取澳大利亚的天气数据(来源:Kaggle).我们只摄取列的一个子集,因为我们的模型不需要整个数据集。

此外,我们执行了一些简单的数据操作,并导出了两个新的变量:年-月和中位温度。

的一个片段Kaggle的澳大利亚天气数据做了一些调整。图像中作者

目前,我们在每个地点和日期都有一个中位温度记录。然而,每天的温度波动很大,这使得预测更加困难。因此,让我们计算月平均值并对数据进行转置,以位置为行,以年-月为列。

按地区和月份划分的月平均气温。图像中作者

由于我们正在处理真实的数据,我们注意到有三个月(2011-04、2012-12和2013-02)完全从数据框架中消失了。因此,我们通过取前一个月和后一个月的平均值来计算缺失月份的值。

最后,我们可以在图表上绘制数据。

月平均温度。图像中作者

这个图表最初显示了所有的地点,但我选择了其中的四个(堪培拉、达尔文、黄金海岸和吉尼尼山)来显示在上面的图像中。

注意平均温度和变化在不同地点之间的差异。我们可以训练一个特定位置的模型以获得更好的精确度,或者我们可以训练一个能够预测每个地区温度的通用模型。

在本例中,我将在单个位置(堪培拉)上训练我们的LSTM模型。如果您对通用模型感兴趣,请不要担心,我将在下一篇关于门控循环单元(GRU)的文章中处理它。订阅不要错过!

LSTM模型的训练与评价

在我们开始之前,有几件事需要强调。

  • 我们将使用18个月的序列来预测未来18个月的平均气温。你可以根据自己的喜好进行调整,但要注意,将没有足够的数据用于长度超过23个月的序列。
  • 我们将把数据分成两个单独的数据框架-一个用于训练,另一个用于验证(没时间了验证)。
  • 因为我们正在创建一个多对多预测模型,我们需要用稍微复杂一点的方法encoder-decoder配置。编码器和解码器都是隐藏的LSTM层,信息通过一个接口传递到另一个重复向量层。
  • 一个重复向量当我们想要有不同长度的序列时是必要的,例如,用18个月的序列来预测接下来的12个月。它确保我们为解码器层提供正确的形状。但是,如果您的输入和输出序列与我的示例中的长度相同,那么您也可以选择设置return_sequences = True在编码器层,并删除重复向量。
  • 注意,我们添加了一个双向包装到LSTM层。它允许我们向两个方向训练模型,这有时会产生更好的结果。然而,它的用途是可选的。
  • 同时,我们需要使用时间分布包装器,分别预测每个时间步骤的输出。
  • 最后,请注意,我在本例中使用了未缩放数据,因为它比使用缩放数据训练的模型(MinMaxScaler)产生了更好的结果。在我的GitHub存储库中,你可以在Jupyter notebook中找到缩放版本和未缩放版本(链接可在文章末尾找到)

首先,让我们定义一个帮助函数,将数据重塑为lstm所需的3D数组。

接下来,我们对LSTM神经网络进行超过1000个时代的训练,并显示带有评估指标的模型摘要。您可以在代码中遵循我的注释来理解每个步骤。

上面的代码打印了我们的LSTM神经网络的以下总结和评估指标(注意,由于神经网络训练的随机性质,您的结果可能不同):

LSTM神经网络性能。图像中作者

现在让我们在图表上绘制结果,比较实际值和预测值。

实际温度vs LSTM神经网络预测温度
实际温度vs LSTM神经网络预测温度
LSTM神经网络预测与实际。图像中作者

看起来我们在预测堪培拉的月平均温度方面已经相对成功了。看看你在澳大利亚的另一个城市是否能得到更好的结果!

最后的评论

我真诚地希望您喜欢阅读这篇文章,并获得一些新的知识。

你可以找到完整的木星笔记本代码在我的GitHub库.请使用它来构建您自己的LSTM神经网络,如果您有任何问题或建议,请不要犹豫与我们联系。

干杯!
扫罗Dobilas

揭秘数据科学与机器学习|https://solclover.com/membership|连接www.linkedin.com/in/saulius-dobilas| Twitter @SolClover

Baidu
map