RNN
1、RNN简述
1)为什么需要RNN(循环神经网络)
普通神经网络只能单独的去处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列; 当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。
RNN的输入可以多个且有序的,它可以模拟人类的阅读顺序去读取文本或者序列化数据,且通过隐藏层神经元的编码,上一个隐藏层神经元的信息可以传递到下一个隐藏层神经元,从而形成一定的记忆能力,能够更好地理解序列化数据。
2)存在梯度消失的问题
当输入的序列足够长时,RNN前期的层通常通常由于梯度消失而停止学习,从而导致RNN只拥有短期记忆。也就是说如果输入的序列的足够长,RNN在处理序列后面的信息时,可能已经将序列前面的信息丢失或者遗忘了,RNN很难完整的传递完整的长序列信息。
再举一个例子:
有时候我们完成一个任务只需要一些邻近信息,如一个语言模型,基于前面所给的字,预测下一个字是什么。如果我们尝试着“the clouds are in the sky”,我们不需要任何更多的内容,最后一个字是显然是sky,这一个例子中相关信息与我们所需要预测的内容之间的gap是非常近的。
当然还有例子,我们需要很多的内容来预测一个字"I grew up in France… I speak fluent French",相邻信息显示在这里需要填写一种语言,但具体是何种语言,需要抓取很远的信息France才能决策出来的。这一个例子中相关信息与我们所需要预测内容的gap是非常远的。
不幸的是,当这些gap变得比较远的时候,RNN就没有办法把这些信息联系起来了。
2、RNN(包括LSTM RNN)的多结构详解
摘录自网址(https://www.jiqizhixin.com/articles/2018-12-14-4)
1)one-to-n
输入不是序列而输出为序列的情况,如下图,1)圆圈或方块表示的是向量。2)一个箭头就表示对该向量做一次(U、W、b)变换,后不赘述。one-to-n模型有两种情况:1)输入信息X作为起始阶段输入;2)输入信息X作为每个阶段的输入。
输入信息X作为起始阶段的输入
输入信息X作为每个阶段的输入
这种 one-to-n 的结构处理问题的应用领域有:
- 从图像生成文字(image caption),此时输入的X就是图像的特征,而输出的y序列就是一段句子,就像看图说话等
- 从类别生成语音或音乐等
2)n-to-n
n-to-n是最经典的RNN结构,输入、输出都是等长的序列数据。
假设输入为X=(x1, x2, x3, x4),每个x是一个单词的词向量。为了建模序列问题,RNN引入了隐状态h(hidden state)的概念,h可以对序列行的数据提取特征,接着再转换为输出。先从h1的计算开始看:
h2的计算和h1类似。要注意的是,在计算时,每一步使用的参数U、W、b都是一样的,也就是说每个步骤的参数都是共享的,这是RNN的重要特点。
一个箭头就表示对对应的向量做一次类似于f(Wx+b)的变换,这里的这个箭头就表示对h1进行一次变换,得到输出y1。
这就是最经典的RNN结构,它的输入是x1, x2, …..xn,输出为y1, y2, …yn,也就是说,输入和输出序列必须要是等长的。由于这个限制的存在,经典RNN的适用范围比较小,但也有一些问题适合用经典的RNN结构建模,如:
- 计算视频中每一帧的分类标签。因为要对每一帧进行计算,因此输入和输出序列等长。
- 输入为字符,输出为下一个字符的概率。这就是著名的Char RNN。
3)n-to-one
要处理的问题输入是一个序列,输出是一个单独的值而不是序列
这种结构通常用来处理序列分类问题。如输入一段文字判别它所属的类别,输入一个句子判断其情感倾向,输入一段视频并判断它的类别等。
4)n-to-m(Encoder-Decoder)
这种结构是Encoder-Decoder,也叫Seq2Seq,是RNN的一个重要变种。原始的n-to-n的RNN要求序列等长,然而我们遇到的大部分问题序列都是不等长的,如机器翻译中,源语言和目标语言的句子往往并没有相同的长度。为此,Encoder-Decoder结构先将输入数据编码成一个上下文语义向量c。语义向量c可以有多种表达方式,最简单的方法就是把Encoder的最后一个隐状态赋值给c,还可以对最后的隐状态做一个变换得到c,也可以对所有的隐状态做变换。
拿到c之后,就用另一个RNN网络对其进行解码,这部分RNN网络被称为Decoder。Decoder的RNN可以与Encoder的一样,也可以不一样。具体做法就是将c当做之前的初始状态h0输入到Decoder中:
还有一种做法是将c当做每一步的输入:
由于这种Encoder-Decoder结构不限制输入和输出的序列长度,因此应用的范围非常广泛,比如:
- 机器翻译:Encoder-Decoder的最经典应用,事实上这结构就是在机器翻译领域最先提出的。
- 文本摘要:输入是一段文本序列,输出是这段文本序列的摘要序列。
- 阅读理解:将输入的文章和问题分别编码,再对其进行解码得到问题的答案。
- 语音识别:输入是语音信号序列,输出是文字序列。
Encoder-Decoder 缺点
- 最大的局限性:编码和解码之间的唯一联系是固定长度的语义向量c
- 编码要把整个序列的信息压缩进一个固定长度的语义向量c
- 语义向量c无法完全表达整个序列的信息
- 先输入的内容携带的信息,会被后输入的信息稀释掉,或者被覆盖掉
- 输入序列越长,这样的现象越严重,这样使得在Decoder解码时一开始就没有获得足够的输入序列信息,解码效果会打折
因此,为了弥补基础的 Encoder-Decoder 的局限性,提出了attention机制。
LSTM
参考文章:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
参考文章:
【1】https://www.jiqizhixin.com/articles/2018-12-14-4