5-3 Coursera吴恩达《序列模型》 第三周课程笔记-序列模型和注意力机制

上一周的课程5-2 Coursera吴恩达《序列模型》 第二周课程笔记-自然语言处理和词嵌入介绍了自然语言处理相关内容,例如词汇表征、词嵌入、嵌入矩阵和负采样等概念,以及Word2Vec和GloVe算法。本周的课程接着介绍序列模型和注意力机制的相关知识,让我们开始吧。

目录

《3.1 序列结构的各种序列》Various sequence to sequence architectures

《3.2 选择最可能的句子》Picking the most likely sentence

《3.3 集束搜索》Beam Search

《3.4 改进集束搜索》Refinements to Beam Search

《3.5 集束搜索的误差分析》Error analysis in beam search

《3.6 Bleu 得分(选修)》Bleu Score (optional)

《3.7 注意力模型直观理解》Attention Model Intuition

《3.8注意力模型》Attention Model

《3.9语音识别》Speech recognition

《3.10触发字检测》Trigger Word Detection

《3.11结论和致谢》Conclusion and thank you

《3.1 序列结构的各种序列》Various sequence to sequence architectures

欢迎来到本次课程的最后一周的内容,同时这也是五门深度学习课程的最后一门,你即将抵达本课程的终点。

seq2seq(sequence to sequence)模型在深度学习的应用中起到不错的作用,我们具体来看看。

如上图所示,输入一个法语句子 “Jane visite I'Afrique en septembre.”,将它翻译成英语“Jane is visiting Africa in September.”。我们用x^<1>一直到x^<5>来表示输入的句子的单词,然后我们用y^<1>到y^<6>来表示输出的句子的单词,那么,如何训练出一个新的网络来输入序列x和输出序列y呢?

这里的一些方法主要都来自于这两篇论文:①Sutskever,Oriol Vinyals 和 Quoc Le的Sequence to sequence learning with neural networks。②Kyunghyun Cho,Bart van Merrienboer,Caglar Gulcehre,Dzmitry Bahdanau,Fethi Bougares,Holger Schwen 和 Yoshua Bengio的Learning phrase representations using RNN encoder-decoder for statistical machine translation

首先,我们先建立一个网络,这个网络叫做编码网络(encoder network)(上图记号1),这里的RNN的单元可以是GRU和LSTM。每次只向该网络中输入一个法语单词,将输入(input)序列接收完毕后,这个RNN网络会输出(output)一个向量来代表这个输入序列。之后你可以建立一个解码网络(decoder network)(上图记号2),它以编码网络的输出作为输入(input),编码网络是左边的黑色部分(记号1),之后它可以被训练为每次输出(output)一个翻译后的单词,一直到它输出序列的结尾或者句子结尾标记。和往常一样我们把每次生成的标记都传递到下一个单元中来进行预测。

深度学习在近期最卓越的成果之一就是这个模型确实有效,在给出足够的法语和英语文本的情况下,如果你训练这个模型,通过输入一个法语句子来输出对应的英语翻译,这个模型非常有效。这个模型简单地用一个编码网络来对输入的法语句子进行编码,然后用一个解码网络来生成对应的英语翻译。

如上图,图像描述(image captioning)有类似的结构,给出一张猫的图片,它能自动地输出该图片的描述,一只猫坐在椅子上,那么如何训练出这样的网络?

在之前的学习中,我们知道如何将图片输入到卷积神经网络中,比如一个预训练的AlexNet结构(上图记号1),然后让其学习图片的编码或者图片的特征。现在我们去掉最后的softmax单元(上图记号2),这个预训练的AlexNet结构会得到一个4096维的特征向量(feature vector),表示这只猫的图片,所以这个预训练网络可以是图像的编码网络。现在我们用4096维的向量来表示这张图片,接着把这个向量输入到RNN中(上图记号3方框),RNN要做的就是生成图像的描述,每次生成一个单词,这和机器翻译中看到的结构很像,现在输入(input)一个描述输入的特征向量,然后让网络生成一个输出序列,或者说一个一个地输出(output)单词序列。

事实证明在图像描述领域,这种方法相当有效,特别是生成的描述长度不是特别长

以上就是基本的seq2seq模型是怎样运作的,以及image to sequence模型或者说图像描述模型是怎样运作的。

《3.2 选择最可能的句子》Picking the most likely sentence

seq2seq机器翻译模型和我们在之前学习的语言模型之间有很多相似的地方,但是它们之间也有许多重要的区别,让我们来具体看看。

如上图第一行,是一个条件语言模型(conditional language model),这个模型可以估计句子的可能性,也可以用它来生成一个新的句子,输入x^<1>和x^<2>,那么x^<2> = y^<1>,但是x^<1>和x^<2>等在这里并不重要。为了让图片看起来更简洁,先把它们抹去,如果定义x^<1>为一个全为0的向量,然后x^<2>和x^<3>等都等于之前所生成的输出,这就是所说的语言模型。

上图第二行是机器翻译模型(machine translation model)用绿色表示encoder网络(编码网络),紫色表示decoder网络(解码网络)。注意到decoder网络(紫色部分)看起来和刚才所画的语言模型几乎一模一样,机器翻译模型其实和语言模型很相似,不同在于语言模型总是以零向量(上图中的a^<0>)开始,而encoder网络(绿色部分)会计算出一系列向量来表示输入的句子。有了这个输入句子,decoder网络(紫色部分)以这个句子开始,而不是以零向量开始,因此这个模型叫做条件语言模型(conditional language model)。相比语言模型,输出任意句子的概率,翻译模型会输出句子的英文翻译,这取决于输入的法语句子。换句话说,我们将估计一个英文翻译的概率,比如估计这句英语翻译的概率,"Jane is visiting Africa in September.",这句翻译是取决于法语句子,"Jane visite I'Afrique en septembre.",这就是英语句子相对于输入的法语句子的可能性,所以它是一个条件语言模型。

如上图,假如你想真正地通过模型将法语翻译成英文,通过输入的法语句子模型将会告诉你各种英文翻译所对应的可能性。在这里x是法语句子"Jane visite l'Afrique en September.",而它将告诉你不同的英语翻译所对应的概率。显然我们不想让它随机地进行输出,如果从这个分布中进行取样得到P(y|x),可能取样一次就能得到很好的翻译,"Jane is visiting Africa in September."。但是也可能得到这个截然不同的翻译,"Jane is going to be visiting Africa in September.",这句话听起来有些笨拙,但它不是一个糟糕的翻译,只是不是最好的而已。当然也可能得到这个翻译,"In September, Jane will visit Africa.",或者有时候你还会得到一个很糟糕的翻译,"Her African friend welcomed Jane in September."。所以当我们使用这个模型来进行机器翻译时,并不想从得到的分布中进行随机取样,而是找到一个英语句子y使得条件概率最大化(maximizes that conditional probability)。所以在开发机器翻译系统时(in developing a machine translation system),需要想出一个算法,用来找出合适的y值,使得该项最大化,而解决这种问题最通用的算法就是束搜索(Beam Search),之后会见到它。

不过在了解束搜索之前,思考一下,为什么不用贪心搜索(Greedy Search)呢?

贪心搜索是一种来自计算机科学的算法,生成第一个词的分布以后,它将会根据你的条件语言模型挑选出最有可能的第一个词进入你的机器翻译模型中,在挑选出第一个词之后它将会继续挑选出最有可能的第二个词,然后继续挑选第三个最有可能的词,这种算法就叫做贪心搜索,但是你真正需要的是一次性挑选出整个单词序列,从y^<1>、y^<2>到y^<T_y>来使得整体的概率最大化。所以这种贪心算法先挑出最好的第一个词,在这之后再挑最好的第二词,接着再挑第三个,这种方法其实并不管用,我们来考虑下面两种翻译来证明这个观点。

第一行翻译明显比第二行好,所以我们希望机器翻译模型会说第一个句子的P(y|x)比第二个句子要高,第一个句子对于法语原文来说更好更简洁。但如果贪心算法挑选出了"Jane is"作为前两个词,因为在英语中going更常见,于是对于法语句子来说"Jane is going"相比"Jane is visiting"会有更高的概率作为法语的翻译,所以很有可能如果你仅仅根据前两个词来估计第三个词的可能性,得到了going,最终将会得到一个欠佳的句子(a less optimal sentence),在P(y|x)模型中这不是一个最好的选择。

这种说法可能比较粗略,但确实是一种广泛的现象(a broader phenomenon),当我们想得到单词序列y^<1>、y^<2>一直到最后一个词总体的概率时,一次只挑选一个词并不是最佳的选择。当然在英语中各种词汇的组合数量有很多。假设你的字典中有10,000个单词,并且你的翻译可能有10个词,那么可能的组合数就是10,000的10次方,这仅仅是10个单词的情况,从这样大一个字典中来挑选单词,所以可能的句子数量非常巨大,不可能去计算每一种组合的可能性。最常用的办法就是用一个近似的搜索算法,这个近似的搜索算法做的就是它会尽力地,尽管不一定总会成功,但它将挑选出句子y使得条件概率最大化,尽管它不能保证找到的y值一定可以使概率最大化。

以上就是机器翻译的内容,它可以用来解决条件语言模型问题,这个模型和之前的语言模型的一个主要区别就是,之前的模型随机生成句子,而该模型寻找最有可能的英语句子,最可能的英语翻译,但是可能的句子组合数量过于巨大,无法一一列举,因此我们需要一种合适的搜索算法,接下来文章可以看到。

《3.3 集束搜索》Beam Search

我们来看看集束搜索(beam search)算法,上个视频”选择最可能的句子“中讲了对于机器翻译来说,给定输入(法语句子),我们并不想要一个随机的英语翻译结果,而是想要一个最好的,最可能的英语翻译结果。对于语音识别也一样,给定一个输入的语音片段,我们不会想要一个随机的文本翻译结果,而是想要最接近原意的翻译结果,集束搜索就是解决这个最常用的算法。让我们用法语句子的例子来试一下集束搜索吧。

“Jane visite l'Afrique en Septembre.”(法语句子),把它翻译成英语,"Jane is visiting Africa in September."(英语句子),(1)集束搜索算法首先做的就是挑选要输出的英语翻译中的第一个(first)单词。这里Andrew使用10,000个词的词汇表,为了简化问题,这里忽略大小写,所有的单词都以小写列出来。在集束搜索的第一步中用的这个网络部分,绿色是编码部分(encoder),紫色是解码部分(decoder),来评估第一个单词的概率值,给定输入序列x,即法语作为输入,第一个输出y的概率值是多少。

贪婪算法只会挑出最可能的那一个单词,然后继续。而集束搜索则会考虑多个选择,集束搜索算法会有一个参数B,叫做集束宽(beam width)。在这个例子中B=3,这样就意味着集束搜索不会只考虑一个可能结果,而是一次会考虑3个,比如对第一个单词有不同选择的可能性,最后找到in、jane、september,是英语输出的第一个单词的最可能的三个选项,然后集束搜索算法会把结果存到计算机内存里以便后面尝试用这三个词。如果集束宽设的不一样,如果集束宽这个参数是10的话,那么我们跟踪的不仅仅3个,而是10个第一个单词的最可能的选择。所以要明白,为了执行集束搜索的第一步,你需要输入法语句子到编码网络,然后会解码这个网络,这个softmax层(紫色网络的蓝框)会输出10,000个概率值,得到这10,000个输出的概率值,取前三个存起来。

如上图,(2)让我们看看集束搜索算法的第二步,已经选出了第一个单词三个最可能的选择为in、jane、september,集束算法接下来会针对每个第一个单词考虑第二个单词分别是什么,如上图蓝色标记,单词in后面的第二个单词可能是a或者aaron,从词汇表里把这些词列了出来,也可能是september、 visit和z,最后一个单词是zulu。

为了评估第二个词的概率值,我们用这个神经网络,其中绿色是编码部分,紫色是解码部分,当决定单词in后面是什么,别忘了解码器的第一个输出y^<1>是单词in,然后把它喂回来,下一个节点的输入就是单词in,输出是y^<2>,有了这个连接,这个网络就可以用来评估在翻译结果的第一个单词in的情况下第二个单词的概率。

注意,在第二步里我们更关心的是要找到最可能的第一个和第二个单词对,即第一个和第二个单词对有最大的概率(P(y^<1>,y^<2>|x))。按照条件概率的准则,这个可以表示成第一个单词的概率乘以第二个单词的概率,第二部分可以从紫色网络部分里得到(上图紫色所示),对于已经选择的in、jane、september这三个单词,你可以先保存P(y^<1>|x)这个概率值,然后再乘以第二个概率值就得到了第一个和第二个单词对的概率(P(y^<1>,y^<2>|x))。

现在我们已经知道在第一个单词是in的情况下如何评估第二个单词的概率,当第一个单词是jane时,如上图第二行所示,同理,句子可能是"jane a"、"jane aaron",...,"jane is"、"jane visits"等等。用这个新的网络部分,y^<1>连接jane(紫色曲线),得到给定输入x和第一个词是jane下,第二个单词的概率,同理,可以乘以P(y^<1>|x)得到P(y^<1>,y^<2>|x)

如上图第三行所示,最后对于单词september也一样,从单词a到单词zulu,计算出相应的概率。总的来说,对于集束搜索的第二步,因为这里集束宽为3,词汇表里有10,000个单词,那么最终我们会有3*10,000=30,000个可能的结果,就是集束宽乘以词汇表大小,我们要做的就是评估这30,000个选择,选出概率大的前三个。假如这30,000个选择里最可能的是“in September”、“jane is”和“jane visits”(上图红色标记),集束搜索算法会保存这些结果,然后用于下一次集束搜索。

在我们进入集束搜索的第三步之前,注意一下集束宽B=3,每一步我们都复制3个,同样用这种网络来评估部分句子和最后的结果,由于集束宽等于3,我们有三个网络副本(上图橘色标记),每个网络的第一个单词不同,而这三个网络可以高效地评估第二个单词所有的30,000个选择。所以不需要初始化30,000个网络副本,只需要这3个网络的副本就可以快速评估softmax的输出,即y^<2>的10,000个结果。

(3)让我们快速解释一下集束搜索的下一步,给定输入x(法语句子),y^<1>和y^<2>的概率值和前面一样,现在我们考虑第三个单词是什么,可以是“in September a”,“in September aaron”,...,“in September zulu”。为了评估第三个单词可能的选择,我们用这个网络部分(上图第一行),第一单词是in,第二个单词是september,所以这个网络部分可以用来评估在给定输入的法语句子x和给定的英语输出的前两个单词“in September”情况下,第三个单词的概率。对于“jane is”和“jane visits”也一样,然后集束搜索还是会挑选出针对前三个词的三个最可能的选择,可能是“in september jane”、“Jane is visiting”或者“Jane visits Africa”(红色标记)。

(4)然后继续进行集束搜索的第四步,过程同上,最终这个过程的输出一次增加一个单词,集束搜索最终会找到“Jane visits africa in september”这个句子,终止在句尾符号(EOS),算法会发现这是最有可能输出的一个英语句子。注意如果集束宽等于1,意味着只考虑1种可能结果,这实际上就变成了贪婪搜索算法。如果同时考虑多个,可能的结果比如3个,10个或者其他的个数,集束搜索通常会找到比贪婪搜索更好的输出结果。

以上就是集束搜索的内容,事实上应用一些额外的提示和技巧的改进能够使集束算法更高效,我们在下个视频中一探究竟。

《3.4 改进集束搜索》Refinements to Beam Search

上个视频介绍了基本的集束搜索(Beam Search),这个视频我们进一步学习一些技巧,能够使算法运行的更好。

如上图,长度归一化(Length normalization)就是对束搜索算法稍作调整的一种方式,帮助你得到更好的结果,下面介绍一下它。

束搜索就是最大化这个概率:

这个乘积也可以表示为如下形式:

这就是乘积概率(the product probabilities)这些概率值通常远小于1。很多小于1的数乘起来,会得到很小很小的数字,会造成数值下溢(numerical underflow)。数值下溢就是数值太小了,导致电脑的浮点表示不能精确地储存,因此实践中在选择最可能的句子y时,我们不会最大化这个乘积,而是取log值,最大化这个log求和的概率值,将得到同样的结果。通过取log,我们会得到一个数值上更稳定的(stable)算法,不容易出现四舍五入的误差,数值的舍入误差(rounding errors)或者说数值下溢(numerical underflow)。最大化P(y)时,因为对数函数(例如log函数)是严格单调递增的函数(a strictly monotonically increasing function),所以最大化logP(y|x)和最大化P(y|x)结果一样。如果一个y值能够使前者最大,就肯定能使后者也取最大。因此在实际工作中,我们总是记录概率的对数和(the sum of logs of the probabilities),而不是概率的乘积(the production of probabilities)。

对于目标函数(this objective function),也可以做一些改变,可以使得机器翻译表现的更好。之前的目标函数(this original objective),如果有一个很长的句子,那么这个句子的概率会很低,因为乘了很多项小于1的数字来估计句子的概率。很多小于1的数字相乘就会得到一个更小的概率值,所以这个目标函数有一个缺点,它可能不自然地倾向于简短的翻译结果,它更偏向短的输出。同时,这里也有同样的问题,概率的log值通常小于等于1,实际上在log的这个范围内,所以加起来的项越多,得到的结果越负,所以对这个算法另一个改变也可以使它表现的更好,我们可以把原目标函数归一化通过除以翻译结果的单词数量(normalize this by the number of words in your translation),即取每个单词的概率对数值的平均,这样做很明显地减少了对输出长的结果的惩罚(this significantly reduces the penalty for outputting longer translations)

在实践中,相比于直接除T_y(输出句子的单词总数),我们有时会用一个更柔和的方法(a softer approach),在T_y上加上指数α,α可以等于0.7。如果α等于1,就相当于完全用长度来归一化,如果α等于0,T_y的0次幂就是1,就相当于完全没有归一化,这就是在完全归一化(full normalization)和没有归一化(no normalization)之间。α就是算法另一个超参数(hyper parameter),需要调整大小来得到最好的结果。这样用α实际上是试探性的,它并没有理论验证。但是大家都发现实践中效果不错,所以很多人都会这么做。我们也可以尝试不同的α值,看看哪一个能够得到最好的结果。

总结一下如何运行束搜索算法。当我们运行束搜索时,会看到很多长度等于1的句子,很多长度等于2的句子,很多长度等于3的句子,等等。可能运行束搜索30步,考虑输出的句子可能达到,比如长度30。因为束宽为3,你会记录所有这些可能的句子长度,长度为1、2、3、4 等等一直到30的三个最可能的选择。然后针对这些所有的可能的输出句子,用这个式子(上图红色方框)给它们打分,取概率最大的几个句子,然后对这些束搜索得到的句子,计算这个目标函数。最后从经过评估的这些句子中,挑选出在归一化的log概率目标函数上得分最高的一个(you pick the one that achieves the highest value on this normalized log probability objective),有时也叫归一化的对数似然目标函数(a normalized log likelihood objective)。这就是最终输出的翻译结果,这就是如何实现束搜索。

最后看看一些实现的细节,如何选择束宽BB越大,我们需要考虑的选择越多,得到的句子可能越好,但是B越大,算法的计算代价越大,因为很多的可能选择要保存起来。如上图所示,我们总结一下关于如何选择束宽B的一些想法。

不同取值的B有各自的优缺点(cons)。(1)如果束宽很大,我们会考虑很多的可能,倾向于得到一个更好的结果,但是算法会运行的慢一些,内存占用也会增大,计算起来会慢一点。(2)如果用小的束宽,结果会没那么好,因为在算法运行中,保存的选择更少,但是算法运行的更快,内存占用也小。在前面的例子中我们用了束宽为3,所以会保存3个可能选择,在实践中这个值有点偏小。在产品中,经常可以看到把束宽设到10,Andrew认为束宽为100对于产品系统来说有点大了,这也取决于不同应用。但是对科研而言,人们想压榨出全部性能,这样有个最好的结果用来发论文,也经常束宽为1000或3000,这也是取决于特定的应用和特定的领域。在实现你的应用时,尝试不同的束宽的值,当B很大的时候,性能提高会越来越少。对于很多应用来说,从束宽等于1(贪心算法:选择最可能的句子中有介绍),到束宽为3到10,你会看到一个很大的改善。但是当束宽从1000增加到3000时,效果就没那么明显了。

对于之前上过计算机科学课程的同学来说,如果你熟悉计算机科学里的搜索算法(computer science search algorithms), 比如广度优先搜索(BFS,Breadth First Search algorithms),或者深度优先搜索(DFS,Depth First Search),你可以这样理解束搜索。不同于这些算法,这些都是精确的搜索算法(exact search algorithms),束搜索运行的更快,但是不能保证一定能找到目标函数准确的最大值。这就是束搜索和其他算法的关系。如果你没听说过广度优先搜索和深度优先搜索,也不用担心,这些对于我们的目标也不重要。

以上就是束搜索的改进方法。束搜索算法广泛应用在多产品系统或者许多商业系统上,在深度学习系列课程中的第三门课中,我们讨论了很多关于误差分析(error analysis)的问题。事实上在束搜索上做误差分析是Andrew发现的最有用的工具之一。有时你想知道是否应该增大束宽,束宽是否足够好,你可以计算一些简单的东西来指导你需要做什么,来改进你的搜索算法,具体情况将在之后介绍。

《3.5 集束搜索的误差分析》Error analysis in beam search

回忆一下,在这五门课中的第三门课3-2 Coursera吴恩达《构建机器学习项目》 第二周课程笔记-机器学习策略(2)中,我们讲解了误差分析是如何能够帮助集中时间做项目中最有用的工作,束搜索算法(beam search)是一种近似搜索算法(an approximate search algorithm),也被称作启发式搜索算法(a heuristic search algorithm),它不总是输出可能性最大的句子,它仅记录着B为前3或者10或是100种可能。那么如果束搜索算法出现错误会怎样呢?

接下来我们将会学习到误差分析和束搜索算法是如何相互起作用的,以及怎样发现是束搜索算法出现了问题,需要花时间解决,还是你的RNN模型出了问题,要花时间解决。我们先来看看如何对束搜索算法进行误差分析。

举个例子,如上图所示,对于法语“Jane visite l'Afrique en septembre”来说,在机器翻译的开发集(development set)中,人工翻译是:Jane visits Africa in September,标记为y*。这是一个十分不错的人工翻译结果。在已完成学习的RNN翻译模型中运行束搜索算法时,它输出翻译结果为:Jane visited Africa last September,标记为y-帽这是一个十分糟糕的翻译,它实际上改变了句子的原意,因此这不是个好翻译

模型有两个主要部分①一部分是神经网络模型,即序列到序列模型(sequence to sequence model),将这个称为RNN模型,它实际上是个编码器和解码器( an encoder and a decoder)。②另一部分是束搜索算法,以某个集束宽度B运行。如果我们能够找出造成这个错误,这个不太好的翻译的原因,是两个部分中的哪一个,不是很好吗? RNN (循环神经网络)是更可能是出错的原因呢,还是束搜索算法更可能是出错的原因呢?然后再采取相应的措施,像第三门课中收集更多的训练数据。所以同样的,也可以尝试增大束宽。不过如何判断我们是不是值得花时间去改进搜索算法呢? 下面我们来分解这个问题弄清楚什么情况下该用什么解决办法。

RNN (循环神经网络)实际上是个编码器和解码器(the encoder and the decoder),它会计算P(y|x)。对于Jane visits Africa in September,将Jane visits Africa填入这里(上图紫色网络),同样,这里忽略了字母的大小写。P(y|x)结果表明,此时能做的最有效的事就是用这个模型来计算P(y*|x),同时也用RNN模型来计算P(y-帽|x),然后比较一下这两个值哪个更大。这取决于实际是哪种情况,就能够更清楚地将这个特定的错误归咎于RNN或是束搜索算法,或说是哪个负有更大的责任。我们来探究一下其中的逻辑(logic)

如上图,计算完P(y*|x) P(y-帽|x),然后比较大小,分析以下两种情况。

(1)第一种情况,RNN模型的输出结果P(y*|x) 大于P(y-帽|x),这意味着什么呢? 束搜索算法选择了y-帽。 你得到y-帽的方式是,用一个RNN模型来计算P(y|x),然后束搜索算法做的就是尝试寻找使P(y|x)最大的y,不过在这种情况下,相比于y-帽,y*的值更P(y|x)大,因此你能够得出束搜索算法实际上不能够给你一个能使P(y|x)最大化的y值,因为束搜索算法的任务就是寻找一个y的值来使这项更大,但是它却选择了y-帽,而y*实际上能得到更大的值。因此这种情况下你能够得出是束搜索算法出错了

(2)第二种情况:P(y*|x)小于或等于P(y-帽|x),情况1或是情况2总有一个为真。情况2你能够总结出什么呢? 在这个例子中,y*是比y-帽更好的翻译结果,不过根据RNN模型的结果,P(y*)是小于P(y-帽)的,即相比于y-帽,y*成为输出的可能更小。因此在这种情况下,看来是RNN模型出了问题。同时可能值得在RNN模型上花更多时间。这里Andrew少讲了一些有关长度归一化(length normalizations)的细节。这里略过了有关长度归一化的细节,如果你用了某种长度归一化,那么你要做的就不是比较这两种可能性大小,而是比较长度归一化后的最优化目标函数值。不过先忽略这种复杂的情况。第二种情况中虽然y*是一个更好的翻译结果,RNN模型却赋予它更低的可能性,是RNN模型出现了问题

误差分析过程(error analysis process)看起来就像上图。(1)首先遍历开发集(development set),然后在其中找出算法产生的错误,假如这个例子中P(y*|x)的值为2 x 10^-10,而P(y-帽|x)的值为 1 x10^-10,根据上页幻灯片中的逻辑关系,这种情况下我们得知束搜索算法实际上选择了比y*可能性更低的y-帽,因此我们会说束搜索算法出错了。我们将它缩写为B。(2)接着你继续遍历第二个错误,再来看这些可能性。也许对于第二个例子来说,你认为是RNN模型出现了问题,用缩写R来代表RNN。(3)再接着你遍历了更多的例子,有时是束搜索算法出现了问题,有时是模型出现了问题,等等。

通过这个过程,我们能够执行误差分析,得出束搜索算法和RNN模型出错的比例是多少,能发现这两个部分中哪个是产生更多错误的原因。对开发集中每一个错误例子,即算法输出了比人工翻译更差的结果的情况,尝试确定这些错误(ascribe the error),是搜索算法出了问题,还是生成目标函数(束搜索算法使之最大化)的RNN模型出了问题。通过这个过程你能够发现有下面两种情况:①如果发现是束搜索算法造成了大部分错误,可以增大集束宽度。②相反地,如果发现是RNN模型出了更多错,那么可以进行更深层次的分析,来决定是需要增加正则化还是获取更多的训练数据,抑或是尝试一个不同的网络结构,或是其他方案。在第三门课中,了解到各种技巧都能够应用在这里。

这就是束搜索算法中的误差分析,Andrew认为这个特定的误差分析过程是十分有用的,它可以用于分析近似最佳算法(如束搜索算法),这些算法被用来优化学习算法(例如序列到序列模型/RNN)输出的目标函数。学会了这个方法,在应用里能更有效地运用好这些类型的模型。

《3.6 Bleu 得分(选修)》Bleu Score (optional)

机器翻译(machine translation)的一大难题是一个法语句子可以有多种英文翻译而且都同样好,所以当有多个同样好的答案时,怎样评估一个机器翻译系统呢?图像识别(image recognition)只有一个正确答案,测量准确性(measure accuracy)就可以。如果有多个不错的答案,要怎样衡量准确性呢? 常见的解决办法是,通过一个叫做BLEU得分(the BLEU score)的东西来解决。接着让我们了解BLEU得分是怎样工作的。

假如有一个法语句子(French sentence):Le chat est sur le tapis,然后这个句子的人工翻译为:The cat is on the mat。不同的人,也许会翻译为:There is a cat on the mat,实际上这两个都准确地翻译了这个法语句子。BLEU得分做的就是,给定一个机器生成的翻译,它能够自动地计算一个分数来衡量机器翻译的好坏。直觉表明只要机器生成的翻译与任何一个人工翻译的结果足够接近,那么它就会得到一个高的BLEU分数。BLEU代表bilingual evaluation understudy (双语评估替补)。在戏剧界,侯补演员(understudy)学习资深的演员的角色,这样在必要的时候,他们就能够接替这些资深演员。而BLEU的初衷是相对于请评估员(ask human evaluators),人工评估机器翻译系统(the machine translation system),BLEU得分就相当于一个侯补者,它可以代替人类来评估机器翻译的每一个输出结果。

BLEU得分是由Kishore Papineni, Salim Roukos,Todd Ward和Wei-Jing Zhu发表的这篇论文十分有影响力并且实际上也是一篇很好读的文章(a readable paper):BLEU: a Method for Automatic Evaluation of Machine Translation。有时间的话,推荐阅读。

BLEU得分背后的理念(intuition)是观察机器生成的翻译,然后看生成的词是否出现在上一个人工翻译参考之中。因此这些人工翻译的参考会包含在开发集或是测试集中。

现在,如上图,我们看一个极端的例子(example)。机器翻译MT(machine translation)的输出是:the the the the the the the。这显然是一个十分糟糕的翻译。衡量机器翻译输出质量的方法之一是观察输出结果的每一个词看其是否出现在参考中,这称为机器翻译的精确度( precision of the machine translation output)。这个情况下,机器翻译输出了七个单词并且这七个词中的每一个都出现在了参考1或是参考2。单词the在两个参考中都出现了,所以看上去每个词都是很合理的。因此这个输出的精确度就是7/7,看起来是一个极好的精确度。(实际上并不好,接下来有一个改良版本。)这就是为什么把出现在参考中的词在MT输出的所有词中所占的比例作为精确度评估标准并不是很有用的原因。因为它似乎意味着,例子中MT输出的翻译有很高的精确度,因此取而代之的是我们要用的这个改良后的精确度评估方法,我们把每一个单词的记分上限定为它在参考句子中出现的最多次数。在参考1中,单词the出现了两次,在参考2中,单词the只出现了一次。而2比1大,所以我们会说,单词the的得分上限为2。有了这个改良后的精确度,我们就说,这个输出句子的得分为2/7,因为在7个词中,我们最多只能给它2分。所以分母(denominator)就是7个词中单词the总共出现的次数,而分子(numerator)就是单词the出现的计数。我们在达到上限时截断计数,这就是改良后的精确度评估(the modified precision measure)

到目前为止,我们只关注单独的单词,在BLEU得分中,我们也考虑成对的单词,因此定义一下二元词组(bigrams)的BLEU得分

bigram的意思就是相邻的两个单词。现在我们来看看怎样用二元词组来定义BLEU得分,并且这仅仅只是最终的BLEU得分的一部分。我们会考虑一元词组(unigrams)也就是单个单词以及二元词组(bigrams),即成对的词,同时也许会有更长的单词序列,比如说三元词组(trigrams),意思是三个挨在一起的词。我们继续刚才的例子,还是参考1和2,现在我们假定机器翻译输出了稍微好一点的翻译:The cat the cat on the mat,仍然不是一个好的翻译,不过也许比上一个好一些。这里,可能的二元词组有the cat ,忽略大小写,接着是cat the, 这是另一个二元词组,然后又是the cat。不过我们已经有了,所以跳过它,然后下一个是cat on,然后是on the,再然后是the mat。所以这些就是机器翻译中的二元词组。好,我们来数一数每个二元词组出现了多少次。the cat出现了两次 ,剩下的都只出现了一次。

最后 ,我们来定义一下截取计数(the clipped count),即Count_clip。为了定义它,我们以给算法设置得分上限(limit),上限值为二元词组出现在参考1或2中的最大次数。①the cat在两个参考中最多出现一次(注意是在两个参考中取max),所以将截取它的计数为1。②cat the它并没有出现在参考1和参考2中,所以将它截取为0。③cat on出现了一次,我们就记1分。④on the出现一次就记1分,⑤the mat出现了一次,所以这就是截取完的计数(the clipped counts)。我们把所有的这些计数都截取了一遍,实际上就是将它们降低使之不大于二元词组出现在参考中的次数。最后,修改后的二元词组的精确度就是count_clip之和。那就是4除以二元词组的总个数6,因此4/6也就是2/3为二元词组改良后的精确度。

如上图,我们将它公式化。我们将改良后的一元词组精确度定义为P_1,P代表的是精确度(precision)。这里的下标1的意思是一元词组。它定义为一元词组之和,即对机器翻译结果中所有单词求和,MT 输出就是y-帽,Count_clip(unigram),再除以机器翻译输出中的一元词组出现次数之和。因此这个就是最终结果应该是两页幻灯片前得到的2/7(??这里没有看懂,我理解的是5/7,算出来的小伙伴麻烦评论区留言呀)。这里的1指代的是一元词组,意思是考虑单独的词,同样定义P_n为n元词组精确度,用n-gram替代掉一元词组。定义就是机器翻译输出中的n元词组的count_clip之和除以n元词组的出现次数之和。因此这些精确度或说是这些改良后的精确度得分评估的是一元词组、二元词组或者是三元词组,甚至是n取更大数值的n元词组。这个方法都能够衡量机器翻译输出中与参考相似重复的程度。另外,你能够确信如果机器翻译输出与参考1或是参考2完全一致的话,那么所有的这些P_1、P_2等等的值,都会等于1.0。为了得到改良后的1.0的精确度,只要你的输出与参考之一完全相同就能满足,不过有时即使输出结果并不完全与参考相同,这也是有可能实现的。

最后,我们将这些组合一下来构成最终的BLEU得分。P_n就是n元词组这一项的BLEU得分,即计算出的n元词组改良后的精确度,按照惯例,将P_1,P_2,P_3,P_4等用这个公式组合在一起,取平均值(mean)BLEU得分被定义为:

对这个线性运算进行乘方运算,乘方(exponentiation)是严格单调递增的运算(strictly monotonically increasing operation),实际上会用一个叫做BP的惩罚因子(the BP penalty)来调整这项。BP的意思是“简短惩罚”(brevity penalty)。事实表明,输出一个非常短的翻译更容易得到高精确度。因为输出的大部分词可能都出现在参考之中,不过我们并不想要特别短的翻译结果。因此简短惩罚(BP)就是一个调整因子(an adjustment factor),它能够惩罚输出了太短翻译结果的翻译系统。BP的公式如上图所示。如果你的机器翻译系统实际上输出了比人工翻译结果更长的翻译,那么它就等于1,其他情况下就是像这样的公式,惩罚所有更短的翻译,细节部分看这篇论文。

拥有单一实数评估指标(a single real number evaluation metric)的很重要,因为它能够让你尝试两种想法,然后看一下哪个得分更高,尽量选择得分更高的那个,BLEU得分对于机器翻译来说,具有革命性的(revolution)原因是因为它有一个相当不错的虽然不是完美的但是非常好的单一实数评估指标(a single real number evaluation index),因此它加快了整个机器翻译领域的进程,实践中,很少人会从零实现一个BLEU得分(implement a BLEU score from scratch),有很多开源的(open)实现结果,可以下载下来然后直接用来评估系统。不过今天,BLEU得分被用来评估许多生成文本的系统(systems that generate text),比如说机器翻译系统(machine translation systems),也有图像描述系统(image captioning systems)。你会用神经网络来生成图像描述,然后使用BLEU得分来看一下,结果在多大程度上与参考描述或是多个人工完成的参考描述内容相符。BLEU得分是一个有用的单一实数评估指标,用于评估生成文本的算法,判断输出的结果是否与人工写出的参考文本的含义相似不过它并没有用于语音识别(speech recognition)。因为在语音识别当中,通常只有一个答案,你可以用其他的评估方法,来看一下你的语音识别结果,是否十分相近或是字字正确(pretty much, exactly word for word correct)。

《3.7 注意力模型直观理解》Attention Model Intuition

本周的课程我们都在使用这个编码解码的构架(a Encoder-Decoder architecture)来完成机器翻译。当你使用RNN读一个句子,于是另一个会输出一个句子。注意力模型(the Attention Model)会使它工作得更好。注意力这种思想(the attention idea)已经是深度学习中最重要的思想之一,来看看它是怎么运作的

假设有一个很长的法语句子,绿色的编码器读取并记忆整个句子,然后在感知机中传递(to read in the whole sentence and then memorize the whole sentences and store it in the activations conveyed here)。这个紫色的解码网络(the decoder network)将生成英文翻译。但是,人工翻译并不会读整个法语句子,再记忆里面的东西,然后从零开始,机械式地翻译成一个英语句子。人工翻译可能是看一部分,翻译一部分,一直这样下去。因为记忆整个的像这样的的句子是非常困难的。

看这个Bleu score-Sentence length曲线图,我们看到这个编码解码结构对于短句子效果非常好,于是它会有一个相对高的Bleu分(Bleu score),但是对于长句子而言,比如说大于30或者40词的句子,它的表现就会变差(蓝色曲线)。整体来看,很短的句子很难得到所有词会难以翻译;对于长句子,效果也不好,因为在神经网络中,记忆非常长句子是非常困难的。在之后的学习中,会学习注意力模型,它翻译得很像人类。有了注意力模型,机器翻译系统的表现会像绿色曲线,因为翻译只会翻译句子的一部分,不会有一个巨大的下倾(huge dip),这个下倾实际上衡量了神经网络记忆一个长句子的能力,这是我们不希望神经网络去做的事情。

注意力模型源于Dimitri, Bahdanau, Camcrun Cho, Yoshe Bengio的Neural Machine Translation by Jointly Learning to Align and Translate。虽然这个模型源于机器翻译,但它也推广到其他应用领域。Andrew认为在深度学习领域,这个是个非常有影响力和开创性的论文。

看这个法语:Jane visite l'Afrique en Septembre(1)假定我们使用一个双向的RNN(a bidirectional RNN),为了计算每个输入单词的的特征集(set of features),我们必须要理解输出y-帽^<1>一直到y-帽^<5>的双向RNN。但是我们并不是只翻译一个单词,让我们先去掉上面的Y,然后对于句子里的每五个单词,计算一个句子中单词的特征集,也有可能是周围的词生成英文翻译。我们将使用另一个RNN生成英文翻译。用记号S来表示RNN的隐藏状态(the hidden state in this RNN),记为S^<1>。我们希望第一个生成的单词将会是Jane,那么我们应该看输入的法语句子的哪个部分?似乎你应该先看第一个单词或者它附近的词,但是别看太远了,比如句尾。

注意力模型就会计算注意力权重(a set of attention weights)。用α^<1,1>来表示生成第一个词时应该放多少注意力在这个第一块信息处。α^<1,2>表示计算第一个词Jane时,我们应该花多少注意力在输入的第二个词上面。α^<1,3>同理。注意力权重将评估应该花多少注意力在记号为C的内容上。这就是RNN的一个单元,如何尝试生成第一个词的,这是RNN的其中一步(蓝色标记)(2)对于RNN的第二步(紫色标记),我们将有一个新的隐藏状态S^<2>,使用一个新的注意力权值集(a new set of the attention weights),α^<2,1>表示在生成第二个词时应该花多少注意力在输入的第一个法语词jane上, visits就会是第二个标签了(the ground trip label)。α^<2,2>也同理,花多少注意力在visite词上。当然我们第一个生成的词Jane也会输入到这里,于是我们就有了需要花注意力的上下文,然后会一起生成第二个词,(3)第三步S^<3>(绿色标记),visits也是输入,我们再有上下文C,它取决于不同的时间集(time sets),其他分析过程类似。

如上图橘色标记,直观来想就是RNN向前进一次生成一个词,直到最终生成可能是。注意力权重α^<t,t>表示当你尝试生成第t个英文词,应该花多少注意力在第t个法语词上面。当生成一个特定的英文词时,这允许它在每个时间步去看周围词距内的法语词要花多少注意力。

《3.8注意力模型》Attention Model

注意力模型直观理解中我们看到注意力模型如何让一个神经网络只注意到一部分的输入句子。当它在生成句子的时候,更像人类翻译。让我们把这些想法转化成确切的式子,来实现注意力模型(Attention Model)

如上图所示,我们先假定有一个输入句子,并使用双向的RNN(bidirectional RNN),或者双向的GRU或者双向的LSTM,去计算每个词的特征(features)。实际上GRU和LSTM经常应用于这个,可能LSTM更经常一点。对于前向传播(forward occurrence),有第一个时间步的前向传播的激活值(a forward occurrence first time step),第一个时间步后向传播(backward occurrence)的激活值,后向的激活值,以此类推。他们一共向前了五个时间步,也向后了五个时间步,技术上我们把这里设置为0。我们也可以后向传播6次,设一个都是0的因子,实际上就是个都是0的因子。为了简化每个时间步的记号,即使你在双向RNN已经计算了前向的特征值和后向的特征值,我们用a^<t>来一起表示这些联系(these concatenated)。

a^<t>是时间步t上的特征向量(feature vector)。但是为了保持记号的一致性,我们用第二个,也就是t’,实际上我们将用t’来索引法语句子里面的词

接下来我们只进行前向计算,就是说这是个单向的RNN,用状态S表示生成翻译(translation)。所以第一个时间步,它应该生成y^<1>,当你输入上下文C的时候就会这样,如果你想用时间来索引它,你可以写C^<1>,但有时候Andrew就写个C,就是没有上标的C,这个会取决于注意力参数,即α^<1,1>α^<1,2>以此类推,告诉我们应该花多少注意力。同样的,这个a参数告诉我们上下文有多少取决于我们得到的特征,或者我们从不同时间步中得到的激活值。所以我们定义上下文的方式实际上来源于被注意力权重加权的不同时间步中的特征值。于是更公式化的注意力权重将会满足非负的条件,所以这就是个0或正数,它们加起来等于1。我们等会会见到我们如何确保这个成立,我们将会有上下文,或者说在t = 1时的上下文,Andrew会经常省略上标,这就会变成对t’的求和。这个权重的所有的t’值,加上这些激活值。所以这里的这项(上图编号1所示)就是注意力权重,这里的这项(上图编号2)来自于这里(上图编号3),于是α^<t,t'>就是y^<t>应该在t’时花在a^<t’>上注意力的数量(so α^<t,t'> is the amounention that’s y^<t> should pay to a^<t’>)。换句话来说,当你在t处生成输出词,你应该花多少注意力在第t’个输入词上面,这是生成输出的其中一步。然后下一个时间步(绿色标记),你会生成第二个输出。于是相似的,你现在有了一个新的注意力权重集,再找到一个新的方式将它们相加,这就产生了一个新的上下文,这个也是输入,且允许你生成第二个词。只有现在才用这种方式相加,它会变成第二个时间步的上下文。即对t’的α^<2,t’>进行求和,于是使用这些上下文向量,C^<1>写到这里,C^<2>也同理。这里的神经网络看起来很像相当标准的RNN序列(紫色标记),这里有着上下文向量作为输出(output),我们可以一次一个词地生成翻译,我们也定义了如何通过这些注意力权重和输入句子的特征值来计算上下文向量。剩下唯一要做的事情就是定义如何计算这些注意力权重(attention weights)。让我们下张幻灯片看看。

回忆一下α^<t,t'>,表示当你尝试去生成第t个输出的翻译词时应该花费在a^<t’>上的注意力的数量。这个式子你可以用来计算α^<t,t'>,在此之前我们要先计算e^<t,t'>,关键要用softmax,来确保这些权重加起来等于1。如果你对t’求和,比如每一个固定的t值,这些加起来等于1。如果你对t’求和,然后优先使用softmax,确保这些值加起来等于1。 

如何计算这些e项呢?一种方式是用小的神经网络,于是s^<t-1>就是神经网络在上个时间步的状态,于是这里我们有一个神经网络,如果你想要生成y^<t>,那么s^<t-1>就是上一时间步的隐藏状态,即s^<t>。这是给小神经网络的其中一个输入,也就是在神经网络中的一个隐藏层,因为你需要经常计算它们,然后a^<t’>,即上个时间步的的特征是另一个输入。直观来想就是,如果你想要决定要花多少注意力在t’的激活值上。于是,似乎它会很大程度上取决于你上一个时间步的的隐藏状态的激活值。你还没有当前状态的激活值,因为上下文会输入到这里,所以你还没计算出来,但是看看你生成上一个翻译的RNN的隐藏状态,然后对于每一个位置,每一个词都看向他们的特征值,这看起来很自然,即α^<t,t’>和e^<t,t’>应该取决于这两个量:s^<t-1>和a^<t’>(蓝色圆圈标记)。但是我们不知道具体函数是什么,所以我们可以做的事情就是训练一个很小的神经网络,去学习这个函数到底是什么。相信反向传播算法,相信梯度下降算法学到一个正确的函数(right function)。这表示,如果你应用这整个的模型,然后用梯度下降来训练它,这是可行的。这个小型的神经网络做了一件相当棒的事情,告诉你y^<t>应该花多少注意力在a^<t>上面,然后这个式子(蓝色圆圈标记)确保注意力权重加起来等于1,于是当你持续地一次生成一个词,这个神经网络实际上会花注意力在右边的这个输入句子上,它会完全自动的通过梯度下降来学习。

这个算法的一个缺点(downside)就是它要花费三次方的时间(take quadratic time),就是说这个算法的复杂是O(n^3)的,如果你有T_x个输入单词和T_y个输出单词,于是注意力参数的总数就会是T_x *T_y,所以这个算法有着三次方的消耗。但是在机器翻译的应用上,输入和输出的句子一般不会太长,可能三次方的消耗是可以接受,但也有很多研究工作,尝试去减少这样的消耗。这个想法被应用在很多问题中,比如图片加标题(image captioning),图片加标题就是看一张图,写下这张图的标题(caption)。具体参考这篇论文:Neural image caption generation with visual attention

因为机器翻译是一个非常复杂的问题(complicated problem)。当在日期标准化的问题(the date normalization problem)上应用了注意力,输入左侧这样的一个日期,这个日期实际上是阿波罗登月的日期(the Apollo Moon landing),输出是右侧标准的形式。用一个序列的神经网络,即序列模型去标准化到这样的形式,这个日期实际上是威廉·莎士比亚的生日(the birthday of William Shakespeare)。一般认为你可以训练一个神经网络,输入任何形式的日期,生成标准化的日期形式。也可以看看可视化的注意力权重(the visualizations of the attention weights)。这个一个机器翻译的例子,不同注意力权重的大小被画上了不同的颜色,这显示了当它生成特定的输出词时通常会花注意力在输入的正确的词上面,包括学习花注意在哪。以及使用反向传播时,什么时候学习完成。

这就是注意力模型,在深度学习中真的是个非常强大的想法(powerful idea)

《3.9语音识别》Speech recognition

现今,最令人振奋的发展之一就是seq2seq模型(sequence-to-sequence models)语音识别(speech recognition)方面准确性有了很大的提升。我们来看看seq2seq模型是如何应用于音频数据(audio data)的,比如语音(the speech)。什么是语音识别问题呢

有一个音频片段(audio clip)x,任务是自动地生成文本(transcript)y。一个音频片段,画出来是这样(横轴是时间)。一个麦克风的作用是测量出微小的气压(air pressure)变化,耳朵能够探测到这些微小的气压变化,于是我们可以听到声音,气压随着时间而变化。假如这个音频片段的内容是:"the quick brown fox"(敏捷的棕色狐狸),这时我们希望一个语音识别算法(speech recognition algorithm),通过输入这段音频,然后输出音频的文本内容。考虑到人的耳朵并不会处理声音的原始波形(row wave forms),而是通过一种特殊的物理结构来测量不同频率和强度的声波。音频数据的常见预处理步骤,就是运行这个原始的音频片段,然后生成一个声谱图(spectrogram)横轴(horizontal axis)是时间,纵轴(vertical axis)是声音的频率(frequencies),而图中不同的颜色,显示了声波能量的大小(the amount of energy),也就是在不同的时间和频率上这些声音有多大。通过这样的声谱图,伪空白输出(the false blank outputs)也应用于预处理步骤,也就是在音频被输入到学习算法之前,而人耳所做的计算和这个预处理过程非常相似。

曾经有一段时间语音识别系统是用音位(phonemes)来构建的,也就是人工设计的基本单元(hand-engineered basic units of cells),如果用音位来表示"the quick brown fox",在这里稍微简化一些,"the"含有"th"和"e"的音,而"quick"有"k" "w" "i" "k"的音,语音学家过去把这些音作为声音的基本单元写下来,把这些语音分解成这些基本的声音单元,而"brown"不是一个很正式的音位,因为它的音写起来比较复杂,不过语音学家(linguists)们认为用这些基本的音位单元(basic units of sound called phonemes)来表示音频(audio),是做语音识别最好的办法。不过在end-to-end模型中,我们发现这种音位表示法(phonemes representations)非必要,可以构建一个系统,通过向系统中输入音频片段(audio clip),然后直接输出音频的文本(a transcript),而不需要使用这种人工设计的表示方法。使用这种方法需要用一个很大的数据集,研究数据集可能长达300个小时,在学术界,甚至3000小时的文本音频数据集,都被认为是合理的大小。大量的研究,大量的论文所使用的数据集中,有几千种不同的声音,而且,最好的商业系统现在已经训练了超过1万个小时的数据,甚至10万个小时,并且它还会继续变得更大。在文本音频数据集中(Transcribe audio data sets)同时包含x和y,通过深度学习算法大大推进了语音识别的进程。那么,如何建立一个语音识别系统呢?

如上图,一种方法是结合之前的注意力模型(attention model),在输入音频的不同时间帧上(横轴),你可以用一个注意力模型,来输出文本描述,如"the quick brown fox",或者其他语音内容。

还有一种效果也不错的方法,就是用CTC损失函数(CTC cost)来做语音识别。CTC就是Connectionist Temporal Classification,它是由Alex Graves、Santiago Fernandes, Faustino Gomez、和Jürgen Schmidhuber提出的。具体可以参考论文:Connectionist temporal classification:labelling unsegmented sequence data with recurrent neural networks

算法思想如下:

假设语音片段内容是某人说:"the quick brown fox",这时我们使用一个新的网络,结构像这个样子,这里输入x和输出y的数量一样,因为这里画的只是一个简单的单向RNN结构。然而在实际中,它有可能是双向的LSTM结构,或者双向的GRU结构,并且通常是很深的模型。但注意一下这里时间步的数量,它非常地大。在语音识别中,通常输入的时间步数量(the number of input time steps)要比输出的时间步的数量(the number of output time steps)多出很多。举个例子,有一段10秒的音频,并且特征(features)是100赫兹的,即每秒有100个样本,于是这段10秒的音频片段就会有1000个输入,就是简单地用100赫兹乘上10秒。所以有1000个输入,但可能你的输出就没有1000个字母了,或者说没有1000个字符。这时要怎么办呢?CTC损失函数允许RNN生成这样的输出:ttt,这是一个特殊的字符,叫做空白符(black character),我们这里用下划线表示,这句话开头的音可表示为h_eee_ _ _,然后这里可能有个空格,我们用这个(非下划线)来表示空格,之后是_ _ _qqq__,这样的输出也被看做是正确的输出。下面这段输出对应的是"the q"。CTC损失函数的一个基本规则是将空白符之间的重复的字符折叠起来,再说清楚一些,这里用下划线来表示这个特殊的空白符(a special blank character),它和空格(the space character)是不一样的。所以the和quick之间有一个空格符,所以我们要输出一个空格,通过把用空白符所分割的重复的字符折叠起来,然后我们就可以把这段序列折叠成"the q"。这样一来你的神经网络因为有很多这种重复的字符,和很多插入在其中的空白符(blank characters),所以最后我们得到的文本会短上很多。于是这句"the quick brown fox"包括空格一共有19个字符,在这样的情况下,通过允许神经网络有重复的字符和插入空白符使得它能强制输出1000个字符,甚至你可以输出1000个y值来表示这段19个字符长的输出。这篇论文来自于Alex Grace以及刚才提到的那些人。Andrew所参与的深度语音识别系统项目就使用这种思想来构建有效的语音识别系统。

以上是语音识别的粗略的理解(rough sense),理解语音识别模型是如何工作的,注意力模型是如何工作的,以及CTC模型是如何工作的,以及这两种不同的构建这些系统的方法。现今,在生产技术中,构建一个有效语音识别系统,是一项相当重要的工作(a pretty significant effort),并且它需要很大的数据集(data set),之后的课程Andrew将告诉我们如何构建一个触发字检测系统(rigger word detection system),其中的关键字检测系统(keyword detection system)将会更加简单,它可以通过一个更简洁的数量更合理的数据来完成。

《3.10触发字检测》Trigger Word Detection

随着语音识别的发展,越来越多的设备可以通过你的声音来唤醒,也叫做触发字检测系统(rigger word detection systems)。我们来看一看如何建立一个触发字系统。

触发字系统的例子包括Amazon echo,它通过单词Alexa唤醒;还有百度DuerOS设备,通过"小度你好"来唤醒;苹果的Siri用Hey Siri来唤醒;Google Home使用Okay Google来唤醒,这就是触发字检测系统。假如你在卧室中,有一台Amazon echo,你可以在卧室中简单说一句: Alexa, 现在几点了?就能唤醒这个设备。它将会被单词"Alexa"唤醒,并回答你的询问。Andrew想教会我们如何构建一个触发字检测系统

如上图所示,现在有一个这样的RNN结构,我们要做的就是把一个音频片段(an audio clip)计算出它的声谱图特征(spectrogram features)得到特征向量x^<1>, x^<2>, x^<3>...,然后把它放到RNN中,最后定义我们的目标标签y。假如音频片段中的这一点是某人刚刚说完一个触发字,比如"Alexa",或者"小度你好" 或者"Okay Google",那么在这一点之前,你就可以在训练集中把目标标签都设为0,然后在这个点之后把目标标签设为1。假如在一段时间之后,触发字又被说了一次,比如是在这个点说的,那么就可以再次在这个点之后把目标标签设为1。这样的标签方案对于RNN来说是可行的,并且确实运行得非常不错。不过该算法一个明显的缺点是构建了一个很不平衡的训练集(a very imbalanced training set),0的数量比1多太多了

还有一个解决方法,虽然听起来有点简单粗暴,但确实能使其变得更容易训练。如上图所示,比起只在一个时间步上去输出1,其实你可以在输出变回0之前,多次输出1,或说在固定的一段时间内输出多个1。这样就稍微提高了1与0的比例。在音频片段中,触发字刚被说完之后,就把多个目标标签设为1,这里触发字又被说了一次。说完以后,又让RNN去输出1。在之后的编程练习中,你可以进行更多这样的操作

Andrew:这就是触发字检测,希望你能对自己感到自豪。因为你已经学了这么多深度学习的内容,现在你可以只用几分钟时间,就能用一张幻灯片来描述触发字能够实现它,并让它发挥作用。你甚至可能在你的家里用触发字系统做一些有趣的事情,比如打开或关闭电器,或者可以改造你的电脑,使得你或者其他人可以用触发字来操作它。

这是深度学习课程最后一个技术视频(last technical video),所以总结一下我们对序列模型的学习。我们学了RNN,包括GRU和LSTM,然后在上一周我们学了词嵌入(word embeddings),以及它们如何学习词汇的表达(how they learn representations of words)。在这周还学了注意力模型(the attention model)以及如何使用它来处理音频数据(audio data)。希望你在编程练习中实现这些思想的时候,能够体会到诸多乐趣。接下来我们来看最后一个视频。

《3.11结论和致谢》Conclusion and thank you

恭喜(congratulatiioons)你能走到这一步,在最后这节视频中,只想做个总结,并给你一些最后的想法。

Andrew:我们一起经历了一段很长的旅程,如果你已经学完了整个专业的课程,那么现在你已经学会了神经网络和深度学习,如何改进深度神经网络,如何结构化机器学习项目,和卷积神经网络。在最近的课程中还学了序列模型,我知道你为此非常努力,也希望你能对自己感到自豪,为你的努力,为你所做的这一切。

Andrew想向我们传达一个对你来说可能很重要的想法。

Andrew觉得深度学习是一种超能力(superpower),通过深度学习算法,你可以让计算机拥有"视觉"(make a computer see),让计算机自己合成小说(synthesize novel art),或者合成音乐(synthesized music),让计算机将一种语言翻译成另一种(translate from one language to another),或者对放射影像进行定位然后进行医疗诊断(Maybe have it located radiology image and render a medical diagnosis),或者构建自动驾驶系统(build pieces of a car that can drive itself)。如果说这还不是超能力的话,那还能是什么呢?当我们结束这一系列课程的时候,结束整个专业的时候,Andrew希望你能够使用这些思想来发展你的事业,追逐你的梦想,但最重要的是,去做你认为最合适的能对人类有贡献的事。这个世界现在面临着诸多挑战,但是在这种力量下,在人工智能和深度学习的力量下,Andrew觉得我们可以让世界变得更美好。现在这种超能力就掌握在你的手中,去突破障碍,让生活变得更好,这不单单是为自己,也是为了其他人。当然Andrew也希望我们能够对自己取得的成就以及你学到的一切感到自豪。当你完成这一系列课程的学习后,Andrew想我们可以把课程分享到社交媒体上,比如Twitter和Facebook,让你的朋友也能知道这门课程。

最后,Andrew想告诉我们的最后一件事,就是恭喜我们完成了这门课程的学习,为自己所取得的成就欢呼吧!同时也非常感谢,因为大家都很忙,即便如此我们还是花了很多时间来学习这些视频,可能还花了很多时间来做课堂测验还有编程练习,Andrew希望我们能够乐在其中,并学到很多算法流程。Andrew很荣幸你们能够花费时间,付诸精力,来学习这些东西,非常感谢大家!

说明:记录学习笔记,如果错误欢迎指正!转载请联系我。

猜你喜欢

转载自blog.csdn.net/csdn_xmj/article/details/119320136