LSTM内部结构及前向传播原理——LSTM从零实现系列(1)

news/2024/12/27 20:00:01/

一、前言

        作为专注于时间序列分析的玩家,虽然LSTM用了很久但一直没有写过一篇自己的LSTM原理详解,所以这次要写一个LSTM的从0到1的系列,从模型原理讲解到最后不借助三方框架自己手写代码来实现LSTM模型。本文本身没有特别独到之处,因为网上其实已经有很多优秀的关于LSTM讲解的文章,文章也做了很多借鉴;本文一方面是作为后续讲解如何从0实现LSTM的前置阅读内容,另一方面是作为自己多年对LSTM学习和理解的总结,同时也为作者的后续在此方向进一步的理论研究做铺垫。

        LSTM是建立在普通的神经网络之上,准确说是建立在循环神经网络RNN之上,加上其可叠加的特性,一般归为深度学习范畴。对于神经网络和RNN这些前置知识之前已经写过很多文章,可参考下面链接。本文重点讲解LSTM的算法机制,为后续实现手写LSTM模型做铺垫。

https://blog.csdn.net/yangwohenmai1/category_9126892.html

        LSTM主要解决了RNN的梯度消失和梯度爆炸问题,实现了时间序列的长期预测功能,这一机制的实现方案类似残差网络,利用一条单独通路,将过去的记忆尽可能多的向未来传递,再通过LSTM模型内部的各种控制门来对过去的记忆内容进行提取,舍弃,修正,变成当前的输出结果。再将当前时间步的结果和修改过的记忆信息向下一个LSTM单元传递。

        LSTM的缺点是如果我们输入的历史序列很长,则LSTM模型的内存和训练时间会大大增加,这是由于LSTM内部的计算过程复杂和监督学习数据的特殊结构所导致的。所以后来推出了简化版的LSTM,即GRU,我将其视为LSTM的儿子,LSTM则是爸爸。下面就来了解一下LSTM的原理,图片大多是从网络上借鉴而来,文尾附参考文献链接。

二、LSTM结构特点

        一般的RNN可以理解为多个相同的单元循环链接,将本次循环的状态向后传递,作为下次循环输入的一部分。缺点是不论激活函数如何选择,都会出现梯度爆炸或梯度消失的问题,因为最后链式求导过程都是连乘的形式。常见的RNN结构如下:

        LSTM比RNN内部结构复杂的多,总的来说有三大控制门,分别是遗忘门、候选记忆门、输出门,还有一条负责传送长期记忆的传送带。就是这些门对历史信息进行提取、舍弃、更新这些精细化控制,同时也保证了模型不会出现梯度消失和梯度爆炸的情况。LSTM网络结构如下:

        LSTM最核心的机制就是这个历史信息“传送带”,一方面它贯穿了整个“循环网络”,将历史的信息顺畅的向后传递,另一方面每个单元在更新历史信息时使用的是“+”而不是“×”,这使得链式求导时避免了连乘的出现,从而解决了梯度爆炸和梯度消失的问题。对应功能模块如下:

        LSTM整体结构的中文示意图如下,这个结构中有两个重要参数分别是“记忆细胞”C和“隐藏状态”H,一般来说我们称C为长期记忆,H为短期记忆。原则上不建议也不应该用拟人的方式去解释神经网络,但是为了方便理解各个功能模块后续就沿用这种描述方式。下面我们就对每个过程进行拆分讲解。

三、LSTM原理分步解析

3.1.遗忘门的原理:

        遗忘门f_t可表示为下式,其中W_{xf}表示输入x传递到f_t对应的权重矩阵,W_{h_{t-1}f}表示上一时间步状态h_{t-1}传递到f_t对应的权重矩阵,b_f表示偏置项。通过激活函数\sigmaf_t的计算结果限定在(0,1)之间。

f_{t}=\sigma (x_{t}W_{xf}+h_{t-1}W_{h_{t-1}f}+b_f)

 3.2.输入门的原理:

        输入门i_t可表示为下式,其中W_{xi}表示输入x_t传递到i_t对应的权重矩阵,W_{h_{t-1}i}表示上层状态h_{t-1}传递到i_t对应的权重矩阵,b_i表示偏置项。通过激活函数\sigmai_t的计算结果限定在(0,1)之间。

i_{t}=\sigma (x_{t}W_{xi}+h_{t-1}W_{h_{t-1}i}+b_i)

        中间状态\tilde{C_t}可表示为下式, 其中W_{xC}表示输入x_t传递到\tilde{C_t}对应的权重矩阵,W_{h_{t-1}C}表示上层状态h_{t-1}传递到\tilde{C_t}对应的权重矩阵,b_C表示偏置项。通过激活函数tanh\tilde{C_t}的计算结果限定在(-1,1)之间。这里为什么使用tanh而不用\sigma其实没有定论,根据经验激活函数的选择应该是作者通过超参数后得出的较优结论,不具有明确的可解释行。

\tilde{C_t}=tanh(x_tW_{xC}+h_{t-1}W_{h_{t-1}C}+b_{C})

3.3.候选记忆的原理:

        输出状态C_t可表示为下式,其中C_{t-1}是上一时间步传递过来的输出状态,f_ti_t\tilde{C_t}是遗忘门、输入门、中间状态的计算结果。

C_t=f_t\odot C_{t-1}+i_t\odot \tilde{C_t}

        f_t\odot C_{t-1}表示遗忘门f_t和上一时间步的状态C_{t-1}做逐点相乘,f_t\in (0,1),使矩阵中接近0的位置的内容被遗忘,接近1位置的部分被保留,达到选择性遗忘的效果。

        i_t\odot \tilde{C_t}表示输出入门i_t和中间状态\tilde{C_t}进行逐点相乘,得到新的候选记忆,也即需要记忆的新特征。i_t\in (0,1),决定了\tilde{C_t}的信息是完全保留还是全部忘记。

        最后我们用f_t遗忘掉历史记忆C_{t-1}中的信息,将新的记忆i_t\odot \tilde{C_t}添加到C_{t-1}中,构成了当前时间步的新记忆C_{t}

3.4.输出门的原理:

        输出门o_t可表示为下式,其中W_{xo}表示输入x_t传递到o_t对应的权重矩阵,W_{h_{t-1}o}表示上个时间步的状态h_{t-1}传递到o_t对应的权重矩阵,b_o表示偏置项。通过激活函数\sigmao_t的计算结果限定在(0,1)之间。

o_{t}=\sigma (x_{t}W_{xo}+h_{t-1}W_{h_{t-1}o}+b_o)

        输出状态h_t可表示为下式,将输出门o_ttanh(C_t)逐点相乘,得到当前时间步新的输出状态,作为下个时间步输入的一部分。

h_t=o_t\odot tanh(C_t)

3.5.总结:

        此时我们就得到一套完整的大脑机制,遗忘门忘掉没用的信息,输入门和候选记忆产生新的记忆信息,输出门负责更新记忆,再将新的记忆送给下一个神经元。

        上述内容基本就是LSTM核心的工作流程,通过将每个功能模块组合起来,就构成了完整的LSTM模型,下面介绍一下数据如何在LSTM模型中流转。

四、多层LSTM以及前向传播的细节

        下面问题来了,LSTM一般属于深度学习范畴,那深度学习必然会有多层模型进行叠加传参的问题。说到模型叠加一般网上就会给出类似下面这张图,这种图可能除了画图人自己,没多少人能看明白参数是怎么传递的。 那么对于LSTM这种更加复杂的RNN类模型,作者讲解一下参数是如何传递的。

4.1.多层LSTM结构

        下图是一个双层LSTM的示例,我们一起分析一下参数是如何在模型中流转的。首先要明确的是图中双层LSTM分别指第一行的3个LSTM单元和第二行的3个LSTM单元,而每一行中的3个LSTM单元表示的是当前LSTM层包含3个时间步。传播方向由第二行指向第一行。

4.2.第一层LSTM计算

        首先看下输入数据x在第一层LSTM中的流转,蓝色方框表示第一层LSTM。

  • 我们知道LSTM单元包含三个输入参数x,c,h,首先x1作为第一个时间步,输入到第一个LSTM单元中,此时输入的初始c0和h0都是0矩阵,计算完成后,第一个LSTM单元输出新的一组h1,c1,作为本层LSTM的第二个时间步的输入参数。
  • 因此第二个时间步的输入就是h1,c1,x2,而输出是h2,c2
  • 因此第三个时间步的输入就是h2,c2,x3,而输出是h3,c3

        至此第一层LSTM的三个时间步计算完成,我们得到了三个输出结果(h1,h2,h3)。

4.3.第二层LSTM计算

        在下图中,蓝色方框对应的是第二层LSTM,本层没有输入参数x1,x2,x3,所以我们将第一层LSTM输出的(h1,h2,h3),作为第二层LSTM的输入x1,x2,x3。

  • 第一个时间步输入的初始c0和h0都为0矩阵,计算完成后,第一个时间步输出新的一组h1,c1,作为本层LSTM的第二个时间步的输入参数。
  • 因此第二个时间步的输入就是h1,c1,x2,而输出是h2,c2
  • 因此第三个时间步的输入就是h2,c2,x3,而输出是h3,c3

        直到LSTM的三个时间步计算完成,又会得到三个新输出(h1,h2,h3),可以继续向后传播,或者直接传入全连接层,将其映射到对应的输出结果。

         上述流程就是多层LSTM内部实现前向传播的数据流转过程。更具体的流程后续我们会在源码实现中讲解。

五、总结

        本文讲解了LSTM的内部结构,原理机制,以及前向传播流程。下片文章讲解LSTM的反向传播流程。链接如下:

写作中。。。。

参考文献:

从零开始实现循环神经网络(无框架) - 知乎

Stateful LSTM in Keras – Philippe Remy – My Blog.

https://colah.github.io/posts/2015-08-Understanding-LSTMs/

白话--长短期记忆(LSTM)的几个步骤,附代码!_mantchs的博客-CSDN博客

LSTM 为何如此有效?这五个秘密是你要知道的

循环神经网络RNN&LSTM推导及实现 - 知乎


http://www.ppmy.cn/news/1877.html

相关文章

大厂程序员bibili技术学习分享

大厂程序员bibili技术学习分享

JAVA队列及实现类

什么是队列? 队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删除;比如我…

计算机毕业设计Java精品在线试题库系统(源码+mysql数据库+系统+lw文档)

计算机毕业设计Java精品在线试题库系统(源码mysql数据库系统lw文档) 计算机毕业设计Java精品在线试题库系统(源码mysql数据库系统lw文档)本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:id…

mysql基本命令

mysql -h localhost -u 用户名 -p密码 //連接數據庫 use desk_show; //使用數據庫 show tables; //顯示數據表 describe sys_att; …

Springboot漫画网站j846u计算机毕业设计-课程设计-期末作业-毕设程序代做

Springboot漫画网站j846u计算机毕业设计-课程设计-期末作业-毕设程序代做 【免费赠送源码】Springboot漫画网站j846u计算机毕业设计-课程设计-期末作业-毕设程序代做本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件&#xff1…

Java开发学习(二十六)----SpringMVC返回响应结果

SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户。 比如:根据用户ID查询用户信息、查询用户列表、…

图论算法(2)—————拓扑排序

在几天前写了一篇最小生成树的文章 今天再讲解一下图论的另一个算法:拓扑排序 注:今天只讲解kahn算法,各位如果对dfs算法有需求可联系我进行讲解 说到拓扑排序,不得不先了解下拓扑是个什么东东 拓扑,它是一种结构 …

深度学习-BN(Batch Normalization)

1. 介绍 Batch Normalization是2015年一篇论文中提出的数据归一化\color{blue}{数据归一化}数据归一化方法,往往用在深度神经网络中激活层之前。其作用可以加快模型训练时的收敛速度,使得模型训练过程更加稳定,避免梯度爆炸或者梯度消失。并且…