LSTM的总结

2024-06-07 14:48
文章标签 lstm 总结

本文主要是介绍LSTM的总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       

目录

1、RNN

1.1 RNN模型为啥诞生

1.2 基础的RNN模型结构

2、LSTM

2.1 LSTM的基础结构

2.2 LSTM的结构详解

2.3 LSTM的输入和输出

2.4 多层LSTM结构

3 总结

4 参考文件


对于一个算法的产生,一般肯定是为了解决其之前的算法没有解决的问题。所以如果要说一个算法的由来或者优点,肯定是跟它同类型(解决相同的任务),且比他早的里程碑的算法对比。

       LSTM是NLP中比较经典的算法,在百科里的介绍是:长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,是为了解决一般的RNN(循环神经网络)存在的长期依赖问题而专门设计出来的,所有的RNN都具有一种重复神经网络模块的链式形式。所以可以看到,LSTM就是为了解决RNN存在的弊病而诞生的。

       那么LSTM对于整个NLP来说,是一个怎样的呢?从后面的其他语言模型(openAI GPT、ELMO)来看,它可以作为语言表征模型的基础特征提取器,除此之外,从LSTM的其他应用来看,它本身就是一种语言模型,也可以直接用来处理其他的NLP任务。

       从模型的对比和追根溯源来看,要理解LSTM,最好先知道RNN是什么结构,它是干啥的,存在怎样的缺陷,这样才能知道LSTM的优势所在,以及这个模型设计的灵感。

1、RNN

1.1 RNN模型为啥诞生

       其实本质上来讲,神经网络就是训练一堆合适的参数,来提取喂给网络的数据的特征,这里的参数就是各种权重矩阵。在计算机视觉也就是图像处理领域(CV),输入的是图片,经过处理每张图片细分成组成图片的基础单位像素,每个像素点用相应的像素值代替,这样模型才能处理输入的数据嘛(计算机在进行数学计算时只能处理数值型数据,所以不管是输入的什么形式的数据,都要想办法转换成相应的数值)所以一张图片可以看做是一个n*n大小的矩阵。经典的图像处理算法CNN的做法是,通过一个k*k的卷积核也就是过滤器,来提取图片上某个位置的局部特征,也就是局部位置各个像素点之间的联系。

       对于NLP任务来说,输入的是句子,对句子进行处理后的基础单位就是字符或者词组,根据图像处理中的经验,我们要做的就是提取这些基础组成之间的联系,也就是输入数据的特征。其实很好理解,像素跟像素之间关联才形成了我们所看到的图片,字符或者词组之前的组合才形成了我们能理解的一个小句子。那么如何对自然语言这种序列型的句子做特征提取呢,RNN就诞生了

       但是,如果只是像CNN那样,关注局部的组成,对于NLP来说,就只能提取一个局部小短语的语义特征了,这对于那些关注局部特征的任务来说,还是能处理的,比如NLP中的情感识别。但是对一些词之间依赖性比较强的任务,比如命名实体识别(NER),就很不友好了,毕竟中文博大精深,一个词在不同的语句和语境里面都会有不同的含义,这个时候就要考虑整个句子的上下文特征了。所以这个时候就有了针对NLP任务专门设计的RNN算法。(这里可以参考:从前馈到反馈:解析循环神经网络(RNN)及其tricks)

1.2 基础的RNN模型结构

       那我们再来简单的看下RNN的模型是怎样设计的。下面这张图是李宏毅老师的NLP课程中RNN的讲解图。首先我们来看以下一个RNN网络是怎样的,如图1所示。

                                                                                     图1:RNN结构图

      我们可以看到,RNN的基础组成其实就是这个图里面的蓝色的f那一块。每一个基础的蓝色单元有两个输入,一个是这个单元的前一个单元的输出h_input,一个是输入的x,有两个输出:当前单元计算完后的h_output,以及一个输出y。我们先不管整个的RNN是如何计算的,先来看这个基础的蓝色单元是怎么计算,蓝色单元的计算过程如下,可以参考图2:

(1)输入x,其实对应的就是一个字符/词组,一般我们将它处理成一个m维的数值向量;

(2)数值计算/特征提取f,从图的右边可以看到,就是一个sigmoid的计算。它的计算就是当前的输入x乘其权重后加上前一个单元的输出h乘相应权重,然后通过sigmoid激活一下。这其实可以看做是前一个输入信息和当前输入的数据做的特征叠加。这一计算的输出就是当前单元的输出h。

(3)当前单元的输出y,则是在h的基础上再做了一次特征的提取。(向量乘权重其实可以看做是对向量做了一次特征提取)

                                                                                                  图2 

        好了,基础的单元计算解释完了,我们可以看到,每个单元计算不仅考虑的当前自己的输入,而且还考虑了自己前一个单元提供的信息,这样的话,对于一个自然语言序列(x1,x2,x3,……,xi)来说,每一个输入的词xi,都会考虑它自身和前一个词xi-1的特征,从第一个词开始一直往下延续,这样就保证了整个句子词间关系的提取。这就是RNN要解决的CNN不能解决的问题。

       那实际的RNN是怎么运行的呢。在图1中,一个RNN网络是一连串f串起来的,但在实际中一层RNN网络只有一个上面那样的蓝色单元。在(t-1)时刻,蓝色单元输入的是当前序列的某个字符x_t-1的数值表示,以及上一个时刻的h_t-2,经过处理产生的是y_t-1和h_t-1,在t时刻,同样地还是这个单元,输入的是当前的字符x_t和上一个单元的输出h_t-1,产生的是y_t和h_t。

       好了,上面就是最简单的RNN的结构。对于RNN模型存在的问题,比如梯度消失和梯度爆炸,可以参考这篇文章:从前馈到反馈:解析循环神经网络(RNN)及其tricks

2、LSTM

2.1 LSTM的基础结构

        前面说到了,RNN对长序列的句子不够友好,会出现梯度消失和梯度爆炸,所以长短期记忆(Long short-term memory, LSTM)就被创造出来了,专门解决RNN存在的这些问题。简单来说,就是相比普通的RNN,LSTM能够在更长的序列中有更好的表现。

       首先从名字就能看出,LSTM既能处理长期记忆,又能处理短期记忆,所以,按这种情况来说,它的结构肯定是长时段的信息和短时间的信息的特征都能捕捉的,带着这种印象,我们再来看下李宏毅老师的LSTM的模型图,如图3所示。这张图只给出了类似前面图2表示的RNN的基础模块,没有给完整的结构图,是因为LSTM跟RNN的过程非常的相似,只是中间的基础单元的计算不一样。如图3所示,左边是RNN的基础单元,右边是LSTM的基础单元。

                                                                                                     图3

2.2 LSTM的结构详解

       从图3我们可以看到,LSTM比RNN多了一种输入c_t-1,也就是说,当前时刻除了从上一个时刻获取了信息h_t-1,还获取了一种信息c_t-1。从整体结构来看,其实我们可以把h_t-1理解为局部级的短时间的信息,c_t-1理解为序列级的长时段的信息。好,有了这个认知,我们再来看,图3中蓝色的LSTM块是怎么进行计算的,看起来很复杂,但是如果拆开来理解,就很好理解了。下面的图4就是具体的计算模块:

 图4(深蓝色的圆圈里面带点的符号是Hadamard Product,也就是操作矩阵中对应的元素相乘,因此要求两个相乘矩阵是同型的。 橙色的圆圈里面带加号则代表进行矩阵加法。)

       那我们分别来看下各个计算的组成是怎么理解,感觉这里李宏毅老师把它区分得很清楚,算是我看过的所有LSTM文章最好记忆的(不过也是看了其它几位大神的文章后综合理解的)。我们主要分几步讲解:

(1)对于图4中绿色的小块块Z_f,Z_i,Z_o,我们暂时先不管它是怎么计算,记住它就是一种权重向量,就跟前面的RNN的那个W_h和W_i一样,就是一种用来提取输入信息的特征的参数就行了,具体怎么计算,我们可以后面来解释。还有一个浅绿色的小块Z,它跟其他块的处理不一样,它不是权重向量,而是原始的外部信息输入x_t和上一时刻的短时信息输出h_t-1经过处理后提取的当前单元的短时信息。

(2)长时记忆c_t的计算,从上面图4右边公式的第一行可以看出,这个值可以拆为两部分。前面的那部分很好理解,前一个时刻t-1传过来的长时记忆c_t-1与权重向量Z_f相乘,从长时记忆中提取需要的信息,也就是特征。后面那部分呢,Z(对应浅绿色模块)是当前外部输入的字符x_t和上一时刻输出的短时信息h_t-1经过处理后形成的一个新的短时信息,这个Z乘上一个权重Z_i之后,就是在当前的短时信息里面提取的能够添加到长时信息中的特征。所以c_t就很好理解,长时信息就像一个箱子,本来是空的,但是随着一个一个序列字符丢到LSTM单元训练,每次都能从当前单元里提取当前的短时信息Z_i*Z(包括字符特征和局部特征),然后把这个信息融合到那个长时特征的箱子里Z_f*c_t-1,帮后面没训练的字符记住前面有哪些信息,供他们使用。

(3)短时记忆h_t的计算。在第二步的计算中,我们可以看到,c_t是融合了所有的前期信息和当前局部信息的信息总和。对于短时的记忆呢,我们可以用一个类似滤波器的东西,从这个信息总和里提取当前我们想要保留下来的局部信息,作为下一个字符训练所需要的局部信息。这里我们用tanh(c_t)来激活了一下c_t,其实是给值做了一个缩放,然后呢,再乘滤波器Z_o,就是我们要输出的当前保留的局部短时信息h_t = Z_o*tanh(c_t)。

(4)最后就是y_t了,我们可以看到,y_t其实也是一个局部量,就是每一个输入x_t都会对应一个y_t,它不会做长时间的积累。所以,这里就直接在产生的局部短时记忆上再做了一层特征提取,形成了当前的输出y_t,其实我们可以理解为,直接加了一层全连接,然后产生输出。

       好了,现在,我们对LSTM那个蓝色块的计算有一个全局的印象了,总结起来就是,有一个收集全局信息特征的c,它会随着序列的数据输入,不断的积累整个序列的特征,它的积累就是融合之前收集的全局信息c_t-1和当前新加入的局部信息Z。然后呢,我们在训练当前的外部输入x的时候,也不能忘了这个词的上下文局部信息h_t-1,所以要从c_t里面抽取一部分作为要传承下去的局部信息h_t,以便在t+1时刻x还能利用t-1时刻的信息。

       到现在,我们的LSTM计算里,只有一个地方不是特别的清楚,就是上面提到的绿色小块代表的Z_f,Z_i,Z_o三个权重向量,以及一个信息向量Z。来看下它是怎么计算的,如图5所示,其实他们的计算都特别的简单,都是当前的输入x_t和上一时刻输出的局部信息h_t-1进行拼接之后,乘了一个权重矩阵形成的新的权重。然后作为新信息而不是特征的Z,是多加了一个激活函数tanh的处理。

                                                                                                  图5 

        到这里,一个基础的LSTM的结构就解析完了,只是很简单的做了一下结构说明,是一个整体的印象,这里也是直接基于给出的框架来理解的。如果想要有一个推导式的模型形成了解,可以参考这篇文章:Step-by-step to LSTM: 解析LSTM神经网络设计原理

2.3 LSTM的输入和输出

       也许到了这里,大家还只是对LSTM的整个流程和各个模块怎么计算有个整体的了解,但是具体每一步计算是怎样的还不是特别清晰。可以参考下面这张图,是知乎一位网友画的:LSTM神经网络输入输出究竟是怎样的?——EDU GUO的回答,这幅图跟我们上面的讲解是完美对应的,图里的小圆圈就是我们神经网络里常说的神经元,我们可以把它理解为是一个数值。

preview

       除此之外,还有一位网友简单的给出了RNN网络的一个计算例子,这个看懂了,其实换成LSTM是一样的,只是多了几个计算步骤。原文请参考:LSTM神经网络输入输出究竟是怎样的?——隔壁小王的回答

preview

2.4 多层LSTM结构

      多层LSTM 的结构如下图所示,具体的参数输入可以参考文章:LSTM细节分析理解(pytorch版)

 

3 总结

       这篇文章就是总结了其他几篇文章的介绍,加上自己的一些理解,也许很多地方跟学术上不太一样,包括LSTM有名的遗忘门、记忆门和输出门,其实这些都包含在我们上面讲的结构里,没有标出来,但是我觉得不影响对结构的理解。整体上明白了LSTM的框架之后,再看其他文章的各种术语会好理解很多。

       同时,这也只是一篇很简单的LSTM入门文章,简答的介绍了下RNN,以及如何变成LSTM,以及LSTM的框架。但是有一个我觉得很重要的问题没有解决,那就是从RNN变成LSTM,为什么就能解决梯度消失和梯度下降的问题,这个就涉及到具体的公式了,还得花时间来了解。

4 参考文件

      参考文献是按照我阅读的顺序来排序的,感觉按照这几篇文章学习下来,基本的LSTM的框架就理解了。

   (1)人人都能看懂的LSTM

   (2)快速理解LSTM,从懵逼到装逼

   (3)从前馈到反馈:解析循环神经网络(RNN)及其tricks

   (4)Step-by-step to LSTM: 解析LSTM神经网络设计原理

   (5)一幅图真正理解LSTM的物理结构

   (6)LSTM神经网络输入输出究竟是怎样的?——隔壁小王的回答

这篇关于LSTM的总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1039482

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Java注解详细总结

什么是注解?         Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。         注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。 自定义注解  现在我们自定义一个MyTest注解 public @interface MyTest{String aaa();boolean bbb()

tensorboard-----summary用法总结

Tensorflow学习笔记——Summary用法         最近在研究tensorflow自带的例程speech_command,顺便学习tensorflow的一些基本用法。 其中tensorboard 作为一款可视化神器,可以说是学习tensorflow时模型训练以及参数可视化的法宝。 而在训练过程中,主要用到了tf.summary()的各类方法,能够保存训练过程以及参数分布图并在

七种排序方式总结

/*2018.01.23*A:YUAN*T:其中排序算法:冒泡排序,简单排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序*/#include <stdio.h>#include <math.h>#include <malloc.h>#define MAXSIZE 10000#define FALSE 0#define TRUE 1typedef struct {i

Java实现MD5加密总结

Java实现MD5加密总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 什么是MD5加密 MD5是一种常用的哈希算法,用于将任意长度的数据通过哈希运算转换为固定长度的数据串,通常为128位的二进制串,常用于对密码等敏感信息进行加密存储或传输。 2. Java实现MD5加密的方法 2.1 使用java.sec

Linux通配符总结

Linux通配符总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在Linux系统中,通配符是一种用于匹配文件名或路径名的特殊字符。通过使用通配符,可以方便地匹配多个文件或目录,从而进行文件操作或查找。 2. 常用的通配符 在Linux系统中,常用的通配符包括以下几种: *:匹配任意长度的任意字符。?:匹配任意单个字符

【Linux文件系统】被打开的文件与文件系统的文件之间的关联刨析总结

操作系统管理物理内存以及与外设磁盘硬件进行数据的交换 操作系统如何管理物理内存呢? 其实操作系统内核先对内存先描述再组织的!操作系统管理内存的基本单位是4KB,操作系统会为每一个4KB大小的物理内存块创建一个描述该4KB内存块的struct page结构体,该结构体存储着这4KB内存块的属性信息,通过管理struct page来对内存进行管理,page结构体的大小比较小,OS通常将它们组成一个