自然语言处理 | (24) RNN、RNN变体、Seq2Seq、Attention机制简介

原文地址

本篇博客转载自知乎,原文见上面的链接。本文主要利用图片的形式简单的介绍了经典RNN、RNN几个重要变体,以及Seq2Seq模型、Attention机制。旨在让大家有个初步的印象,之后的几篇博客还会更详细的展开。

目录

一、单层网络

二、经典的RNN结构(N vs. N)

三、N vs. 1

四、1 vs. N

五、 N vs. M

六、Attention机制

七、总结


一、单层网络

在RNN之前,首先了解一下最基本的单层全联接网络,结构如下:

其中输入是x,经过线性变换Wx+b和非线性变换激活函数f得到输出y。

二、经典的RNN结构(N vs. N)

在实际应用中,我们还会遇到很多序列型数据:

  • 在自然语言处理问题中。x_1可以看作是第一个单词或其嵌入表示,x_2可以看作是第二个,依次类推。
  • 语音处理中。此时,x_1x_2x_3...是每帧的声音信号
  • 时间序列问题。例如每天的股票价格等。

序列形数据不太好用原始的全联接网络来处理,因为序列中各个term之间是有关联的,如一句话中的每个单词都是有关系的,而不是独立的,而且全联接网络一旦搭建起来,输入是确定的,只能处理定长的数据,而序列一般是长短不一的。RNN可以处理序列中每个term之间的联系,而且可以处理变长序列(不过我们用RNN处理序列时,一般把所有的序列统一为一个定长,可以向量化同时对多个序列进行处理,加快速度)。

为了建模序列问题,RNN引入隐藏状态h(hidden state)的概念,h可以对序列型数据提取特征,接着再转换为输出。

先从h_1(第一个时间步骤上的隐藏状态)开始看:

其中,圆圈和方块代表的是向量/tensor;一个箭头代表对向量做一次变换。如上图中h_0,x_1分别有一个箭头链接,表示对h_0,x_1各做一次变换。

h_2的计算和h_1类似。注意计算时,每一个时间步骤上使用的参数U,W,b都是一样的,也就是每个时间步骤上的参数都是共享的,这是RNN的重要特点。

h_2是第2个时间步骤上的隐藏状态,它编码了序列中前两个term的信息。

使用相同的参数U、W、b,依次计算剩下的:

方便起见,只画了4个时间步骤上的操,即序列长度为4的情况。实际上这个计算过程可以无限持续下去,直到输入序列的最后一个term。

目前我们的RNN还没有输出,得到输出值的方法就是直接通过隐藏状态h进行计算:
 

和之前一样,一个箭头就表示对对应的向量/tensor做一次类似于f(Wx+b)的变换,这里的箭头就表示对h_1进行一次变换,得到输出y_1(第一个时间步骤上的输出)。

剩下的每个时间步骤上的输出类似进行(使用和计算y_1时,相同的参数V和c):

上图就是最经典的RNN结构,他的输入是一个序列x_1,x_2,...,x_n,每个时间步骤上输入序列中的一个term x_i,输出是一个等长的序列y_1,y_2,...,y_n,每个时间步骤上产生一个输出y_i。注意上述结构下的输入/输出序列是等长的。

由于这个限制存在,经典RNN的使用范围比较小,但也有一些问题适合用经典的RNN搭建:

  • 计算视频中每一帧的分类标签。因为要对每一帧进行计算,因此输入和输出序列等长。
  • 输入为一个字符,输出为预测下一个字符出现的概率。这就是char RNN,他可以用来生成文章、诗歌甚至代码。可以参考The Unreasonable Effectiveness of Recurrent Neural Networks

 

三、N vs. 1

有时,我们要处理的问题输入是一个序列,输出是一个单独的值而不是一个序列,此时只需要对最后一个时间步骤的隐藏状态h进行输出变换即可:

这种结构通常用于处理序列分类问题。如输入一段文本判断它所属的类别,或判断其情感倾向,输入一段视频判断他的类别等。

四、1 vs. N

下面看一下,如果输入不是序列而输出是序列的情况如何处理,可以只在序列开始进行输入计算:

还有一种结构是把输入信息x作为每个时间步骤上的输入:

下面是一个等价表示:

这种1 vs. N的结构可以处理的问题:

  • 从图像生成文字(image caption)/生成图像描述:此时输入的X就是编码/提取的图像特征,而输出的y序列就是可以描述该图像内容的一段句子。
  • 从类别生成语音或音乐等

 

五、 N vs. M

下面介绍RNN最重要的一个变种:N vs. M。 这种结构又叫Encoder-Decoder模型,也可以称为Seq2Seq模型。

原始的RNN要求序列等长,即N vs. N,然而我们遇到的大部分问题序列都是不等长的,如机器翻译、语音识别等,源序列和目标序列往往没有相同的长度。

为此,Encoder-Decoder结构先将输入序列编码为一个上下文向量c,用它来表示输入序列的语义特征:

得到c的方式有多种,最简单的就是把Encoder的最后一个时间步骤的隐藏状态赋值给c,还可以对最后的隐藏状态做一个变换得到c,也可以对所有时间步骤上隐藏状态最一个变换得到c。

得到c之后,就要用另一个RNN网络对其进行解码,这部分RNN网络称为Decoder。具体做法是把Encoder产生的c当作初始状态h_0输入到Decoder中:

还有一种做法是将c作为每一个时间步骤的输入:

由于这种Encoder-Decoder结构不限制输入和输出序列的长度,因此应用范围非常广泛,比如:

  • 机器翻译:Encoder-Decoder最经典的应用,事实上这一结构就是在机器翻译领域最先提出。
  • 文本摘要:输入是一段文本序列,输出是这段文本序列的摘要序列。
  • 阅读理解:将输入文章和问题分别编码,再对其进行解码得到问题的答案。
  • 语音识别:输入是语音序列,输出是文字序列
  • ............

 

六、Attention机制

在Encoder-Decoder结构中,Encoder把所有输入序列都编码成一个统一的语义特征c再解码,因此c必须包含原始序列中所有信息,他的长度就成了限制模型性能的瓶颈。如机器翻译问题,当要翻译的句子较长时,一个c可能存不下那么多信息,就会造成翻译静笃的下降。

Attention机制通过在Decoder的每一个时间步骤上输入不同的c来解决这个问题,下图是带有Attention机制的Decoder:

每一个c会自动去选取与当前时间步骤所要输出的y最合适的上下文信息。具体来说,我们用a_{ij}衡量Encoder中第j阶段的隐藏状态h_j和Decoder中第i阶段的相关性,最终Decoder中第i阶段的输入的上下文信息c_i,就来自于Encoder中所有h_ja_{ij}的加权和。

以机器翻译为例(中->英):

输入序列是"我爱中国",因此Encoder中各个时间步骤/阶段的隐藏状态h_1,h_2,h_3,h_4分别可以大致看作是"我","爱","中","国"所代表的信息(严格来说,h_2应该包含了"我爱"的信息,因为他不仅包含当前时间步骤的输入,也包含上一个时间步骤隐藏状态的输入,但这里我们看作它主要包含"爱"的信息,其他h也是一样)。在翻译成英语时,第一个上下文c_1应该和"我"这个字最相关,因此对应的a_{11}就比较大,而相应的a_{12},a_{13},a_{14}就比较小。c_2应该和"爱"最相关,因此对应的a_{22}就比较大。最后c_3和“中国”或h_3,h_4最相关,因此a_{33},a_{34}的值就比较大。

至此,关于Attention机制,最后一个问题是这些权重a_{ij}是怎么来的?

事实上,a_{ij}同样是从模型/数据中学出来的,他实际和Decoder的第i-1阶段的隐藏状态和Encoder第j个阶段的隐藏状态有关,利用他们经过特殊的运算得到(之后的博客我们会详细介绍运算细节)。

同样拿上面的机器翻译举例,a_{1j}的计算(箭头表示对h_{0}^{'}h_j同时作变换):

a_{2j}的计算(箭头表示对h_{1}^{'}h_j同时作变换)

a_{3j}的计算(箭头表示对h_{2}^{'}h_j同时作变换)

以上就是带有Attention的Encoder-Decoder模型计算的全过程。

 

七、总结

本文主要讲了N vs N,N vs 1、1 vs N、N vs M四种经典的RNN模型,以及如何使用Attention结构。希望能对大家有所帮助。

上述RNN采用的都是朴素RNN单元,当然也可以换成LSTM单元或GRU单元,他们更擅长捕捉长依赖关系,内部的运算会更加复杂,但基本原理是一样的,之后我们还会介绍。可以参考这篇文章Understanding LSTM Networks来了解一下LSTM的内部结构。

上述提到的RNN结构都是最基本的结构,相当于积木,在实际上使用时,会产生各种各样的变体,如双向RNN,将RNN单元替换为LSTM或GRU,堆叠多层RNN,添加dropout或batch normaliaztion防止过拟合,加速训练以及transformeri 结构等。但是我们只有把这些基础结构学好,学会每块积木的用途和原理,接下里就可以灵活的使用这些积木,基于自己的应用,搭建出各种复杂的网络结构了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/sdu_hao/article/details/88133059
今日推荐