作者: ,2019年1月21日
翻译:陈之炎
校对:丁楠雅
本文为你详细介绍序列模型,并分析其在不同的真实场景中的应用。
简介
如何预测一个序列中接下来要发生什么事情是一个非常吸引人的课题,这是我对数据科学如此着迷的原因之一!有趣的是——人类的头脑确实擅长于此,但是机器却不是这样的。如果一本书中有一个神秘的情节,人类的大脑就会开始预测出结果,然而,如何教会机器来做类似的事情呢?
多亏了深度学习,我们今天能做的事情比几年前要多的多。处理序列数据的能力,如音乐歌词、句子翻译、理解评论或构建聊天机器人-所有这些都要归功于序列建模。
这便是我们在本文中需要学习的内容,由于这是.ai专业系列课程的一部分,我希望读者能够了解到某些概念。如果你还没有读过前几篇文章,或者还需要快速复习一下,可以访问以下链接:
在本节课程中,我们将看到如何将序列模型应用到不同的真实场景中去,如情感分类、图像字幕等。
课程目录
序列模型课程内容如下:
一、模块1:循环神经网络(RNNs)
二、模块2:自然语言处理(NLP)和单词嵌入
2.1 单词嵌入简介
2.2 学习单词嵌入: & GloVe
2.3 单词嵌入的应用程序
三、模块3:序列模型与注意力()机制
到目前为止,我们已经在这个系列课程中涵盖了相当多的内容,以下是对所学概念的简要概括:
现在我们把重点转向序列建模,本课程分为三个模块(官方课程名称为: Ng教授的深度学习专业课程第5课):
准备好了吗?那我们便从模块1开始第5课序列模型的学习吧!由于平台系统字数限制,后续推出模块2:自然语言处理(NLP)和单词嵌入、模块3:序列模型与注意力()机制,敬请关注!
一、模块1:循环神经网络
第5课第一模块的目标是:
如果这些缩写听起来令人生畏,不要担心——我们会很快把它们解决掉。
1. 首先,为什么是序列模型?
为回答这个问题,将向你展示一些在真实场景中应用到的序列模型示例。
这是一个很常见的应用(每个有智能手机的人都会知道这一点),在这里,输入是一个音频剪辑板,模型生成文本转录。在这里,音频被认为是一个序列,随着时间的推移,输出为一系列单词。
序列模型的另一个流行应用是情感分类。我们将一个文本句子作为输入,模型必须预测出句子的情感(积极、消极、愤怒、兴奋等),输出可以为分级或标星。
给定一个DNA序列作为输入,期望模型能够预测出哪一部分DNA属于哪一种蛋白质。
用一种语言输入一个句子,比如法语,希望模型能把它转换成另一种语言,比如英语。在这里,输入和输出都是序列:
这实际上是利用序列模型对即将到来的事件(和当前的趋势)进行预测,该模型用来预测给定视频中正在进行的活动,在这里,输入是一个帧序列。
这当然是我最喜欢的序列模型示例。如下图所示,我们用一句话作为输入,并希望模型能识别出该句子中的人名:
现在,在做进一步深入探讨之前,需要讨论几个重要的符号,你会在整个文章中看到这些符号。
2. 将在本文中使用到的符号
我们用“x”来表示一个句子,为方便理解,以下面的示例句子为例:
X:哈利和赫敏发明了一种新的咒语。
现在,我们用x<t>来表示句子中的每个词:
上述句子的输出将是:
Y=1 0 1 0 0 0 0
在这里,1表示这个单词代表一个人的名字(0表示它是其他)。下面是我们经常用到的一些常用符号:
此时,我们或许会问——如何在一个序列中表示一个单独的单词呢?嗯,这里,我们要依靠词汇表或字典,即我们在句子中使用到的单词列表,词汇表结构如下所示:
词汇表的大小因不同的应用而异,通常从训练集中挑选出现频度最高的单词来制作词汇表。
现在,假设我们想表示单词“Harry”这个词,它在词汇表中的位置是 位,我们对这个词汇进行一次编码,以表示“Harry”:
通常,x<t>是一个独热编码向量,我们将1放在第4075t位置,所有其余的单词将表示为0。
如果单词不出现在词汇表中,会创建一个未知的<unk>标记,并将其添加到词汇表中。就这么简单!
3. 循环神经网络(RNN)模型
当X,Y之中有一个是序列,或者X和Y都是序列时,我们使用循环神经网络来学习从X到Y的映射。但是,为什么不能用一个标准的神经网络来解决这些序列问题呢?
问得太好了!下面,让我用一个例子来做出解释。假设我们需要构建下述神经网络:
这里主要有两个问题:
为此,需要建立一种表示,用它来解析不同长度的句子,并减少模型中的参数数量。这就是我们要用到循环神经网络的地方,这便是典型RNN:
RNN获取第一个单词(x<1>),并将其馈送到预测输出(y‘<1>)的神经网络层。重复此过程,直到最后一步x<tx>生成最后的输出y‘<Ty>,这是输入字数和输出字数相等的网络。
RNN按从左到右的顺序扫描数据。注意,RNN在每个时间步长中使用的参数是共享的,在每个输入层和隐藏层(Wax)之间、每个时间步长(Waa)之间以及隐藏层和输出层(Wya)之间共享参数。
因此,如果需要对x<3>进行预测,我们也会得到关于x<1>和x<2>的信息。RNN的一个潜在缺点是:它只从先前的时间步长获取信息,而不是从后续的时间步长获取信息。这个问题可以用双向RNN来解决,我们会在稍后进行讨论。现在,我们来看看RNN模型中的前向传播的步骤:
a<0> 是一个全零向量,我们计算与标准神经网络相类似的激活函数:
同样,我们可以计算每个时间步长的输出。这些公式的一般形式可以写成:
可以用更为简洁的方法列出这些方程:
水平叠加Waa 和Wya 以获得Wa,a<t-1>和x<t>垂直叠加。目前只有一个矩阵,而不是带着两个参数的矩阵。简言之,这便是循环神经网络的前向传播原理。
3.1 时间轴上的反向传播
接下来,你可能会看到这种情况-反向传播步骤与前向传播的方向正好相反。我们有一个损失函数,为了得到准确的预测,需要将它最小化。损失函数由以下公式给出:
我们计算每个时间步长里的损失,最后对所有这些损失求和,以计算序列的最终损失:
在前向传播中,我们从左向右移动,即增加时间t的步长。在反向传播中,我们从右向左移动,即在时间轴上向后移动(因此称为时间反向传播)。
到目前为止,我们看到的是输入和输出序列长度相等的应用场景。但是如果输入和输出序列长度不等的情况又如何呢?我们将在下一节中看到这些不同的应用场景。
3.2 不同种类的RNN
可以用多种不同类型的RNN来处理序列长度不同的示例。这些问题可分为以下几类:
前面看到的名称实体识别示例属于这个类别。假设我们有一系列的单词,对于每个单词,我们必须预测它是否是一个人名。针对此类问题的RNN架构如下:
对于每个输入字,我们预测它对应的输出字。
来看看情绪分类问题:我们将一个句子传递给模型,它将返回与该句子对应的情感或评级。这是一个多对一的问题,输入序列可以有不同的长度,而输出只有一个。针对此类问题的RNN架构如下所示:
这里,我们在句子结束时会得到一个输出。
以音乐生成为例,我们希望用音乐作为输入来预测歌词。在这种情况下,输入只是一个单词(或一个整数),输出的长度可变。这类问题的RNN体系结构如下所示:
还有一种RNN在工业上广泛使用,即机器翻译,将一种语言的输入句翻译成另一种语言。这是一个多对多的问题,输入序列的长度可能等于也可能不等于输出序列的长度。
在这种情况下,我们有编码器和解码器。编码器读取输入语句,解码器将其转换为输出语句:
3.3 语言模型和序列生成
假设需要建立一个语音识别系统,我们听到一句话:“苹果和梨沙拉很好吃”。该模型将预测什么——“苹果配梨沙拉很美味”还是“苹果和梨沙拉是美味”?
我希望是第二句话!语音识别系统通过预测每个句子的概率来选择句子。
但是又如何来构建语言模型呢?
假设有一个输入语句:
猫平均每天睡15小时
构建语言模型的步骤如下:
我们取第一个输入词并对其进行预测,输出会告诉我们字典中任意单词的概率是多少。第二个输出会告诉我们给定第一个输入字的预测词的概率:
RNN模型中的每一步都会查看前面的一组单词,以预测下一个单词。训练RNN模型会遇到各种各样的挑战,这将在下一节进行讨论。
3.4 RNN的梯度消失
循环神经网络的最大问题之一是它会陷入梯度消失。怎么回事?我们来考虑这两个句子:
那只猫吃了一堆食物,已经吃饱了。
猫已经吃了一堆食物之后,都已经吃饱了。
以上两个句子中哪一句语法正确?是第一句。(如果你错过了请再读一遍!)
基本RNN不擅长捕获长期依赖项,这是因为在反向传播过程中,来自输出Y的梯度将很难传播回来,从而影响先期层的权重。因此,在基本RNN中,输出受到更接近该单词的那个输入的影响。
为避免这种情况的发生,我们可以通过设置一个预先定义的阈值来对它们进行剪辑。
3.5 门控循环单元(GRU)
GRU是RNN的一种改进形式。它们在捕获更长范围的依赖关系方面非常有效,并且有助于解决梯度消失问题。在时间步长t中计算激活的公式为:
RNN的隐藏单元如下图所示:
一个单元的输入是来自前一个单元的激活和该时间步长的输入字。在计算该步长的激活和输出的时候,我们在这个RNN中添加一个存储单元,以便记住当前单词以外的单词。来看看GRU的方程:
c<t> = a<t>
其中c是一个存储单元。
在每个时间步长内,将c<的值用以下公式得到的值迭代:
这便是更新c<t>值的候选值。我们还定义了一个更新门,利用这个门的值来决定是否更新存储单元,更新门的方程为:
请注意,因为使用来计算更新值,所以,更新门的输出总是在0和1之间。我们使用先前的存储单元值和更新门输出来更新存储单元。c<t>的更新方程如下:
当门值为0时,c<t> = c<t-1>,即不更新c<t>;;当门值为1时,c<t> = c<t>,对值进行更新。举一个例子来理解这一概念:
当遇到cat这个词时,门(gate)值为1;对于序列中的所有其他单词,门(gate)值为0,因此cat的信息将被携带到单词“was”。我们期望模型能预测到单词were的地方应该是was。
GRUS就是通过这种方式来助力于记忆长期依赖关系,下面是这个可视化工具,会有助于你理解GRU工作原理:
每个单元均有三个输入:a<t-1>, c<t-1> 和x<t>,以及三个输出:a<t>, c<t> 和 y(hat)<t>。
3.6 长期短期记忆(LSTM)
当前,LSTM在深度学习中非常流行。由于它们的复杂性,现在可能没有很多工业应用程序,但请相信我,它们很快就会出现。花点时间学习这个概念是值得的——将来它会派上用场。
为了更好地理解LSTM,让我们一起回顾一下在GRU那个小节中看到的所有方程:
在计算c<t>的相关性时,只是添加了一个门(gate),而这个门(gate)告诉我们c<t-1>与c<t>的更新值之间是如何相关的,对于GRUs来说, a<t> = c<t>。
LSTM是增强版的GRU,它的应用更为普遍。LSTM的方程式为:
这和GRU的类似,对吧?我们只是使用a<t-1>取代了c<t-1>。更新门的公式也可以写为:
在LSTM中,还有一个遗忘门和一个输出门。这些门的方程与更新门的方程相类似:
最后,将c<t>的值更新为:
下一层的激活将是:
你会使用哪种算法——GRU还是 LSTM?
每种算法都有各自的优点。你会发现:它们的准确度取决于你试图解决的问题的类型。GRU的优势在于它有一个更简捷的架构,因此我们可以用它来构建一些大的模型,然而, LSTM则更为强大和有效,因为它有3个门。
3.7 双向RNN
到目前为止,我们看到的RNN架构只关注序列中先前的信息。如果我们的模型能够同时考虑到序列的先前信息和后续信息,同时在特定的时间步长中进行预测,那会有多棒啊?
是的,这完全有可能做到!欢迎来到双向RNN的世界。但是在介绍双向RNN以及它们的工作原理之前,还是让我们先看看为什么需要它。
来看看一个命名实体识别问题,我们想知道序列中的一个单词是否代表一个人名。看看下面这个例子:
他说:“泰迪熊在打折!“
如果我们把这个句子输入一个简单的RNN,模型会预测“Teddy”是一个人的名字。它没有考虑到这个词后面会发生什么。通过双向RNN,可以解决这个问题。
现在假设我们有一个4个单词的输入序列,双向RNN看起来像:
利用以下公式,计算RNN单元的输出:
同样,可以有双向GRU和双向LSTM。使用双向RNN的缺点是,在进行预测之前,必须先查看整个数据序列。但是,标准的B-RNN算法对于构建和设计大多数NLP应用程序时,效率是非常高的。
3.8 深度RNN
还记得深度神经网络的样子吗?
它有一个输入层,一些隐藏层和一个输出层。深度RNN也类似,它采用相似的网络架构并在时间轴上展开:
这里,激活函数的表示法如下:
假设需要计算a[2]<3> :
这是为深度RNN准备的。深呼吸,这些内容是不是不难消化?后续请关注模块2:自然语言处理(NLP)和单词嵌入的学习!
译者简介
陈之炎,北京交通大学通信与控制工程专业毕业,获得工学硕士学位,历任长城计算机软件与系统公司工程师,大唐微电子公司工程师,现任北京吾译超群科技有限公司技术支持。目前从事智能化翻译教学系统的运营和维护,在人工智能深度学习和自然语言处理(NLP)方面积累有一定的经验。业余时间喜爱翻译创作,翻译作品主要有:IEC-ISO 7816、伊拉克石油工程项目、新财税主义宣言等等,其中中译英作品“新财税主义宣言”在 TIMES正式发表。能够利用业余时间加入到THU 数据派平台的翻译志愿者小组,希望能和大家一起交流分享,共同进步
— 完 —
关注清华-青岛数据科学研究院官方微信公众平台“THU数据派”及姊妹号“数据派THU”获取更多讲座福利及优质内容。