大名鼎鼎的LSTM详解

大名鼎鼎的LSTM详解

本文大部分内容来自于 >>> LSTM详解 .我又从别的地方补充了一些材料,尽可能把它讲的更加完善,尤其是细节方面。尤其是补充了为什么会出现LSTM。这是我的学习笔记,请大神指正。

前言

即使你刚刚入门深度学习,你对传统RNN也不会陌生。我们以NLP常见的序列标注问题为例,h表示一个状态,也就是我们想要的输出,句子被word embedding之后,顺序进入模型,在参数矩阵A的作用下,其中h_0包含the这个词的信息,h_1包含the 和cat 两个词的信息,最后到h_t之后,就包含所有句子的信息。大家很快就能发现问题:句子很长之后就会出现梯度消失的问题,ht包含第一个字符x_0的信息很少很少。在这个基础上LSTM应运而生,它的论文发表在1997年。

RNN图示

在许多讲LSTM的文章中,都会出现下面这个图。 说实话,这个图确实很清晰明了(对于懂的人来说),一些很“显然”的问题就被忽略了,但是对于刚入门的人来说,一些基础的问题却要搞很久才能弄明白,我在原作者讲的很清楚的情况下再补充新手需要的内容。

LSTM总体框图

在这里先说一下这些符号的含义:

Neuial Network layer:一层神经网络,也就是w^T x + b的操作。区别在于使用的激活函数不同,σ表示的是sigmoid函数,他是将数据压缩到[0,1]范围内,如下图所示;tanh表示的是双曲正切激活函数,他把数据归一化到[-1,1]之间,具体函数网上可查,不一一贴图;

sigmoid函数

Pointwise Operation:这个是两个矩阵按位操作,如果是X号表示,这两个维数相同的矩阵,每个位置相同的元素相乘放到新矩阵的该位置上,如下图所示,加法也是同样。

pointwise操作乘法示意

Vector Transfer:矩阵传递

Concatenate:矩阵连接,两个矩阵不做任何计算,只是连接在一起,比如原来A10维,B5维,连接之后15维,就像贪食蛇一样。

Copy:一个矩阵变成两个一模一样的;

了解了这些基本操作,大概知道基础的运行原理,我们接下来一个个解析他的四个门结构,首先看大体结构。

LSTM的大体结构

相比于原始的RNN的隐层(hidden state), LSTM增加了一个细胞状态Ct(cell state),下图是lstm中间一个时刻t的输入输出。

LSTM单个结构

我们首先看一下LSTM在t时刻的输入与输出,首先,输入有三个: 细胞状态C_{t-1}(黄色圆圈),隐层状态h_{t-1}(紫色圆圈), t时刻输入向量X_t​(蓝色圆圈),而输出有两个:细胞状态 C_t​, 隐层状态 h_t​。其中

  1. 细胞状态 C_{t-1}的信息,一直在上面那条线上传递, t时刻的隐层状态 ht​与输入xt​会对Ct​进行适当修改,然后传到下一时刻去。
  2. C_{t-1}会参与 t时刻输出 h_t​的计算。
  3. 隐层状态 h_{t-1}的信息,通过LSTM的“门”结构,对细胞状态进行修改,并且参与输出的计算。

总的来说呢,细胞状态的信息一直在上面那条线上传递,隐层状态一直在下面那条线上传递,不过它们会有一些交互,在LSTM中,通常被叫做“门”结构。由此可以看到h_t不光光是由上一个状态,和本次的输入所决定,还有一个细胞状态C_{t-1},这是其与RNN最大的不用

LSTM也是RNN的一种,输入基本没什么差别。通常我们需要一个时序的结构喂给LSTM,数据会被分成 t个部分,也就是上面图里面的 X_t​,X_t​可以看作是一个向量 ,在实际训练的时候,我们会用batch来训练,所以通常它的shape是**(batch_size, input_dim)**。当然我们来看这个结构的时候可以认为batch_size是1,理解和计算之类的也比较简单。

另外C_0​与 h_0​的值,也就是两个隐层的初始值,一般是用全0初始化。两个隐层的同样是向量的形式,在定义LSTM的时候,会定义隐层大小(hidden size),即Shape(C_t) = Shape(h_t) = HiddenSize。输出的维度与对应输入是一致的。

LSTM的门结构( 一共有3个)

1. 遗忘门 Forget Gate

遗忘门及其公式

首先说一下[ht−1​,xt​]这个东西就代表把两个向量连接起来(操作与numpy.concatenate相同)。然后f_t​就是一个网络的输出,看起来还是很简单的,执行的是上图中的公式。 具体的操作如下图所示:

单个神经网络的操作-以遗忘门为例

这个图没有体现出来+b这个操作,下同

然而它为什么叫遗忘门呢,下面是我自己的看法,前面也说了,σ的输出在0到1之间,这个输出 f_t逐位与C_{t-1}的元素相乘,我们可以发现,当f_t的某一位的值为0的时候,这C_{t-1}对应那一位的信息就被干掉了,而值为(0, 1),对应位的信息就保留了一部分,只有值为1的时候,对应的信息才会完整的保留。因此,这个操作被称之为遗忘门,也算是“实至名归”,这样放到传送带上的内容是经过遗忘的,传送带我们后边会用到。

2. 更新门 Input Gate

这个门有两个部分,一个是~C_t​(因为我没有会员,当时写MD笔记不能插图,所以没有用Markdown来写,符合只能放在前面了,大家凑合着看吧),这个可以看作是新的输入带来的信息,tanh这个激活函数将内容归一化到-1到1。另一个是 i_t,这个东西看起来和遗忘门的结构是一样的,这里可以看作是新的信息保留哪些部分。

更新门操作及其公式

下面的操作就是对C_t进行更新,这个公式表示什么呢?看左边,就是前面遗忘门给出的f_t​,这个值乘C_{t-1},表示过去的信息有选择的遗忘(保留)。右边也是同理,新的信息~{C_t}乘i_t表示新的信息有选择的遗忘(保留),最后再把这两部分信息加起来,就是新的状态C_t了。

更新门的第二个操作,更新C传送带

具体的操作示意图如下:

更新传送带示意

3. 输出门层 Output Gate

最后就是lstm的输出了,此时细胞状态C_t已经被更新了,这里的o_t​还是用了一个sigmoid函数,表示输出哪些内容,而C_t​通过tanh缩放后与o_t​相乘,这就是这一个timestep的输出了。

看完公式之后,我们再来看图解,o_t比较简单,同forget门一样

参数

上面说了lstm的原理与公式,这里想再讲一下参数是怎么计算的。简单来说,就是上面公式的W和b包含的参数数量(上面一共有四个)。 W的话,就是输入维度乘输出维度, b的参数量就是加上输出维度。 上面的公式中,W有四个:W_f,W_i,W_c,W_o​,同样,b也是四个: b_f, b_i, b_c, b_o​。 我们假设输入x_t​这个向量的维度是512,lstm的隐层数是 256,根据这个来实际计算一下参数量。 首先是输入 [h_{t-1}, x_t],这个前面说过,是两个向量连接起来,因此维度相加: 256 + 512 = 768。 因为隐层是 256,所以输出就是256维。 W的参数量就是 768×256=196608,b的参数是256。 所以最终的参数量就是:(768×256+256)×4=787456

另外,pytorch中的lstm实现稍有不同,其公式如下:

上面的 g_t其实就是~C_t​​,其他符号基本是一致的。可以看到,pytorch中,x_t与h_{t-1}并没有拼接在一起,而是各自做了对应的运算,这其实就是使用了分块矩阵的技巧进行计算,结果理论上是一样的,不过这里有些不同的就是加了两个bias,因此计算偏置的参数需要乘2。

编辑于 2023-05-31 11:10 ・IP 属地上海
RNN
神经网络
深度学习(Deep Learning)
赞同 142​ 24 条评论
分享
喜欢 ​ 收藏 ​ 申请转载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值