最近在看End-to-end Relation Extraction using LSTMs on Sequences and Tree Structures这篇文章时,看到此文在Entity detection中用到了greedy search与beam search。内容转自:https://github.com/fengdu78/deeplearning_ai_books (黄海广为Andrew Ng的深度学习课程所编写的笔记)git
在这一周,你将会学习seq2seq(sequence to sequence)模型,从机器翻译到语音识别,它们都能起到很大的做用,从最基本的模型开始。以后你还会学习集束搜索(Beam search)和注意力模型(Attention Model),一直到最后的音频模型,好比语音。github
如今就开始吧,好比你想经过输入一个法语句子,好比这句 “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,另外一篇的做者是Kyunghyun Cho,Bart van Merrienboer,Caglar Gulcehre,Dzmitry Bahdanau,Fethi Bougares,Holger Schwen 和 Yoshua Bengio。编程
首先,咱们先创建一个网络,这个网络叫作编码网络(encoder network)(上图编号1所示),它是一个RNN的结构, RNN的单元能够是GRU 也能够是LSTM。每次只向该网络中输入一个法语单词,将输入序列接收完毕后,这个RNN网络会输出一个向量来表明这个输入序列。以后你能够创建一个解码网络,我把它画出来(上图编号2所示),它以编码网络的输出做为输入,编码网络是左边的黑色部分(上图编号1所示),以后它能够被训练为每次输出一个翻译后的单词,一直到它输出序列的结尾或者句子结尾标记,这个解码网络的工做就结束了。和往常同样咱们把每次生成的标记都传递到下一个单元中来进行预测,就像以前用语言模型合成文本时同样。api
深度学习在近期最卓越的成果之一就是这个模型确实有效,在给出足够的法语和英语文本的状况下,若是你训练这个模型,经过输入一个法语句子来输出对应的英语翻译,这个模型将会很是有效。这个模型简单地用一个编码网络来对输入的法语句子进行编码,而后用一个解码网络来生成对应的英语翻译。网络
还有一个与此相似的结构被用来作图像描述,给出一张图片,好比这张猫的图片(上图编号1所示),它能自动地输出该图片的描述,一只猫坐在椅子上,那么你如何训练出这样的网络?经过输入图像来输出描述,像这个句子同样。app
方法以下,在以前的卷积网络课程中,你已经知道了如何将图片输入到卷积神经网络中,好比一个预训练的AlexNet结构(上图编号2方框所示),而后让其学习图片的编码,或者学习图片的一系列特征。如今幻灯片所展现的就是AlexNet结构,咱们去掉最后的softmax单元(上图编号3所示),这个预训练的AlexNet结构会给你一个4096维的特征向量,向量表示的就是这只猫的图片,因此这个预训练网络能够是图像的编码网络。如今你获得了一个4096维的向量来表示这张图片,接着你能够把这个向量输入到RNN中(上图编号4方框所示),RNN要作的就是生成图像的描述,每次生成一个单词,这和咱们在以前将法语译为英语的机器翻译中看到的结构很像,如今你输入一个描述输入的特征向量,而后让网络生成一个输出序列,或者说一个一个地输出单词序列。ide
事实证实在图像描述领域,这种方法至关有效,特别是当你想生成的描述不是特别长时。据我所知,这种模型首先是由Junhua Mao,Wei Xu,Yi Yang,Jiang Wang,Zhiheng Huang和Alan Yuille提出的,尽管有几个团队都几乎在同一时间构造出了很是类似的模型,由于还有另外两个团队也在同一时间得出了类似的结论。我以为有可能Mao的团队和Oriol Vinyals,Alexander Toshev,Samy Bengio和Dumitru Erhan,还有Andrej Karpathy和Fei-Fei Yi是同一个团队。函数
如今你知道了基本的seq2seq模型是怎样运做的,以及image to sequence模型或者说图像描述模型是怎样运做的。不过这两个模型运做方式有一些不一样,主要体如今如何用语言模型合成新的文本,并生成对应序列的方面。一个主要的区别就是你大概不会想获得一个随机选取的翻译,你想要的是最准确的翻译,或者说你可能不想要一个随机选取的描述,你想要的是最好的最贴切的描述,咱们将在下节视频中介绍如何生成这些序列。工具
在seq2seq机器翻译模型和咱们在第一周课程所用的语言模型之间有不少类似的地方,可是它们之间也有许多重要的区别,让咱们来一探究竟。
你能够把机器翻译想成是创建一个条件语言模型,在语言模型中上方是一个咱们在第一周所创建的模型,这个模型可让你可以估计句子的可能性,这就是语言模型所作的事情。你也能够将它用于生成一个新的句子,若是你在图上的该处(下图编号1所示),有\(x^{<1>}\)和\(x^{<2>}\),那么在该例中\(x^{<2>} = y^{<1>}\),可是\(x^{<1>}\)、\(x^{<2>}\)等在这里并不重要。为了让图片看起来更简洁,我把它们先抹去,能够理解为\(x^{<1>}\)是一个全为0的向量,而后\(x^{<2>}\)、\(x^{<3>}\)等都等于以前所生成的输出,这就是所说的语言模型。
而机器翻译模型是下面这样的,我这里用两种不一样的颜色来表示,即绿色和紫色,用绿色(上图编号2所示)表示encoder网络,用紫色(上图编号3所示)表示decoder网络。你会发现decoder网络看起来和刚才所画的语言模型几乎如出一辙,机器翻译模型其实和语言模型很是类似,不一样在于语言模型老是以零向量(上图编号4所示)开始,而encoder网络会计算出一系列向量(上图编号2所示)来表示输入的句子。有了这个输入句子,decoder网络就能够以这个句子开始,而不是以零向量开始,因此我把它叫作条件语言模型(conditional language model)。相比语言模型,输出任意句子的几率,翻译模型会输出句子的英文翻译(上图编号5所示),这取决于输入的法语句子(上图编号6所示)。换句话说,你将估计一个英文翻译的几率,好比估计这句英语翻译的几率,"Jane is visiting Africa in September.",这句翻译是取决于法语句子,"Jane visite I'Afrique en septembre.",这就是英语句子相对于输入的法语句子的可能性,因此它是一个条件语言模型。
如今,假如你想真正地经过模型将法语翻译成英文,经过输入的法语句子模型将会告诉你各类英文翻译所对应的可能性。\(x\)在这里是法语句子"Jane visite l'Afrique en septembre.",而它将告诉你不一样的英语翻译所对应的几率。显然你不想让它随机地进行输出,若是你从这个分布中进行取样获得\(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\)(上图编号1所示),使得条件几率最大化。因此在开发机器翻译系统时,你须要作的一件事就是想出一个算法,用来找出合适的\(y\)值,使得该项最大化,而解决这种问题最通用的算法就是束搜索(Beam Search),你将会在下节课见到它。
不过在了解束搜索以前,你可能会问一个问题,为何不用贪心搜索(Greedy Search)呢?贪心搜索是一种来自计算机科学的算法,生成第一个词的分布之后,它将会根据你的条件语言模型挑选出最有可能的第一个词进入你的机器翻译模型中,在挑选出第一个词以后它将会继续挑选出最有可能的第二个词,而后继续挑选第三个最有可能的词,这种算法就叫作贪心搜索,可是你真正须要的是一次性挑选出整个单词序列,从\(y^{<1>}\)、\(y^{<2>}\)到\(y^{<T_{y}>}\)来使得总体的几率最大化。因此这种贪心算法先挑出最好的第一个词,在这以后再挑最好的第二词,而后再挑第三个,这种方法其实并无论用,为了证实这个观点,咱们来考虑下面两种翻译。
第一串(上图编号1所示)翻译明显比第二个(上图编号2所示)好,因此咱们但愿机器翻译模型会说第一个句子的\(P(y|x)\)比第二个句子要高,第一个句子对于法语原文来讲更好更简洁,虽然第二个也不错,可是有些啰嗦,里面有不少不重要的词。但若是贪心算法挑选出了"Jane is"做为前两个词,由于在英语中going更加常见,因而对于法语句子来讲"Jane is going"相比"Jane is visiting"会有更高的几率做为法语的翻译,因此颇有可能若是你仅仅根据前两个词来估计第三个词的可能性,获得的就是going,最终你会获得一个欠佳的句子,在\(P(y|x)\)模型中这不是一个最好的选择。
我知道这种说法可能比较粗略,可是它确实是一种普遍的现象,当你想获得单词序列\(y^{<1>}\)、\(y^{<2>}\)一直到最后一个词整体的几率时,一次仅仅挑选一个词并非最佳的选择。固然,在英语中各类词汇的组合数量还有不少不少,若是你的字典中有10,000个单词,而且你的翻译可能有10个词那么长,那么可能的组合就有10,000的10次方这么多,这仅仅是10个单词的句子,从这样大一个字典中来挑选单词,因此可能的句子数量很是巨大,不可能去计算每一种组合的可能性。因此这时最经常使用的办法就是用一个近似的搜索算法,这个近似的搜索算法作的就是它会尽力地,尽管不必定总会成功,但它将挑选出句子\(y\)使得条件几率最大化,尽管它不能保证找到的\(y\)值必定可使几率最大化,但这已经足够了。
最后总结一下,在本视频中,你看到了机器翻译是如何用来解决条件语言模型问题的,这个模型和以前的语言模型一个主要的区别就是,相比以前的模型随机地生成句子,在该模型中你要找到最有可能的英语句子,最可能的英语翻译,可是可能的句子组合数量过于巨大,没法一一列举,因此咱们须要一种合适的搜索算法,让咱们在下节课中学习集束搜索。
这节视频中你会学到集束搜索(beam search)算法,上节视频中咱们讲了对于机器翻译来讲,给定输入,好比法语句子,你不会想要输出一个随机的英语翻译结果,你想要一个最好的,最可能的英语翻译结果。对于语音识别也同样,给定一个输入的语音片断,你不会想要一个随机的文本翻译结果,你想要最好的,最接近原意的翻译结果,集束搜索就是解决这个最经常使用的算法。这节视频里,你会明白怎么把集束搜索算法应用到你本身的工做中,就用咱们的法语句子的例子来试一下集束搜索吧。
“Jane visite l'Afrique en Septembre.”(法语句子),咱们但愿翻译成英语,"Jane is visiting Africa in September".(英语句子),集束搜索算法首先作的就是挑选要输出的英语翻译中的第一个单词。这里我列出了10,000个词的词汇表(下图编号1所示),为了简化问题,咱们忽略大小写,全部的单词都以小写列出来。在集束搜索的第一步中我用这个网络部分,绿色是编码部分(下图编号2所示),紫色是解码部分(下图编号3所示),来评估第一个单词的几率值,给定输入序列\(x\),即法语做为输入,第一个输出\(y\)的几率值是多少。
贪婪算法只会挑出最可能的那一个单词,而后继续。而集束搜索则会考虑多个选择,集束搜索算法会有一个参数B,叫作集束宽(beam width)。在这个例子中我把这个集束宽设成3,这样就意味着集束搜索不会只考虑一个可能结果,而是一次会考虑3个,好比对第一个单词有不一样选择的可能性,最后找到in、jane、september,是英语输出的第一个单词的最可能的三个选项,而后集束搜索算法会把结果存到计算机内存里以便后面尝试用这三个词。若是集束宽设的不同,若是集束宽这个参数是10的话,那么咱们跟踪的不只仅3个,而是10个第一个单词的最可能的选择。因此要明白,为了执行集束搜索的第一步,你须要输入法语句子到编码网络,而后会解码这个网络,这个softmax层(上图编号3所示)会输出10,000个几率值,获得这10,000个输出的几率值,取前三个存起来。
让咱们看看集束搜索算法的第二步,已经选出了in、jane、september做为第一个单词三个最可能的选择,集束算法接下来会针对每一个第一个单词考虑第二个单词是什么,单词in后面的第二个单词多是a或者是aaron,我就是从词汇表里把这些词列了出来,或者是列表里某个位置,september,多是列表里的 visit,一直到字母z,最后一个单词是zulu(下图编号1所示)。
为了评估第二个词的几率值,咱们用这个神经网络的部分,绿色是编码部分(上图编号2所示),而对于解码部分,当决定单词in后面是什么,别忘了解码器的第一个输出\(y^{<1>}\),我把\(y^{<1>}\)设为单词in(上图编号3所示),而后把它喂回来,这里就是单词in(上图编号4所示),由于它的目的是努力找出第一个单词是in的状况下,第二个单词是什么。这个输出就是\(y^{<2>}\)(上图编号5所示),有了这个链接(上图编号6所示),就是这里的第一个单词in(上图编号4所示)做为输入,这样这个网络就能够用来评估第二个单词的几率了,在给定法语句子和翻译结果的第一个单词in的状况下。
注意,在第二步里咱们更关心的是要找到最可能的第一个和第二个单词对,因此不只仅是第二个单词有最大的几率,而是第一个、第二个单词对有最大的几率(上图编号7所示)。按照条件几率的准则,这个能够表示成第一个单词的几率(上图编号8所示)乘以第二个单词的几率(上图编号9所示),这个能够从这个网络部分里获得(上图编号10所示),对于已经选择的in、jane、september这三个单词,你能够先保存这个几率值(上图编号8所示),而后再乘以第二个几率值(上图编号9所示)就获得了第一个和第二个单词对的几率(上图编号7所示)。
如今你已经知道在第一个单词是in的状况下如何评估第二个单词的几率,如今第一个单词是jane,道理同样,句子多是"jane a"、"jane aaron",等等到"jane is"、"jane visits"等等(上图编号1所示)。你会用这个新的网络部分(上图编号2所示),我在这里画一条线,表明从\(y^{<1>}\),即jane,\(y^{< 1 >}\)链接jane(上图编号3所示),那么这个网络部分就能够告诉你给定输入\(x\)和第一个词是jane下,第二个单词的几率了(上图编号4所示),和上面同样,你能够乘以\(P(y^{<1>}|x)\)获得\(P(y^{<1>},y^{<2>}|x)\)。
针对第二个单词全部10,000个不一样的选择,最后对于单词september也同样,从单词a到单词zulu,用这个网络部分,我把它画在这里。来看看若是第一个单词是september,第二个单词最多是什么。因此对于集束搜索的第二步,因为咱们一直用的集束宽为3,而且词汇表里有10,000个单词,那么最终咱们会有3乘以10,000也就是30,000个可能的结果,由于这里(上图编号1所示)是10,000,这里(上图编号2所示)是10,000,这里(上图编号3所示)是10,000,就是集束宽乘以词汇表大小,你要作的就是评估这30,000个选择。按照第一个词和第二个词的几率,而后选出前三个,这样又减小了这30,000个可能性,又变成了3个,减小到集束宽的大小。假如这30,000个选择里最可能的是“in September”(上图编号4所示)和“jane is”(上图编号5所示),以及“jane visits”(上图编号6所示),画的有点乱,但这就是这30,000个选择里最可能的三个结果,集束搜索算法会保存这些结果,而后用于下一次集束搜索。
注意一件事情,若是集束搜索找到了第一个和第二个单词对最可能的三个选择是“in September”或者“jane is”或者“jane visits”,这就意味着咱们去掉了september做为英语翻译结果的第一个单词的选择,因此咱们的第一个单词如今减小到了两个可能结果,可是咱们的集束宽是3,因此仍是有\(y^{<1>}\),\(y^{<2>}\)对的三个选择。
在咱们进入集束搜索的第三步以前,我还想提醒一下由于咱们的集束宽等于3,每一步咱们都复制3个,一样的这种网络来评估部分句子和最后的结果,因为集束宽等于3,咱们有三个网络副本(上图编号7所示),每一个网络的第一个单词不一样,而这三个网络能够高效地评估第二个单词全部的30,000个选择。因此不须要初始化30,000个网络副本,只须要使用3个网络的副本就能够快速的评估softmax的输出,即\(y^{<2>}\)的10,000个结果。
让咱们快速解释一下集束搜索的下一步,前面说过前两个单词最可能的选择是“in September”和“jane is”以及“jane visits”,对于每一对单词咱们应该保存起来,给定输入\(x\),即法语句子做为\(x\)的状况下,\(y^{<1>}\)和\(y^{<2>}\)的几率值和前面同样,如今咱们考虑第三个单词是什么,能够是“in September a”,能够是“in September aaron”,一直到“in September zulu”。为了评估第三个单词可能的选择,咱们用这个网络部分,第一单词是in(上图编号1所示),第二个单词是september(上图编号2所示),因此这个网络部分能够用来评估第三个单词的几率,在给定输入的法语句子\(x\)和给定的英语输出的前两个单词“in September”状况下(上图编号3所示)。对于第二个片断来讲也同样,就像这样同样(上图编号4所示),对于“jane visits”也同样,而后集束搜索仍是会挑选出针对前三个词的三个最可能的选择,多是“in september jane”(上图编号5所示),“Jane is visiting”也颇有可能(上图编号6所示),也极可能是“Jane visits Africa”(上图编号7所示)。
而后继续,接着进行集束搜索的第四步,再加一个单词继续,最终这个过程的输出一次增长一个单词,集束搜索最终会找到“Jane visits africa in september”这个句子,终止在句尾符号(上图编号8所示),用这种符号的系统很是常见,它们会发现这是最有可能输出的一个英语句子。在本周的练习中,你会看到更多的执行细节,同时,你会运用到这个集束算法,在集束宽为3时,集束搜索一次只考虑3个可能结果。注意若是集束宽等于1,只考虑1种可能结果,这实际上就变成了贪婪搜索算法,上个视频里咱们已经讨论过了。可是若是同时考虑多个,可能的结果好比3个,10个或者其余的个数,集束搜索一般会找到比贪婪搜索更好的输出结果。
你已经了解集束搜索是如何工做的了,事实上还有一些额外的提示和技巧的改进可以使集束算法更高效,咱们在下个视频中一探究竟。
上个视频中, 你已经学到了基本的束搜索算法(the basic beam search algorithm),这个视频里,咱们会学到一些技巧, 可以使算法运行的更好。长度归一化(Length normalization)就是对束搜索算法稍做调整的一种方式,帮助你获得更好的结果,下面介绍一下它。
前面讲到束搜索就是最大化这个几率,这个乘积就是\(P(y^{< 1 >}\ldots y^{< T_{y}}|X)\),能够表示成:\(P(y^{<1>}|X)\) \(P(y^{< 2 >}|X,y^{< 1 >})\) \(P(y^{< 3 >}|X,y^{< 1 >},y^{< 2>})\)…\(P(y^{< T_{y} >}|X,y^{<1 >},y^{<2 >}\ldots y^{< T_{y} - 1 >})\)
这些符号看起来可能比实际上吓人,但这就是咱们以前见到的乘积几率(the product probabilities)。若是计算这些,其实这些几率值都是小于1的,一般远小于1。不少小于1的数乘起来,会获得很小很小的数字,会形成数值下溢(numerical underflow)。数值下溢就是数值过小了,致使电脑的浮点表示不能精确地储存,所以在实践中,咱们不会最大化这个乘积,而是取\(log\)值。若是在这加上一个\(log\),最大化这个\(log\)求和的几率值,在选择最可能的句子\(y\)时,你会获得一样的结果。因此经过取\(log\),咱们会获得一个数值上更稳定的算法,不容易出现四舍五入的偏差,数值的舍入偏差(rounding errors)或者说数值下溢(numerical underflow)。由于\(log\)函数它是严格单调递增的函数,最大化\(P(y)\),由于对数函数,这就是\(log\)函数,是严格单调递增的函数,因此最大化\(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的数字,那么就会获得一个更小的几率值,因此这个目标函数有一个缺点,它可能不天然地倾向于简短的翻译结果,它更偏向短的输出,由于短句子的几率是由更少数量的小于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}\)上加上指数\(a\),\(a\)能够等于0.7。若是\(a\)等于1,就至关于彻底用长度来归一化,若是\(a\)等于0,\(T_{y}\)的0次幂就是1,就至关于彻底没有归一化,这就是在彻底归一化和没有归一化之间。\(a\)就是算法另外一个超参数(hyper parameter),须要调整大小来获得最好的结果。不得不认可,这样用\(a\)其实是试探性的,它并无理论验证。可是你们都发现效果很好,你们都发现实践中效果不错,因此不少人都会这么作。你能够尝试不一样的\(a\)值,看看哪个可以获得最好的结果。
总结一下如何运行束搜索算法。当你运行束搜索时,你会看到不少长度等于1的句子,不少长度等于2的句子,不少长度等于3的句子,等等。可能运行束搜索30步,考虑输出的句子可能达到,好比长度30。由于束宽为3,你会记录全部这些可能的句子长度,长度为一、二、 三、 4 等等一直到30的三个最可能的选择。而后针对这些全部的可能的输出句子,用这个式子(上图编号1所示)给它们打分,取几率最大的几个句子,而后对这些束搜索获得的句子,计算这个目标函数。最后从通过评估的这些句子中,挑选出在归一化的\(log\) 几率目标函数上得分最高的一个(you pick the one that achieves the highest value on this normalized log probability objective.),有时这个也叫做归一化的对数似然目标函数(a normalized log likelihood objective)。这就是最终输出的翻译结果,这就是如何实现束搜索。这周的练习中你会本身实现这个算法。
最后还有一些实现的细节,如何选择束宽B。B越大,你考虑的选择越多,你找到的句子可能越好,可是B越大,你的算法的计算代价越大,由于你要把不少的可能选择保存起来。最后咱们总结一下关于如何选择束宽B的一些想法。接下来是针对或大或小的B各自的优缺点。若是束宽很大,你会考虑不少的可能,你会获得一个更好的结果,由于你要考虑不少的选择,可是算法会运行的慢一些,内存占用也会增大,计算起来会慢一点。而若是你用小的束宽,结果会没那么好,由于你在算法运行中,保存的选择更少,可是你的算法运行的更快,内存占用也小。在前面视频里,咱们例子中用了束宽为3,因此会保存3个可能选择,在实践中这个值有点偏小。在产品中,常常能够看到把束宽设到10,我认为束宽为100对于产品系统来讲有点大了,这也取决于不一样应用。可是对科研而言,人们想压榨出所有性能,这样有个最好的结果用来发论文,也常常看到你们用束宽为1000或者3000,这也是取决于特定的应用和特定的领域。在你实现你的应用时,尝试不一样的束宽的值,当B很大的时候,性能提升会愈来愈少。对于不少应用来讲,从束宽1,也就是贪心算法,到束宽为三、到10,你会看到一个很大的改善。可是当束宽从1000增长到3000时,效果就没那么明显了。对于以前上过计算机科学课程的同窗来讲,若是你熟悉计算机科学里的搜索算法(computer science search algorithms), 好比广度优先搜索(BFS, Breadth First Search algorithms),或者深度优先搜索(DFS, Depth First Search),你能够这样想束搜索,不像其余你在计算机科学算法课程中学到的算法同样。若是你没据说过这些算法也没关系,可是若是你据说过广度优先搜索和深度优先搜索,不一样于这些算法,这些都是精确的搜索算法(exact search algorithms),束搜索运行的更快,可是不能保证必定能找到argmax的准确的最大值。若是你没据说过广度优先搜索和深度优先搜索,也不用担忧,这些对于咱们的目标也不重要,若是你据说过,这就是束搜索和其余算法的关系。
好,这就是束搜索。这个算法普遍应用在多产品系统或者许多商业系统上,在深度学习系列课程中的第三门课中,咱们讨论了不少关于偏差分析(error analysis)的问题。事实上在束搜索上作偏差分析是我发现的最有用的工具之一。有时你想知道是否应该增大束宽,个人束宽是否足够好,你能够计算一些简单的东西来指导你须要作什么,来改进你的搜索算法。咱们在下个视频里进一步讨论。
在这五门课中的第三门课里,你了解了偏差分析是如何可以帮助你集中时间作你的项目中最有用的工做,束搜索算法是一种近似搜索算法(an approximate search algorithm),也被称做启发式搜索算法(a heuristic search algorithm),它不老是输出可能性最大的句子,它仅记录着B为前3或者10或是100种可能。那么若是束搜索算法出现错误会怎样呢?
本节视频中,你将会学习到偏差分析和束搜索算法是如何相互起做用的,以及你怎样才能发现是束搜索算法出现了问题,须要花时间解决,仍是你的RNN模型出了问题,要花时间解决。咱们先来看看如何对束搜索算法进行偏差分析。
咱们来用这个例子说明: “Jane visite l'Afrique en septembre”。假如说,在你的机器翻译的dev集中,也就是开发集(development set),人工是这样翻译的: Jane visits Africa in September,我会将这个标记为\(y^*\)。这是一个十分不错的人工翻译结果,不过假如说,当你在已经完成学习的RNN模型,也就是已完成学习的翻译模型中运行束搜索算法时,它输出了这个翻译结果:Jane visited Africa last September,咱们将它标记为\(\hat 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填入这里(上图编号1所示),一样,我如今忽略了字母的大小写,后面也是同样,而后这个就会计算。\(P(y|x)\)结果代表,你此时能作的最有效的事就是用这个模型来计算\(P(y^*|x)\),同时也用你的RNN模型来计算\(P(\hat y|x)\),而后比较一下这两个值哪一个更大。有多是左边大于右边,也有多是\(P(y^*)\)小于\(P(\hat y)\),其实应该是小于或等于,对吧。取决于实际是哪一种状况,你就可以更清楚地将这个特定的错误归咎于RNN或是束搜索算法,或说是哪一个负有更大的责任。咱们来探究一下其中的逻辑。
这是以前幻灯片里的两个句子。记住,咱们是要计算\(P(y^*|x)\)和\(P(\hat y|x)\),而后比较这两个哪一个更大,因此就会有两种状况。
第一种状况,RNN模型的输出结果\(P(y^*|x)\) 大于\(P(\hat y|x)\),这意味着什么呢?
束搜索算法选择了\(\hat y\) ,对吧?
你获得\(\hat y\)的方式是,你用一个RNN模型来计算\(P(y|x)\),而后束搜索算法作的就是尝试寻找使\(P(y|x)\)最大的\(y\),不过在这种状况下,相比于\(\hat y\),\(y^*\)的值更\(P(y|x)\)大,所以你可以得出束搜索算法实际上不可以给你一个能使\(P(y|x)\)最大化的\(y\)值,由于束搜索算法的任务就是寻找一个\(y\)的值来使这项更大,可是它却选择了\(\hat y\),而\(y^*\)实际上能获得更大的值。所以这种状况下你可以得出是束搜索算法出错了。那另外一种状况是怎样的呢?
第二种状况是\(P(y^*|x)\)小于或等于\(P(\hat y|x)\)对吧?这二者之中总有一个是真的。状况1或是状况2总有一个为真。状况2你可以总结出什么呢?
在咱们的例子中,\(y^*\) 是比 \(\hat y\)更好的翻译结果,不过根据RNN模型的结果,\(P(y^*)\) 是小于\(P(\hat y)\)的,也就是说,相比于\(\hat y\),\(y^*\)成为输出的可能更小。所以在这种状况下,看来是RNN模型出了问题。同时可能值得在RNN模型上花更多时间。这里我少讲了一些有关长度归一化(length normalizations)的细节。这里我略过了有关长度归一化的细节,若是你用了某种长度归一化,那么你要作的就不是比较这两种可能性大小,而是比较长度归一化后的最优化目标函数值。不过如今先忽略这种复杂的状况。第二种状况代表虽然\(y^*\)是一个更好的翻译结果,RNN模型却赋予它更低的可能性,是RNN模型出现了问题。
因此偏差分析过程看起来就像下面这样。你先遍历开发集,而后在其中找出算法产生的错误,这个例子中,假如说\(P(y^*|x)\)的值为2 x 10-10,而\(P(\hat y|x)\)的值为 1 x10-10,根据上页幻灯片中的逻辑关系,这种状况下咱们得知束搜索算法实际上选择了比\(y^*\)可能性更低的\(\hat y\),所以我会说束搜索算法出错了。我将它缩写为B。接着你继续遍历第二个错误,再来看这些可能性。也许对于第二个例子来讲,你认为是RNN模型出现了问题,我会用缩写R来表明RNN。再接着你遍历了更多的例子,有时是束搜索算法出现了问题,有时是模型出现了问题,等等。经过这个过程,你就可以执行偏差分析,得出束搜索算法和RNN模型出错的比例是多少。有了这样的偏差分析过程,你就能够对开发集中每个错误例子,即算法输出了比人工翻译更差的结果的状况,尝试肯定这些错误,是搜索算法出了问题,仍是生成目标函数(束搜索算法使之最大化)的RNN模型出了问题。而且经过这个过程,你可以发现这两个部分中哪一个是产生更多错误的缘由,而且只有当你发现是束搜索算法形成了大部分错误时,才值得花费努力增大集束宽度。相反地,若是你发现是RNN模型出了更多错,那么你能够进行更深层次的分析,来决定是须要增长正则化仍是获取更多的训练数据,抑或是尝试一个不一样的网络结构,或是其余方案。你在第三门课中,了解到各类技巧都可以应用在这里。
这就是束搜索算法中的偏差分析,我认为这个特定的偏差分析过程是十分有用的,它能够用于分析近似最佳算法(如束搜索算法),这些算法被用来优化学习算法(例如序列到序列模型/RNN)输出的目标函数。也就是咱们这些课中一直讨论的。学会了这个方法,我但愿你可以在你的应用里更有效地运用好这些类型的模型。
机器翻译(machine translation)的一大难题是一个法语句子能够有多种英文翻译并且都一样好,因此当有多个一样好的答案时,怎样评估一个机器翻译系统呢?不像图像识别(image recognition),只有一个正确答案,就只要测量准确性就能够了。若是有多个不错的答案,要怎样衡量准确性呢?
常见的解决办法是,经过一个叫作BLEU得分(the BLEU score)的东西来解决。因此,在这个选修视频中,我想与你分享,我想让你了解BLEU得分是怎样工做的。
假如给你一个法语句子: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发表的这篇论文十分有影响力而且实际上也是一篇很好读的文章。因此若是有时间的话,我推荐你读一下。BLEU得分背后的理念是观察机器生成的翻译,而后看生成的词是否出如今少一我的工翻译参考之中。所以这些人工翻译的参考会包含在开发集或是测试集中。
(参考论文:Papineni, Kishore& Roukos, Salim & Ward, Todd & Zhu, Wei-jing. (2002). BLEU: a Method for Automatic Evaluation of Machine Translation.10.3115/1073083.1073135.)
如今,咱们来看一个极端的例子。咱们假设机器翻译系统缩写为MT。机器翻译 (MT)的输出是:the the the the the the the。这显然是一个十分糟糕的翻译。衡量机器翻译输出质量的方法之一是观察输出结果的每个词看其是否出如今参考中,这被称作是机器翻译的精确度(a 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分。因此这里分母就是7个词中单词the总共出现的次数,而分子就是单词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出现了两次 ,cat the出现了一次,剩下的都只出现了一次。最后 ,咱们来定义一下截取计数(the clipped count)。也就是Count_clip。为了定义它,咱们以这列的值为基础,可是给算法设置得分上限,上限值为二元词组出如今参考1或2中的最大次数。the cat在两个参考中最多出现一次,因此我将截取它的计数为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\)表明的是精确度。这里的下标1的意思是一元词组。不过它定义为一元词组之和,也就是对机器翻译结果中全部单词求和,MT 输出就是\(\hat y\),Countclip(unigram)。除以机器翻译输出中的一元词组出现次数之和。所以这个就是最终结果应该是两页幻灯片前获得的2/7。这里的1指代的是一元词组,意思是咱们在考虑单独的词,你也能够定义\(P_n\)为\(n\)元词组精确度,用n-gram替代掉一元词组。因此这就是机器翻译输出中的\(n\)元词组的countclip之和除以\(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\)。而后将它们用这个公式组合在一块儿,就是取平均值。按照惯例BLEU得分被定义为,\(exp (\frac{1}{4}\sum\limits_{n=1}^{4}{{{P}_{n}}})\),对这个线性运算进行乘方运算,乘方是严格单调递增的运算,咱们实际上会用额外的一个叫作BP 的惩罚因子(the BP penalty)来调整这项。BP的意思是“简短惩罚”( brevity penalty)。这些细节也许并非十分重要,可是你能够大体了解一下。
事实代表,若是你输出了一个很是短的翻译,那么它会更容易获得一个高精确度。由于输出的大部分词可能都出如今参考之中,不过咱们并不想要特别短的翻译结果。所以简短惩罚(BP)就是一个调整因子,它可以惩罚输出了过短翻译结果的翻译系统。BP的公式如上图所示。若是你的机器翻译系统实际上输出了比人工翻译结果更长的翻译,那么它就等于1,其余状况下就是像这样的公式,惩罚全部更短的翻译,细节部分你可以在这篇论文中找到。
再说一句,在以前的视频中,你了解了拥有单一实数评估指标(a single real number evaluation metric)的重要性,由于它可以让你尝试两种想法,而后看一下哪一个得分更高,尽可能选择得分更高的那个,BLEU得分对于机器翻译来讲,具备革命性的缘由是由于它有一个至关不错的虽然不是完美的可是很是好的单一实数评估指标,所以它加快了整个机器翻译领域的进程,我但愿这节视频可以让你了解BLEU得分是如何操做的。实践中,不多人会从零实现一个BLEU得分(implement a BLEU score from scratch),有不少开源的实现结果,你能够下载下来而后直接用来评估你的系统。不过今天,BLEU得分被用来评估许多生成文本的系统(systems that generate text),好比说机器翻译系统(machine translation systems),也有我以前简单提到的图像描述系统(image captioning systems)。也就是说你会用神经网络来生成图像描述,而后使用BLEU得分来看一下,结果在多大程度上与参考描述或是多我的工完成的参考描述内容相符。BLEU得分是一个有用的单一实数评估指标,用于评估生成文本的算法,判断输出的结果是否与人工写出的参考文本的含义类似。不过它并无用于语音识别(speech recognition)。由于在语音识别当中,一般只有一个答案,你能够用其余的评估方法,来看一下你的语音识别结果,是否十分相近或是字字正确(pretty much, exactly word for word correct)。不过在图像描述应用中,对于同一图片的不一样描述,多是一样好的。或者对于机器翻译来讲,有多个同样好的翻译结果,BLEU得分就给了你一个可以自动评估的方法,帮助加快算法开发进程。说了这么多,但愿你明白了BLEU得分是怎么运行的。
在本周大部分时间中,你都在使用这个编码解码的构架(a Encoder-Decoder architecture)来完成机器翻译。当你使用RNN读一个句子,因而另外一个会输出一个句子。咱们要对其作一些改变,称为注意力模型(the Attention Model),而且这会使它工做得更好。注意力模型或者说注意力这种思想(The attention algorithm, the attention idea)已是深度学习中最重要的思想之一,咱们看看它是怎么运做的。
像这样给定一个很长的法语句子,在你的神经网络中,这个绿色的编码器要作的就是读整个句子,而后记忆整个句子,再在感知机中传递(to read in the whole sentence and then memorize the whole sentences and store it in the activations conveyed her)。而对于这个紫色的神经网络,即解码网络(the decoder network)将生成英文翻译,Jane去年九月去了非洲,很是享受非洲文化,遇到了不少奇妙的人,她回来就嚷嚷道,她经历了一个多棒的旅行,并邀请我也一块儿去。人工翻译并不会经过读整个法语句子,再记忆里面的东西,而后从零开始,机械式地翻译成一个英语句子。而人工翻译,首先会作的多是先翻译出句子的部分,再看下一部分,并翻译这一部分。看一部分,翻译一部分,一直这样下去。你会经过句子,一点一点地翻译,由于记忆整个的像这样的的句子是很是困难的。你在下面这个编码解码结构中,会看到它对于短句子效果很是好,因而它会有一个相对高的Bleu分(Bleu score),可是对于长句子而言,好比说大于30或者40词的句子,它的表现就会变差。Bleu评分看起来就会像是这样,随着单词数量变化,短的句子会难以翻译,由于很可贵到全部词。对于长的句子,效果也很差,由于在神经网络中,记忆很是长句子是很是困难的。在这个和下个视频中,你会见识到注意力模型,它翻译得很像人类,一次翻译句子的一部分。并且有了注意力模型,机器翻译系统的表现会像这个同样,由于翻译只会翻译句子的一部分,你不会看到这个有一个巨大的下倾(huge dip),这个下倾实际上衡量了神经网络记忆一个长句子的能力,这是咱们不但愿神经网络去作的事情。在这个视频中,我想要给大家注意力机制运行的一些直观的东西。而后在下个视频中,完善细节。
注意力模型源于Dimitri, Bahdanau, Camcrun Cho, Yoshe Bengio。(Bahdanau D, Cho K, Bengio Y. Neural Machine Translation by Jointly Learning to Align and Translate[J]. Computer Science,2014.)虽然这个模型源于机器翻译,但它也推广到了其余应用领域。我认为在深度学习领域,这个是个很是有影响力的,很是具备开创性的论文。
让咱们用一个短句举例说明一下,即便这些思想多是应用于更长的句子。可是用短句来举例说明,讲解这些思想会更简单。咱们有一个很日常的句子:(法语)Jane visite l'Afrique en Septembre。假定咱们使用RNN,在这个状况中,咱们将使用一个双向的RNN(a bidirectional RNN),为了计算每一个输入单词的的特征集(set of features),你必需要理解输出\(\hat y^{<1>}\)到\(\hat y^{<3>}\)一直到\(\hat y^{<5>}\)的双向RNN。可是咱们并非只翻译一个单词,让咱们先去掉上面的\(Y\),就用双向的RNN。咱们要对单词作的就是,对于句子里的每五个单词,计算一个句子中单词的特征集,也有多是周围的词,让咱们试试,生成英文翻译。咱们将使用另外一个RNN生成英文翻译,这是我平时用的RNN记号。我不用\(A\)来表示感知机(the activation),这是为了不和这里的感知机(the activations)混淆。我会用另外一个不一样的记号,我会用\(S\)来表示RNN的隐藏状态(the hidden state in this RNN),不用\(A^{<1>}\),而是用\(S^{<1>}\)。咱们但愿在这个模型里第一个生成的单词将会是Jane,为了生成Jane visits Africa in September。因而等式就是,当你尝试生成第一个词,即输出,那么咱们应该看输入的法语句子的哪一个部分?彷佛你应该先看第一个单词,或者它附近的词。可是你别看太远了,好比说看到句尾去了。因此注意力模型就会计算注意力权重(a set of attention weights),咱们将用\(a^{<1,1>}\)来表示当你生成第一个词时你应该放多少注意力在这个第一块信息处。而后咱们算第二个,这个叫注意力权重,\(a^{<1,2>}\)它告诉咱们当你尝试去计算第一个词Jane时,咱们应该花多少注意力在输入的第二个词上面。同理这里是\(a^{<1,3>}\),接下去也同理。这些将会告诉咱们,咱们应该花多少注意力在记号为\(C\)的内容上。这就是RNN的一个单元,如未尝试生成第一个词的,这是RNN的其中一步,咱们将会在下个视频中讲解细节。对于RNN的第二步,咱们将有一个新的隐藏状态\(S^{<2>}\),咱们也会用一个新的注意力权值集(a new set of the attention weights),咱们将用\(a^{<2,1>}\)来告诉咱们何时生成第二个词, 那么visits就会是第二个标签了(the ground trip label)。咱们应该花多少注意力在输入的第一个法语词上。而后同理\(a^{<2,2>}\),接下去也同理,咱们应该花多少注意力在visite词上,咱们应该花多少注意在词l'Afique上面。固然咱们第一个生成的词Jane也会输入到这里,因而咱们就有了须要花注意力的上下文。第二步,这也是个输入,而后会一块儿生成第二个词,这会让咱们来到第三步\(S^{<3>}\),这是输入,咱们再有上下文C,它取决于在不一样的时间集(time sets),上面的\(a^{<3>}\)。这个告诉了咱们咱们要花注意力在不一样的法语的输入词上面。
而后同理。有些事情我还没说清楚,可是在下个视频中,我会讲解一些细节,好比如何准肯定义上下文,还有第三个词的上下文,是否真的须要去注意句子中的周围的词。这里要用到的公式以及如何计算这些注意力权重(these attention weights),将会在下个视频中讲解到。在下个视频中你会看到\(a^{<3,t>}\),即当你尝试去生成第三个词,应该是l'Afique,就获得了右边这个输出,这个RNN步骤应该要花注意力在\(t\)时的法语词上,这取决于在\(t\)时的双向RNN的激活值。那么它应该是取决于第四个激活值,它会取决于上一步的状态,它会取决于\(S^{<2>}\)。而后这些一块儿影响你应该花多少注意在输入的法语句子的某个词上面。咱们会在下个视频中讲解这些细节。可是直观来想就是RNN向前进一次生成一个词,在每一步直到最终生成多是<EOS>。这些是注意力权重,即\(a^{<t,t>}\)告诉你,当你尝试生成第\(t\)个英文词,它应该花多少注意力在第\(t\)个法语词上面。当生成一个特定的英文词时,这容许它在每一个时间步去看周围词距内的法语词要花多少注意力。
我但愿这个视频传递了关于注意力模型的一些直观的东西。咱们如今可能对算法的运行有了大概的感受,让咱们进入到下个视频中,看看具体的细节。
在上个视频中你已经见到了,注意力模型如何让一个神经网络只注意到一部分的输入句子。当它在生成句子的时候,更像人类翻译。让咱们把这些想法转化成确切的式子,来实现注意力模型。
跟上个视频同样,咱们先假定有一个输入句子,并使用双向的RNN,或者双向的GRU或者双向的LSTM,去计算每一个词的特征。实际上GRU和LSTM常常应用于这个,可能LSTM更常常一点。对于前向传播(the forward occurrence),你有第一个时间步的前向传播的激活值(a forward occurrence first time step),第一个时间步后向传播的激活值,后向的激活值,以此类推。他们一共向前了五个时间步,也向后了五个时间步,技术上咱们把这里设置为0。咱们也能够后向传播6次,设一个都是0的因子,实际上就是个都是0的因子。为了简化每一个时间步的记号,即便你在双向RNN已经计算了前向的特征值和后向的特征值,我就用\(a^{<t>}\)来一块儿表示这些联系。因此\(a^{<t>}\)就是时间步\(t\)上的特征向量。可是为了保持记号的一致性,咱们用第二个,也就是\(t'\),实际上我将用\(t'\)来索引法语句子里面的词。接下来咱们只进行前向计算,就是说这是个单向的RNN,用状态\(S\)表示生成翻译。因此第一个时间步,它应该生成\(y^{<1>}\),当你输入上下文\(C\)的时候就会这样,若是你想用时间来索引它,你能够写\(C^{<1>}\),但有时候我就写个\(C\),就是没有上标的\(C\),这个会取决于注意力参数,即\(a^{<1,1>}\),\(a^{<1,2>}\)以此类推,告诉咱们应该花多少注意力。一样的,这个\(a\)参数告诉咱们上下文有多少取决于咱们获得的特征,或者咱们从不一样时间步中获得的激活值。因此咱们定义上下文的方式实际上来源于被注意力权重加权的不一样时间步中的特征值。因而更公式化的注意力权重将会知足非负的条件,因此这就是个0或正数,它们加起来等于1。咱们等会会见到咱们如何确保这个成立,咱们将会有上下文,或者说在\(t=1\)时的上下文,我会常常省略上标,这就会变成对\(t'\)的求和。这个权重的全部的\(t'\)值,加上这些激活值。因此这里的这项(上图编号1所示)就是注意力权重,这里的这项(上图编号2)来自于这里(上图编号3),因而\(a^{<t,t'>}\)就是\(y^{<t>}\)应该在\(t'\)时花在\(a\)上注意力的数量。换句话来讲,当你在\(t\)处生成输出词,你应该花多少注意力在第\(t'\)个输入词上面,这是生成输出的其中一步。而后下一个时间步,你会生成第二个输出。因而类似的,你如今有了一个新的注意力权重集,再找到一个新的方式将它们相加,这就产生了一个新的上下文,这个也是输入,且容许你生成第二个词。只有如今才用这种方式相加,它会变成第二个时间步的上下文。即对\(t'\)的\(a^{<2,t'>}\)进行求和,因而使用这些上下文向量,\(C^{<1>}\)写到这里,\(C^{<2>}\)也同理。这里的神经网络看起来很像至关标准的RNN序列,这里有着上下文向量做为输出,咱们能够一次一个词地生成翻译,咱们也定义了如何经过这些注意力权重和输入句子的特征值来计算上下文向量。剩下惟一要作的事情就是定义如何计算这些注意力权重。让咱们下张幻灯片看看。
回忆一下\(a^{<t,t'>}\),是你应该花费在\(a^{<t'>}\)上的注意力的数量,当你尝试去生成第\(t\)个输出的翻译词,让咱们先把式子写下来,再讨论它是怎么来的。这个式子你能够用来计算\(a^{<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的隐藏状态,而后对于每个位置,每个词都看向他们的特征值,这看起来很天然,即\(a^{<t,t'>}\)和\(e^{<t,t'>}\)应该取决于这两个量。可是咱们不知道具体函数是什么,因此咱们能够作的事情就是训练一个很小的神经网络,去学习这个函数究竟是什么。相信反向传播算法,相信梯度降低算法学到一个正确的函数。这表示,若是你应用这整个的模型,而后用梯度降低来训练它,这是可行的。这个小型的神经网络作了一件至关棒的事情,告诉你\(y^{<t>}\)应该花多少注意力在\(a^{<t>}\)上面,而后这个式子确保注意力权重加起来等于1,因而当你持续地一次生成一个词,这个神经网络实际上会花注意力在右边的这个输入句子上,它会彻底自动的经过梯度降低来学习。
这个算法的一个缺点就是它要花费三次方的时间,就是说这个算法的复杂是\(O(n3)\)的,若是你有\(T_x\)个输入单词和\(T_y\)个输出单词,因而注意力参数的总数就会是\(T_x\times T_y\),因此这个算法有着三次方的消耗。可是在机器翻译的应用上,输入和输出的句子通常不会太长,可能三次方的消耗是能够接受,但也有不少研究工做,尝试去减小这样的消耗。那么讲解注意想法在机器翻译中的应用,就到此为止了。虽然没有讲到太多的细节,但这个想法也被应用到了其余的不少问题中去了,好比图片加标题(image captioning),图片加标题就是看一张图,写下这张图的标题。底下的这篇论文来源于Kevin Chu,Jimmy Barr, Ryan Kiros, Kelvin Shaw, Aaron Korver, Russell Zarkutnov, Virta Zemo, 和 Andrew Benjo。他们也显示了你能够有一个很类似的结构看图片,而后,当你在写图片标题的时候,一次只花注意力在一部分的图片上面。若是你感兴趣,那么我鼓励你,也去看看这篇论文,作一些编程练习。
由于机器翻译是一个很是复杂的问题,在以前的练习中,你应用了注意力,在日期标准化的问题(the date normalization problem)上面,问题输入了像这样的一个日期,这个日期其实是阿波罗登月的日期,把它标准化成标准的形式,或者这样的日期。用一个序列的神经网络,即序列模型去标准化到这样的形式,这个日期其实是威廉·莎士比亚的生日。通常认为是这个日期正如你以前联系中见到的,你能够训练一个神经网络,输入任何形式的日期,生成标准化的日期形式。其余能够作的有意思的事情是看看可视化的注意力权重(the visualizations of the attention weights)。这个一个机器翻译的例子,这里被画上了不一样的颜色,不一样注意力权重的大小,我不想在这上面花太多时间,可是你能够发现,对应的输入输出词,你会发现注意力权重,会变高,所以这显示了当它生成特定的输出词时一般会花注意力在输入的正确的词上面,包括学习花注意在哪。
在注意力模型中,使用反向传播时, 何时学习完成。
这就是注意力模型,在深度学习中真的是个很是强大的想法。在本周的编程练习中,我但愿你能够享受本身应用它的过程。
现今,最使人振奋的发展之一,就是seq2seq模型(sequence-to-sequence models)在语音识别方面准确性有了很大的提高。这门课程已经接近尾声,如今我想经过剩下几节视频,来告诉大家,seq2seq模型是如何应用于音频数据的(audio data),好比语音(the speech)。
什么是语音视频问题呢?如今你有一个音频片断\(x\)(an audio clip,x),你的任务是自动地生成文本\(y\)。如今有一个音频片断,画出来是这样,该图的横轴是时间。一个麦克风的做用是测量出微小的气压变化,如今你之因此能听到个人声音,是由于你的耳朵可以探测到这些微小的气压变化,它多是由你的扬声器或者耳机产生的,也就是像图上这样的音频片断,气压随着时间而变化。假如这个我说的音频片断的内容是:"the quick brown fox"(敏捷的棕色狐狸),这时咱们但愿一个语音识别算法(a speech recognition algorithm),经过输入这段音频,而后输出音频的文本内容。考虑到人的耳朵并不会处理声音的原始波形,而是经过一种特殊的物理结构来测量这些,不一样频率和强度的声波。音频数据的常见预处理步骤,就是运行这个原始的音频片断,而后生成一个声谱图(a spectrogram),就像这样。一样地,横轴是时间,纵轴是声音的频率(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\),经过深度学习算法大大推动了语音识别的进程。那么,如何创建一个语音识别系统呢?
在上一节视频中,咱们谈到了注意力模型,因此,一件你能作的事就是在横轴上,也就是在输入音频的不一样时间帧上,你能够用一个注意力模型,来输出文本描述,如"the quick brown fox",或者其余语音内容。
还有一种效果也不错的方法,就是用CTC损失函数(CTC cost)来作语音识别。CTC就是Connectionist Temporal Classification,它是由Alex Graves、Santiago Fernandes, Faustino Gomez、和Jürgen Schmidhuber提出的。(Graves A, Gomez F. Connectionist temporal classification:labelling unsegmented sequence data with recurrent neural networks[C]// International Conference on Machine Learning. ACM, 2006:369-376.)
算法思想以下:
假设语音片断内容是某人说:"the quick brown fox",这时咱们使用一个新的网络,结构像这个样子,这里输入\(x\)和输出\(y\)的数量都是同样的,由于我在这里画的,只是一个简单的单向RNN结构。然而在实际中,它有多是双向的LSTM结构,或者双向的GIU结构,而且一般是很深的模型。但注意一下这里时间步的数量,它很是地大。在语音识别中,一般输入的时间步数量(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,这是一个特殊的字符,叫作空白符,咱们这里用下划线表示,这句话开头的音可表示为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以及刚才提到的那些人。我所参与的深度语音识别系统项目就使用这种思想来构建有效的语音识别系统。
但愿这能给你一个粗略的理解,理解语音识别模型是如何工做的:注意力模型是如何工做的,以及CTC模型是如何工做的,以及这两种不一样的构建这些系统的方法。现今,在生产技术中,构建一个有效语音识别系统,是一项至关重要的工做,而且它须要很大的数据集,下节视频我想作的是告诉你如何构建一个触发字检测系统(a rigger word detection system),其中的关键字检测系统(keyword detection system)将会更加简单,它能够经过一个更简洁的数量更合理的数据来完成。因此咱们下节课再见。
如今你已经学习了不少关于深度学习和序列模型的内容,因而咱们能够真正去简便地描绘出一个触发字系统(a trigger word system),就像上节视频中你看到的那样。随着语音识别的发展,愈来愈多的设备能够经过你的声音来唤醒,这有时被叫作触发字检测系统(rigger word detection systems)。咱们来看一看如何创建一个触发字系统。
触发字系统的例子包括Amazon echo,它经过单词Alexa唤醒;还有百度DuerOS设备,经过"小度你好"来唤醒;苹果的Siri用Hey Siri来唤醒;Google Home使用Okay Google来唤醒,这就是触发字检测系统。假如你在卧室中,有一台Amazon echo,你能够在卧室中简单说一句: Alexa, 如今几点了?就能唤醒这个设备。它将会被单词"Alexa"唤醒,并回答你的询问。若是你能创建一个触发字检测系统,也许你就能让你的电脑经过你的声音来执行某些事,我有个朋友也在作一种用触发字来打开的特殊的灯,这是个颇有趣的项目。但我想教会你的,是如何构建一个触发字检测系统。
有关于触发字检测系统的文献,还处于发展阶段。对于触发字检测,最好的算法是什么,目前尚未一个普遍的定论。我这里就简单向你介绍一个你可以使用的算法好了。如今有一个这样的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。在以后的编程练习中,你能够进行更多这样的操做,我想你应该会对本身学会了这么多东西而感到自豪。咱们仅仅用了一张幻灯片来描述这种复杂的触发字检测系统。在这个基础上,但愿你可以实现一个能有效地让你可以检测出触发字的算法,不过在编程练习中你能够看到更多的学习内容。这就是触发字检测,但愿你能对本身感到自豪。由于你已经学了这么多深度学习的内容,如今你能够只用几分钟时间,就能用一张幻灯片来描述触发字可以实现它,并让它发挥做用。你甚至可能在你的家里用触发字系统作一些有趣的事情,好比打开或关闭电器,或者能够改造你的电脑,使得你或者其余人能够用触发字来操做它。