第14周-序列模型和注意力机制

基础模型

Sequence to sequence model(encoder-decoder network)

论文标题:

  1. Sequence to sequence learning with neural networks, 2014
  2. Learning phrase representations using RNN encoder-decoder for statistical machine translation, 2014

假设我们要翻译以下句子(法语->英语):
image.png

首先,我们需要建立一个网络,该网络称为encoder network(编码网络),它是一个RNN网络,其中RNN的单元可以是GRU,也可以是LSTM。每次只向该网络中输入一个法语单词,将整个句子输入完毕后,RNN会输出一个向量来代表这个输入序列。
image.png

在之后,我们需要建立一个decoder network(解码网络),它以编码网络的输出作为输入,然后可以被训练为每次输出一个翻译后的单词。一直到它输出序列的结尾或者句子结尾标记,那么这个解码网络的工作就结束了。
image.png

在给出足够的法语和英语文本的情况下,如果我们训练这个模型,通过输入一个法语句子来输出对应的英语翻译,这个模型将会非常有效。

Image captioning

论文标题:

  1. Deep captioning with multimodal recurrent neural network, 2014
  2. Show and tell: Neural image caption generator, 2014
  3. Deep visual-semantic alignments for generating image descriptions, 2015

还有一个非常类似的结构被用来做图像描述。

比如给定一张图片,如这张猫的图片,我们希望网络能够自动地输出该图片的描述:一只猫坐在椅子上。方法如下:在之前的图像课程中我们知道了如何将图片输入到卷积神经网络中,比如一个预训练的AlexNet结构,然后让其学习图片的编码或者学习图片的一系列特征。如下,如果我们去掉最后的Softmax层,那么这个预训练的AlexNet结构会给我们一个4096维的特征向量,而向量表示的就是这只猫的图片。。
image.png

因此,这个预训练网络可以是图像的编码网络(encoder network),接着我们可以把输出的向量输入到RNN中,而RNN要做的就是生成图像的描述,这与我们之前所讲的英语法语翻译的结构很类似。事实证明这个方法在图像描述的领域中很有效,特别是当我们想生成的描述不是很长时。
image.png

Summary

现在我们知道了Seq2Seq模型和图像描述模型是怎样运作的,不过这两个模型的运作方式有一些不同,主要体现在如何用语言模型合成新的文本,并生成对应序列的方面。

Picking the most likely sentence

在seq2seq机器翻译模型和我们在第一周课程里所用的语言模型之间有很多相似的地方,也有很多重要的区别。

我们可以把机器翻译想成是建立一个条件语言模型。下图先给出我们在学习序列模型第一周语言模型时所给出的网络结构:
image.png
这个模型可以让我们估计句子的可能性,我们也可以用其生成一个新的句子。

而机器翻译模型长的是下面这样,其中绿色表示encoder网络,而紫色表示decoder网络。
image.png
所以机器翻译模型与语言模型很相似,不同在于语言模型总是以零向量开始,而encoder网络会计算出一系列句子并将其输入到decoder网络中。因此我们称其为条件语言模型。相比语言模型是输出任意句子的概率,翻译模型会输出句子的英文翻译,这取决于输入的法语句子。也就是说,我们估计这句英文翻译的概率,比如”Jane is visiting Africa in September”,这句翻译取决于法语句子”Jane visited I’Afrique en septembre”,这就是英语句子相对于输入的法语句子的可能性,所以它是条件语言模型。
image.png

下面我们希望能够利用上面的模型实现法译英。通过输入的法语句子,模型会告诉我们各种英文翻译所对应的可能性(概率)。
image.png
其中,x在这里是法语句子,而y这里对应不同英语句子翻译的概率。显然我们不希望它随机地进行输出,如果我们从这个分布中进行取样,我们可能会得到各种不同的翻译,可能有的糟糕,有的还可以:
image.png

所以当我们使用这个模型来进行翻译时,我们并不是从得到的分布中进行随机采样,而是要找到一个英语句子y,使得条件概率最大化。所以在开发机器翻译系统时,我们需要做的一件事就是想出一个算法,用来找到合适的y值,使得该项最大化。而解决这个问题的算法称为Beam Search(束搜索)。

在下一节介绍束搜索前,我们需要了解为什么不使用贪心搜索。这是一种来自计算机科学的算法,在生成第一个词的分布之后,它会根据我们的条件语言模型挑选出最有可能的第一个词,放入机器翻译模型中,接着它会继续挑选出最有可能的其他词。
image.png
但是我们真正需要的是一次性挑选出整个单词序列,从y<1>、y<2>到y,来使得整体的概率最大化。所以这种贪心算法是先挑出最好的第一个词,在这之后再挑最好的第二个词,这样一直挑选下去,而这种方法其实并不管用。

为了证明整个观点,我们考虑下面两种翻译:
image.png
显然第一个翻译要好于第二个,所以我们希望机器翻译模型可以说第一个句子的p(y|x)比第二个句子高。但如果贪心算法挑选出了”Jane is”这两个词,而由于”is going”在英语中更加常见,所以对于法语句子来说”Jane is going”要比”Jane is visiting”会有更高的概率,所以很有可能如果我们仅仅根据前两个词来估计第三个词的可能性,我们最后得到的会是第二个句子,但这个句子显然比第一个差。
image.png

当然,在英语中各种词汇的组合数量还有许多,所以如果我们的字典中有10,000个单词,并且我们的翻译可能有10个词长,那么可能的组合就是10,000^10那么多。所以可能的句子数量非常巨大,我们不可能计算每一种组合的可能性,所以此时最常用的办法是用一个近似的搜索算法,这个近似的搜索算法做的就是尽力挑选句子使得条件概率最大化。
image.png
尽管这不可能保证找到的句子是条件概率最大化,但这也足够了。

因此接下来,我们需要一个合适的搜索算法。

集束搜索:Beam Search

下面用我们之前所举的法语句子为例讲述beam search算法。
image.png

首先我们用这个网络结构来评估第一个单词的概率值,而贪婪算法只会挑出最有可能的一个单词然后继续,而集束搜索则会考虑多个选择。因此集束搜索会有一个参数B,全称为Beam width,在本例中设置为3。这就意味着集束搜索会一次性考虑3个可能的选择。比如对于第一个单词有不同选择的可能,最后找到in、jane、september是最有可能的三个选项,那么集束搜索算法会把结果存到计算机内存中,以便后面尝试用这三个词。

因此为了执行beam search的第一步,我们需要输入法语句子到编码网络,然后第一步,也就是解码网络的softmax层会输出10,000个概率值,在这10,000个输出的概率值取出前三个存起来。
image.png

在将in、jane、september作为第一个单词的三个可能选择后,beam search所做的第二步是针对每个选择,考虑第二个单词是什么。为了评估第二个词的概率值,我们会用下面这个神经网络。
image.png
将y<1>(假设为in)的输出作为输入,从而可以评估第二个单词的概率。需要注意的是,在第二步里我们更关心的是找到最可能第一个和第二个单词对,而不是仅仅第二个单词具有最大概率。而具体的计算公式如下:
image.png
因此对于第一个单词的三个候选选择,我们可以保存它们对应的概率值,然后再乘以第二个概率值,从而得到两个单词对的概率值。

对应预测单词jane后的第二个单词,相似网络如下:
image.png

同样的,对于september:
image.png

那么我们通过上述的第二步,最后可以得到10,000*3种结果,也就是30,000个可能的结果,即集束宽乘以词汇表大小。而我们要做的就是评估这30,000个选择,然后选出前三个选择,假设选出来的是in september、jane is和jane visits。那么我们注意到,第一个单词的september已经没有可能了,但现在我们还是有3个选择。另外,由于我们的集束宽为3,因此我们会有三个网络副本,每个网络的第一个单词不同。

接下来简要讲第三步,类似上面的网络:
image.png

再继续同样的步骤,直到达到EOS标记。注意到,如果B=1,那么集束搜索就相当于前面所讲的贪婪搜索。

Length normalization

我们知道束搜索所做的是最大化下面的乘积概率:
image.png

如果计算这些概率值,而这些概率值通常是远小于1,将它们相乘最后会造成数值下溢。因此在实际操作时我们不会真的计算乘积,而是取log值。而最大化这个log求和的概率值,也相当于最大化上面的乘积,得到相同的结果。因此通过取log,我们会得到一个数值上更稳定的算法,不容易出现数值的舍入误差。因为对数函数是严格单调递增的函数,而我们要最大化P(y|x),因此最大化logP(y|x)和最大化P(y|x)的结果一样。
image.png

而这个目标函数有一个潜在的缺点,就是它会更偏向简短的翻译结果,因为短句子的概率是由更少的小于1的数字乘积得到的,对取log后的目标函数也是一样。因此我们对目标函数做另一个改变,即对这些数值做归一化,从而消除长短句的影响:
image.png

但通常上,我们不会直接除以Ty,而是会采取更加柔和的方法,即在Ty上加上指数alpha,alpha=0.7。如果取alpha=1,就是直接除以Ty;而如果alpha=0,那么便没有归一化。
image.png
需要明确的是,这个超参数alpha(可调整)的设置并没有理论验证,而是大家都发现在实践中效果很好,所以很多人会这么做。

总结,在集束搜索中,我们会得到许多不同长度的句子,从1到可能最大设置为30之类的。然后我们针对这些所有的可能的输出句子,用上式对它们打分,取出概率最大的几个句子,再对这些束搜索得到的句子计算这个目标函数,最后从经过评估的这些句子中,挑选出在归一化的log概率目标函数上得分最高的一个。(A normalized log likelihood objective)

Beam search discusstion

如何选择B呢?如果B选择大,那么我们的计算代价也会很大,因为我们要把更多的可能选择保存起来。因此这里总结一下关于如何选择beam width的想法。

首先,我们知道B的大小会有以下影响:
image.png

对一般的产品系统而言,B一般选择为10;而对于科研而言,人们想压榨出全部的性能,也经常能够看到大家用束宽为1000或者3000。因此在实现我们的应用时,尝试不同的束宽值,当B很大的时候,性能提高会越来越小。因此对一般应用而言,我们可以从1到3到10这样调整。

另外,与BFS和DFS进行对比:Unlike exact search algorithms like BFS(Breadth First Search) and DFS(Depth First Search), Beam Search runs faster but is not guaranteed to find exact maximum for argmax_y(y|x)。

集束搜索是一种近似搜索算法,也被称作启发式搜索算法。它不总是输出可能性最大的句子,而仅记录着B为前3或者10或是100种可能。如果束搜索算法出现错误,我们就可以用误差分析来发现问题的来源,看看是束搜索算法出现问题,还是我们的RNN模型出现问题。

假设给定以下例子,其中y*为最标准答案,而y^则是我们算法预测的结果,很明显是糟糕的翻译,其改变了句子的原意。
image.png

而我们的模型有两部分,一个部分是RNN模型(即encoder-decoder模型),另一部分是束搜索算法。我们需要知道是哪一部分出现了问题。
image.png

为了知道是哪个部分出现问题,我们需要使用RNN模型计算P(y*|X)和yP(y^|x),需要注意我们要比较的是归一化后的最优化目标函数值。我们可以有以下结论:

image.png

整个误差分析过程如下:
image.png
经过这样的误差分析过程,我们就可以对验证集(dev set)中每一个错误例子,即算法输出了比人工翻译更差的结果的情况,我们可以尝试确定这些错误是搜索算法出了问题,还是生成目标函数的RNN模型出了问题。只有当我们发现束搜索算法造成了大部分错误时,才值得花费努力增大集束宽度;如果我们发现是RNN出错,我们可以考虑是增加正则化还是获取更多训练数据,亦或是尝试其他的网络结构。

这就是束搜索中的误差分析。这个特定的误差分析过程是十分有用的,它可以用于分析近似最佳算法(如束搜索算法),这些算法被用来优化学习算法(例如序列到序列模型/RNN)输出的目标函数。

BLEU分数

论文标题:A method for automatic evaluation of machine translation, 2002

Evaluating machine translation

机器翻译的一大难题是比如给定一个法语句子,可以有多种英文翻译,而且都同样好。那么当具有多种同样好的翻译结果时,应该怎样评估一个机器翻译系统呢?常见的办法是通过BLEU得分来解决。

比如下面的一个法语句子,两个翻译结果都很好:
image.png

而BLEU得分做的就是给定一个机器生成的翻译,它能够自动地计算一个分数来衡量机器翻译的好坏。而只要我们的翻译和人工翻译的结果足够接近,那么它就会得到一个高的BLEU分数。另外,BLEU的全称是bilingual evaluation understudy(双语评估替补)。BLEU分数背后的理念是观察机器生成的翻译,然后看生成的词是否出现在至少一个人工翻译参考之中。因此这些人工翻译的参考会出现包含在验证集或是测试集中。

下面看一个极端的例子。我们假设机器翻译系统(MT)输出了这样一个结果,显然是很糟糕的翻译。
image.png
衡量机器翻译输出质量的方法之一是观察输出结果的每一个词看是否出现在人工翻译参考之中,这被称为机器翻译的精确度(a precision of the machine translation output)。这个情况下,机器翻译输出了7个词,并且每个词都出现在了参考1或参考2中,因此看上去每个词都很合理,所以这个输出的精确度为7/7。然而这显然不正确,因此这就是为什么把出现在参考中的词在MT输出的所有词中所占的比例作为精确度评估标准并不是很有用的原因。
image.png
因此,我们取而代之的是用改良后的精确度评估方法(modified precision),我们把每一个单词的记分上限定为它在参考句子中出现的最多次数。因此在本例中,the在参考1中出现两次,在参考2中出现1次,因此其得分上限为2。因此我们说,这个输出句子的得分为2/7,其中分母就是7个词中单词the总共出现的次数,而分子就是单词the出现的计数,达到上限(在参考句子中的最大出现次数)时就截断计数

Bleu score on bigrams

在前面我们都只考虑了单个的单词,但我们也需要考虑成对的单词。接下来我们定义二元词组上的(bigram:指相邻的两个单词)的BLEU得分。(也有可能为三元词组trigram)

还是上面的例子,但是我们假设机器翻译出了较之前好一些的结果。
image.png
在该翻译上的二元词组有如下几个:
image.png
分别计算二元词组的出现次数以及他们的截断值,以及最后计算得到的精确度为:
image.png

更加具体的公式如下,评估的是一元词组乃至n元词组,从而知道机器翻译结果与人工参考翻译相似重复的程度。
image.png

另外,我们可以确信,如果机器翻译结果与人工翻译结果一致,那么P1等等都会等于1。因此为了达到1.0的改良精确度,我们只需要与人工翻译结果其中的一个完全一致就好了。

Bleu details

image.png
我们会加一个BP = “brevity penalty”(简单惩罚)。事实表明如果我们输出了一个非常短的翻译,那么它更容易得到了一个非常短的翻译,那么它会更容易得到一个高精确度,因为输出的大部分词都可能出现的人工参考中。因此BP就是一个调整因子,来惩罚输出了太短输出结果的翻译系统。

在之前的讲解中,我们知道拥有单一实数评估指标(a single real number evaluation metric)的重要性,它使得我们可以尝试不同想法,然后选取最好的。因此,BLEU分数对于机器翻译来说,具有革命性的原因是因为它有一个相当不错的(尽管不是完美的)但是非常好的单一实数评估指标,从而加快了整个机器翻译领域的进程。实践中,很少人会从零实现一个BLEU分数,如今有很多开源的实现结果。不过今天,BLEU分数被用来评估许多生成文本(generate text)的系统,比如机器翻译系统,也有图像描述系统,即我们用神经网络生成图像描述,然后用BLEU分数看看是否与参考描述相符。

不过,BLEU没有用于语音识别,因为在语音识别中通常只有一个答案,评估语音识别结果我们可以看是否十分相近或是字字正确(exactly word for word correct)。不过,在图像描述应用中,对于同一图片的不同描述,可能是同样好的。总之,BLEU很重要,能够自动评估翻译结果,从而帮助加快算法开发进程。

注意力模型

论文标题:

  1. Neural Machine Translation by Jointly Learning to Align and Translate, 2014(首次提出attention)
  2. Show attention and tell: neural image caption generation with visual attention, 2015

注意力模型已经是深度学习领域中最重要的思想之一。下面开始解释。

·
假设给定一个很长的法语句子。
image.png
在我们的神经网络中,这个绿色的编码器要做的就是读整个句子并且记忆,然后在感知机中传递,而对于紫色的解码网络则将生成英文翻译。其实,人工翻译并不会通过读整个法语句子,再记忆里面的东西,然后从零开始机械式地翻译成一个英语句子。人工翻译首先可能会先翻译出句子的部分,再看下一部分,并翻译,再一直这样下去。我们可以通过一点点地翻译,因为记忆整个长句子是非常困难的。

因此对于上面的网络,它对于短句子翻译的效果很好,能够有较高的BLEU分数,但对相对长的句子(比如大于30或40个单词的句子),它的表现就会变差。
image.png

而有了注意力模型,我们会发现它的翻译过程和人类很像,即一次只翻译句子的一部分,因此我们也不会看到BLEU分数巨大的下倾(huge dip)。而这个下倾实际上衡量了神经网络记忆一个长句子的能力,这是我们不希望看到的。
image.png

Attention model intuition

我们举一个短句来理解注意力模型。我们用双向RNN来对句子中的单词特征集进行计算,然后用另一个RNN来进行翻译。
image.png
当尝试生成句子的第一个单词翻译时,我们的输入包括S<0>,以及对句子中上下文单词的注意力。直观来想,RNN向前进,一次生成一个词,直到最后生成<EOS>,而alpha<t,t’>告诉我们,当我们在翻译第t个英文词时,应该将多少注意力放置在t’个法语单词上,这允许它在每个时间步会去看周围词距内的法语词要花多少注意力。

Attention model

image.png

这个alpha参数告诉我们上下文有多少取决于我们得到的特征或者我们从不同时间步得到的激活值。所以我们定义上下文的方式实际上来源于被注意力权重加权的不同时间步中的特征值(激活值)。因此更加公式化的注意力权重将会满足非负的条件,它们加起来等于1。
image.png

另外,我们也会输入上下文,对应的公式为:
image.png
其中,a<t’>等于前向和后向的激活值:
image.png

因此,alpha就表示y应该在t'时花在a上的注意力(amount of "attention" y should pay to a)。换句话说,当我们在t处生成输出词,我们应该花多少注意力在第t’个输入词上面,这是生成输出的其中一步。随后下一个时间步,我们会生成第二个输出,相似的,我们有了一个新的注意力权重集,再找到一个新的方式将他们相加,这就产生了一个新的上下文,允许我们生成第二个词。
image.png

为了更加清楚,这里采用原论文的图片进行理解:
image.png

接下来需要了解如何计算注意力权重集。

计算注意力权重

从上一节,我们知道:
image.png
其中,y表示第t个输出词,a<t’>表示第t’时间步的激活值。

我们用下面的式子来计算alpha<t,t’>。
image.png

因此在此之前,我们需要计算e,然后用softmax计算出上述注意力权重值,保证和为1。如何计算e呢,我们用下面的这个小型神经网络: ![image.png](https://upload-images.jianshu.io/upload_images/8636110-2161008f31e0f7e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 其中,s就是神经网络在上个时间步的隐藏状态,然后a则为另一个输入。直观来想就是,如果我们想要决定要花多少注意力在t’的激活值上,那么它在很大程度上取决于我们上一个时间步的隐藏状态的激活值。但我们还没有当前状态的激活值,所以我们会看看生成上一个翻译的RNN的隐藏状态,然后对于每一个位置都看看他们的特征值,因此a和e取决于这两个量。
image.png

这个算法的缺点是它要花费三次方的时间,即时间复杂度为O(n^3)。因此如果我们有Tx个输入单词和Ty个输出单词,那么注意力参数的总数会是Tx * Ty。但是在机器翻译的应用中,输入和输出的句子一般不会太长,不过现在也有很多研究在尝试减少这样的消耗。另外也有一篇类似的image captioning论文运用了类似的思想。

Attention examples

image.png

语音识别:Speech recognition

image.png
首先简单介绍语音识别的流程。假设我们说一个音频片段为”the quick brown fox”,
image.png
我们希望一个语音识别算法(speech recognition algorithm),通过输入这段音频,然后输出音频的文本内容。考虑到人的耳朵并不会处理声音的原始波形,而是通过一种特殊的物理结构来测量这些不同频率和强度的声波。因此音频数据的常见预处理步骤,就是运行这个原始的音频片段,然后生成一个声谱图(spectrogram)。
image.png
横轴是时间,纵轴是声音的频率,而图中的不同颜色显示了声波能量的大小(the amount of energy),也就是不同的时间和频率上这些声音有多大。

以前的语音学家都是通过基本的音位单元(basic units of sound called phonemes)来表示音频(audio),然后在end-to-end模型中,我们发现这种音位表示法已经不再必要了,而是可以构建一个系统,通过向系统中输入音频片段(audio clip),然后直接输出音频的文本。使这种方法成为可能的一件事是使用一个很大的数据集,所以语音研究的数据集一般会超过300个小时,而商业系统已经训练出了上万个小时的数据。在文本音频数据集(transribe audio data sets)同时包含x和y,通过深度学习算法大大推进了语音识别的进程。接下来讲解如何建立一个语音识别系统。

Attention model for speech recognition

image.png

我们可以这样做:在横轴上,也就是在输入音频的不同时间帧上,我们可以用注意力模型来输出文本描述。

CTC cost for speech recognition

论文标题:Connectionist Temporal Classification: Labeling unsegmented sequence data with recurrent neural networks, 2006.

CTC的全称为Connectionist Temporal Classification。它的算法思想如下:

假如语音片段内容是某人说”the quick brown fox”,这时候我们使用一个新的网络,结构如下:
image.png

其中,其输入的x和输出的y数量是一样的,另外,尽管这里画的只是一个简单的单向RNN结构,但实际上它有可能是双向的LSTM结构或者双向的GRU结构,并且通常是很深的模型。需要注意,在语音识别中,通常输入的时间步数量(the number of input time steps)要比输出的时间步数量(the number of output time steps)多出很多。举例:假设有一段10秒的音频,并且特征是100赫兹的,即每秒有100个样本,于是这段10秒的音频片段就有1000个输入。但我们的输出就没有1000个字母或字符,这时候CTC损失函数允许RNN生成这样的输出:
image.png
这句输出对应的是”the q”。CTC损失函数的一个基本规则是将空白符之间的重复字符折叠起来,注意空白符和空格符是不一样的。比如,上图中我们发现空格符是短下划线两边还有两个竖杠,从而用于区分空白符和空格符。

因此,尽管我们的文本只有”the quick brown fox”包括空格一共有19个字符,但在这样的情况下,通常允许神经网络有重复的字符和插入空白符来使其强制输出1000个字符。

触发字检测:Trigger word detection

image.png

下面简单介绍一个能够实现的算法:

如果刚探测到一个触发字,将对应时间的目标标签设为1,之后的设为0;如果再遇到触发词,也设置为1。很明显这是一个非平衡数据集,0的数量比1多很多。

解决方法:
image.png
实际上没听懂这里,看看编程能不能懂。

本周作业

完成,向NLP继续进军。