在这一周,你将会学习seq2seqsequence to sequence)模型,从机器翻译到语音识别,它们都能起到很大的作用,从最基本的模型开始。之后你还会学习集束搜索(Beam search)和注意力模型(Attention Model),一直到最后的音频模型,比如语音。

3.1 Basic Models

如何训练出一个新的网络来实现机器翻译?这里有一些方法,主要来自于两篇论文。

[Sutskever et al. 2014. Sequence to sequence learning with neural networks]

[Cho et al.. 2014. Learning phrase representations using RNN encoder-decoder for statistical machine translation]

L5W3-Seq2Seq - 图1

首先,我们先建立一个网络,叫做编码网络(encoder network)(上图左数第一个圈),它是一个RNN的结构, RNN的单元可以是GRU 也可以是LSTM。每次只向该网络中输入一个法语单词,将输入序列接收完毕后,这个RNN网络会输出一个向量来代表这个输入序列。

之后建立一个解码网络,上图左数第二个圈,它以编码网络的输出作为输入,它被训练为每次输出一个翻译后的单词,一直到它输出序列的结尾或者句子结尾标记。我们把每次生成的标记都传递到下一个单元中来进行预测,就像之前用语言模型合成文本时一样。

这个模型简单地用一个编码网络来对输入的法语句子进行编码,然后用一个解码网络来生成对应的英语翻译,且它确实有效。

还有一个与此类似的结构,用来做图像描述。给出一张图片,比如这张猫的图片,它能自动地输出该图片的描述,一只猫坐在椅子上,那么你如何训练出这样的网络?

[Mao et. al. 2014. Deep captioning with multimodal recurrent neural notworka]

(Vinyals et. al, 2014. Show and tell: Neural image caption generator]

[Karpathy and L.i. 2015. Deep visual semantic align mente for generating image descriptiona]

L5W3-Seq2Seq - 图2

在之前的卷积网络课程中,你已经知道了如何将图片输入到卷积神经网络中,比如一个预训练的AlexNet结构,然后让其学习图片的编码,或者学习图片的一系列特征。这个预训练网络可以是图像的编码网络,我们去掉AlexNet中最后的softmax单元,现在得到的是一个4096维的向量来表示这张图片,接着可以把这个向量输入到RNN中。RNN要做的就是生成图像的描述,每次生成一个单词。

这和我们在之前将法语译为英语的机器翻译中看到的结构很像,现在你输入一个描述输入的特征向量,然后让网络生成一个输出序列,或者说一个一个地输出单词序列。

3.2 Conditional Language Model

seq2seq机器翻译模型和我们在第一周课程所用的语言模型之间有很多相似的地方,但是它们之间也有许多重要的区别,让我们来一探究竟。

你可以把机器翻译想成是建立一个条件语言模型。

L5W3-Seq2Seq - 图3

语言模型能够估计句子的可能性,你也可以将它用于生成一个新的句子。为了让图片看起来更简洁,我把它们先抹去,可以理解为L5W3-Seq2Seq - 图4是一个全为0的向量,然后L5W3-Seq2Seq - 图5L5W3-Seq2Seq - 图6等都等于之前所生成的输出,这就是所说的语言模型。

而机器翻译模型是下面这样的,途中用绿色表示encoder网络,紫色表示decoder网络。你会发现decoder网络看起来和语言模型几乎一模一样,不同在于语言模型总是以零向量L5W3-Seq2Seq - 图7开始,而翻译模型中先用encoder网络会计算出一系列向量来表示输入的句子,再传入decoder网络。

相比语言模型会输出任意句子的概率,翻译模型输出的是句子的英文翻译,这取决于输入的法语句子。也就是英语句子相对于输入的法语句子的可能性,所以它是一个条件语言模型(conditional language model)。

所以当你使用这个模型来进行机器翻译时,你并不是从得到的分布中进行随机取样,而是你要找到一个英语句子L5W3-Seq2Seq - 图8,使得 L5W3-Seq2Seq - 图9#card=math&code=P%28y%5E%7B%3C1%3E%7D%2C…%2C%2Cy%5E%7B%3CT_y%3E%7D%7Cx%29&id=RDdQc) 条件概率最大化。

解决这种问题最通用的算法就是集束搜索(Beam Search),你将会在下节课见到它。你可能会为什么不用贪心搜索(Greedy Search)呢?

贪心搜索算法,它将会根据你的条件语言模型挑选出最有可能的第一个词进入你的机器翻译模型中,然后挑选出最有可能的第二个词,第三个词… 但是你真正需要的是一次性挑选出整个单词序列,使得整体的概率最大化。所以贪心算法其实并不管用,为了证明这个观点,我们来考虑下面两种翻译。

Jane is visiting Africa in September.

Jane is going to be visiting Africa in September.

第一串翻译明显比第二个好,所以我们希望机器翻译模型会说第一个句子的L5W3-Seq2Seq - 图10#card=math&code=P%28y%7Cx%29&id=WVix4)比第二个句子要高。第一个句子对于法语原文来说更好更简洁,虽然第二个也不错,但是有些啰嗦,里面有很多不重要的词。

但如果贪心算法挑选出了”Jane is“作为前两个词,因为在英语中going更加常见,所以估计第三个词的可能性得到的就是going,最终你会得到一个欠佳的句子,在L5W3-Seq2Seq - 图11#card=math&code=P%28y%7Cx%29&id=dLDyY)模型中这不是一个最好的选择。

当可能的句子数量非常巨大时,不可能去计算每一种组合的可能性。这时最常用的办法就是用一个近似的搜索算法,它会尽力地挑选出句子L5W3-Seq2Seq - 图12使得条件概率最大化,尽管它不能保证找到的L5W3-Seq2Seq - 图13值一定可以使概率最大化,但这已经足够了。

3.3 Beam Search

贪婪算法每一步只会挑出最可能的那一个单词,然后继续。而集束搜索则会考虑多个选择,它有一个参数B,叫做集束宽(beam width)。

比如,把集束宽设成3,这样就意味着集束搜索一次会考虑前3个概率最大的结果。接下来,集束算法会针对这3个词分别计算下一个单词的概率,然后从所有结果中再挑选出3个。

L5W3-Seq2Seq - 图14

在这个例子中,已经选出了injaneseptember作为第一个单词三个最可能的选择。为了评估第二个词的概率值,我们用这个神经网络的部分,绿色是编码部分,而对于解码部分,把解码器的第一个输出L5W3-Seq2Seq - 图15分别设为这3个单词,做一次预测,得到3个输出向量。结合第一个词的概率,乘以第二个概率值,就得到了第一个和第二个单词对的概率(红色圈出的那个公式)。按照单词对的概率,选出前3个。假如这30,000个选择里最可能的是“in September”和“jane is”,以及“jane visits”,这就意味着我们去掉了september作为翻译结果第一个单词的选择。

由于集束宽等于3,我们有三个网络副本,每个网络的第一个单词不同,而这三个网络可以高效地评估第二个单词所有的30,000个选择。所以不需要初始化30,000个网络副本,只需要使用3个网络的副本就可以快速的评估softmax的输出,即L5W3-Seq2Seq - 图16的10,000个结果。

对于第三个单词,集束搜索还是会挑选出针对前三个词的三个最可能的选择,直到句尾符号出现。

L5W3-Seq2Seq - 图17

3.4 改进Refinements to Beam Search

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

前面讲到束搜索就是最大化这个概率,这个乘积就是L5W3-Seq2Seq - 图18#card=math&code=P%28y%5E%7B%3C%201%20%3E%7D%5Cldots%20y%5E%7B%3C%20T%7By%7D%7D%7CX%29&id=JAHSN),可以表示成:L5W3-Seq2Seq - 图19#card=math&code=P%28y%5E%7B%3C1%3E%7D%7CX%29&id=virZ8) L5W3-Seq2Seq - 图20#card=math&code=P%28y%5E%7B%3C%202%20%3E%7D%7CX%2Cy%5E%7B%3C%201%20%3E%7D%29&id=PuC19) L5W3-Seq2Seq - 图21#card=math&code=P%28y%5E%7B%3C%203%20%3E%7D%7CX%2Cy%5E%7B%3C%201%20%3E%7D%2Cy%5E%7B%3C%202%3E%7D%29&id=y1vBc)…![](https://g.yuque.com/gr/latex?P(y%5E%7B%3C%20T%7By%7D%20%3E%7D%7CX%2Cy%5E%7B%3C1%20%3E%7D%2Cy%5E%7B%3C2%20%3E%7D%5Cldots%20y%5E%7B%3C%20T%7By%7D%20-%201%20%3E%7D)#card=math&code=P%28y%5E%7B%3C%20T%7By%7D%20%3E%7D%7CX%2Cy%5E%7B%3C1%20%3E%7D%2Cy%5E%7B%3C2%20%3E%7D%5Cldots%20y%5E%7B%3C%20T_%7By%7D%20-%201%20%3E%7D%29&id=Nqxpg),也就是乘积概率。但由于概率值都是小于1的,很多小于1的数乘起来,会得到很小很小的数字,会造成数值下溢(numerical underflow)。数值下溢导致电脑的浮点表示不能精确地储存,因此在实践中,我们对其L5W3-Seq2Seq - 图22

L5W3-Seq2Seq - 图23

因为L5W3-Seq2Seq - 图24函数是严格单调递增的函数,所以最大化 L5W3-Seq2Seq - 图25#card=math&code=logP%28y%7Cx%29&id=pjsGT) 和最大化 L5W3-Seq2Seq - 图26#card=math&code=P%28y%7Cx%29&id=ipvd3) 结果一样。所以实际工作中,我们总是记录概率的对数和(the sum of logs of the probabilities),而不是概率的乘积(the production of probabilities)。

还有一个问题,对于目标函数(this objective function)来说,如果一个句子很长,那么它的概率会很低,因为乘了很多项小于1的数字来估计句子的概率。概率取L5W3-Seq2Seq - 图27值也会有同样的问题,加起来的项越多,得到的结果越负。

所以改进就是我们不再最大化这个目标函数了,我们可以把它归一化,也就是将概率和除以结果的单词数量。这样就是取每个单词的概率对数值的平均了,很明显地减少了对输出较长的结果的惩罚。

在实践中,有个探索性的方法,相比于直接除L5W3-Seq2Seq - 图28,也就是输出句子的单词总数,有一个更柔和的方法(a softer approach),那就是L5W3-Seq2Seq - 图29取指数L5W3-Seq2Seq - 图30。如果L5W3-Seq2Seq - 图31等于1,就相当于完全用长度来归一化,如果L5W3-Seq2Seq - 图32等于0,L5W3-Seq2Seq - 图33的0次幂就是1,就相当于没有归一化。L5W3-Seq2Seq - 图34就是算法另一个超参数,可以调整其大小来得到最好的结果。

如何选择束宽B

如果束宽很大,你会得到一个更好的结果,因为你考虑了很多的选择,但是算法会运行的慢一些,内存占用也会增大,计算起来会慢一点。而如果你用小的束宽,结果会没那么好,因为你在算法运行中,保存的选择更少,但是你的算法运行的更快,内存占用也小。

在产品中,经常可以看到把束宽设到10。对科研而言,人们想压榨出全部性能,这样有个最好的结果用来发论文,也经常看到大家用束宽为1000或者3000,这也是取决于特定的应用和特定的领域。对于很多应用来说,从束宽1,也就是贪心算法,到束宽为3、到10,你会看到一个很大的改善。但是当束宽从1000增加到3000时,效果就没那么明显了。

束搜索算法是一种近似搜索算法(an approximate search algorithm),也被称作启发式搜索算法(a heuristic search algorithm)。如果你听说过广度优先搜索和深度优先搜索,这些都是精确的搜索算法(exact search algorithms),束搜索运行的更快,但是不能保证一定能找到argmax的准确的最大值。

3.5 Error analysis in beam search

我们前面讨论过很多关于误差分析(error analysis)的问题。有时你想知道是否应该增大束宽,我的束宽是否足够好,你可以计算一些简单的东西来指导你需要做什么,来改进你的搜索算法。我们来讨论一下。

机器翻译举例 “Jane visite l’Afrique en septembre”。
人工翻译: Jane visits Africa in September,我会将这个标记为L5W3-Seq2Seq - 图35
翻译模型:Jane visited Africa last September,我们将它标记为L5W3-Seq2Seq - 图36。它改变了句子的原意。

翻译模型有两个主要部分,一个是神经网络模型,或说是序列到序列模型(sequence to sequence model),我们将这个称作是RNN模型。另一部分是束搜索算法,以某个集束宽度B运行。

我们要找出造成这个错误结果的原因,是因为RNN,还是因为束搜索。

RNN (循环神经网络)实际上是个编码器和解码器(the encoder and the decoder),它会计算L5W3-Seq2Seq - 图37#card=math&code=P%28y%7Cx%29&id=TkbIh)。你此时能做的最有效的事就是用RNN来计算L5W3-Seq2Seq - 图38#card=math&code=P%28y%5E%2A%7Cx%29&id=SrpXt)和L5W3-Seq2Seq - 图39#card=math&code=P%28%5Chat%20y%7Cx%29&id=RR2jT),然后比较一下这两个值哪个更大。

第一种情况,RNN模型的输出结果L5W3-Seq2Seq - 图40#card=math&code=P%28y%5E%2A%7Cx%29&id=rXwy3) 大于L5W3-Seq2Seq - 图41#card=math&code=P%28%5Chat%20y%7Cx%29&id=PGLII),这意味着什么呢?束搜索算法选择了L5W3-Seq2Seq - 图42
你得到L5W3-Seq2Seq - 图43的方式是,用一个RNN模型来计算L5W3-Seq2Seq - 图44#card=math&code=P%28y%7Cx%29&id=iOW27),然后束搜索算法做的就是尝试寻找使L5W3-Seq2Seq - 图45#card=math&code=P%28y%7Cx%29&id=JXweP)最大的L5W3-Seq2Seq - 图46,即L5W3-Seq2Seq - 图47#card=math&code=arg%5C%3B%20max_y%20P%28y%7Cx%29&id=B7HIq)。但是现在,L5W3-Seq2Seq - 图48#card=math&code=P%28y%5E%2A%7Cx%29&id=U3fM1) 比 L5W3-Seq2Seq - 图49#card=math&code=P%28%5Chat%20y%7Cx%29&id=fz3Md)大,这说明束搜索算法不能够给你一个能使L5W3-Seq2Seq - 图50#card=math&code=P%28y%7Cx%29&id=cHWI2)最大化的L5W3-Seq2Seq - 图51值,因为束搜索算法的任务就是寻找一个L5W3-Seq2Seq - 图52的值来使这项更大,但是它却选择了L5W3-Seq2Seq - 图53,而L5W3-Seq2Seq - 图54实际上能得到更大的值。因此这种情况下你能够得出是束搜索算法出错了。

第二种情况是L5W3-Seq2Seq - 图55#card=math&code=P%28y%5E%2A%7Cx%29&id=FFQSk)小于或等于L5W3-Seq2Seq - 图56#card=math&code=P%28%5Chat%20y%7Cx%29&id=YyeQ5)。
在我们的例子中,L5W3-Seq2Seq - 图57 是比 L5W3-Seq2Seq - 图58更好的翻译结果,不过根据RNN模型的结果,L5W3-Seq2Seq - 图59#card=math&code=P%28y%5E%2A%29&id=LJXNX) 是小于L5W3-Seq2Seq - 图60#card=math&code=P%28%5Chat%20y%29&id=soc8X)的,也就是说,相比于L5W3-Seq2Seq - 图61L5W3-Seq2Seq - 图62成为输出的可能更小。因此在这种情况下,看来是RNN模型出了问题。这里我略过了有关长度归一化的细节,如果你用了某种长度归一化,那么你要做的就不是比较这两种可能性大小,而是比较长度归一化后的最优化目标函数值。

所以误差分析过程看起来就像下面这样。你先遍历开发集,然后在其中找出算法产生的错误。对每一个错误进行误差分析,尝试确定这些错误是搜索算法出了问题,还是生成目标函数(束搜索算法使之最大化)的RNN模型出了问题。只有当你发现是束搜索算法造成了大部分错误时,才值得花费努力增大集束宽度。相反地,如果你发现是RNN模型出了更多错,那么你可以进行更深层次的分析,来决定是需要增加正则化还是获取更多的训练数据,抑或是尝试一个不同的网络结构,或是其他方案。你在第三门课中了解到各种技巧都能够应用在这里。

3.6 Bleu Score(以后看)

机器翻译有一大难题,比如一个法语句子可以有多种英文翻译而且都同样好,当有多个同样好的答案时,怎样评估一个机器翻译系统呢?要怎样衡量准确性呢?
常见的解决办法是,通过一个叫做BLEU得分(the BLEU score)的东西来解决。

Papineni et. al., 2002. Bleu: A method for automatic evaluation of machine translation

3.7 Attention Model Intuition

在本周大部分时间中,你都在使用这个编码-解码(Encoder-Decoder )的构架来完成机器翻译。当你使用RNN读一个句子,于是另一个会输出一个句子。我们要对其做一些改变,称为注意力模型(the Attention Model),并且这会使它工作得更好。

L5W3-Seq2Seq - 图63

当给定一个很长的法语句子,在你的神经网络中,这个绿色的编码器要做的就是读整个句子,然后记忆整个句子,在感知机中传递(store it in the activations conveyed)。而对于这个紫色的解码网络,将生成英文翻译。在这个编码解码结构中,会看到它对于短句子效果非常好,但是对于长句子而言,比如说大于30或者40词的句子,它的表现就会变差。

而人工翻译,首先会做的可能是先翻译出句子的部分,再看下一部分,一点一点地翻译。注意力模型它翻译得很像人类,一次翻译句子的一部分。在这个视频中,我想要给你们注意力机制运行的一些直观的东西。然后在下个视频中讲述细节。

让我们用一个短句举例说明一下。假定使用一个双向的RNN(a bidirectional RNN)计算每个输入单词的的特征集(set of features),然后使用另一个RNN生成英文翻译,这里用L5W3-Seq2Seq - 图64表示RNN的隐藏状态(the hidden state in this RNN),而不用L5W3-Seq2Seq - 图65来表示激活值,避免和BRNN里的激活值L5W3-Seq2Seq - 图66混淆。

L5W3-Seq2Seq - 图67

当你尝试生成第一个词时,应该看输入的法语句子的哪个部分?似乎你应该先看第一个单词,或者它附近的词。但是你别看太远了,比如说看到句尾去了。所以注意力模型就会计算注意力权重a set of attention weights)。

我们将用L5W3-Seq2Seq - 图68来表示当你生成第一个词时你应该放多少注意力在这个第一块信息处,这就是注意力权重,L5W3-Seq2Seq - 图69它告诉我们当你尝试去计算第一个词Jane时,我们应该花多少注意力在输入的第二个词上面。同理这里是L5W3-Seq2Seq - 图70。这就是RNN的一个单元,如何尝试生成第一个词的。(蓝色笔记)

对于RNN的第二步,我们将有一个新的隐藏状态L5W3-Seq2Seq - 图71,我们也会用一个新的注意力权值集(a new set of the attention weights),我们将用L5W3-Seq2Seq - 图72来告诉我们什么时候生成第二个词, 那么visits就会是第二个标签了(the ground trip label)。我们应该花多少注意力在输入的第一个法语词上。然后同理L5W3-Seq2Seq - 图73,接下去也同理。当然,我们生成的第一个词Jane也会输入到L5W3-Seq2Seq - 图74,于是我们就有了需要花注意力的上下文。(紫色笔记)

第三步L5W3-Seq2Seq - 图75同理。(绿色笔记)

3.8 Attention Model

在上个视频中你已经见到了,注意力模型如何让一个神经网络只注意到一部分的输入句子。让我们把这些想法转化成确切的式子,来实现注意力模型。

Bahdanau et. al., 2014. Neural machine translation by jointly learning to align and translate

L5W3-Seq2Seq - 图76

使用和上一节相同的网络结构,输入的句子传递给一个BRNN,计算每个词的特征。为了简化每个时间步的记号,我就用L5W3-Seq2Seq - 图77来表示前向和后向的特征值对,所以L5W3-Seq2Seq - 图78就是时间步L5W3-Seq2Seq - 图79上的特征向量。为了保持记号的一致性,我们用L5W3-Seq2Seq - 图80来索引法语句子里面的词。
L5W3-Seq2Seq - 图81

接下来是一个单向的RNN,用状态L5W3-Seq2Seq - 图82生成翻译。对于第一个时间步,它的输入是上下文L5W3-Seq2Seq - 图83,C是被注意力权重加权的不同时间步中的特征值,注意力权重,即L5W3-Seq2Seq - 图84L5W3-Seq2Seq - 图85… 公式化的注意力权重将会满足非负的条件,且它们加起来等于1。
L5W3-Seq2Seq - 图86
这个公式的意思是,我们在生成第一个输出的时候,应该花多少注意力在第L5W3-Seq2Seq - 图87个输入词上。

下一个时间步,你会生成第二个输出。相似的,有一个新的注意力权重集,将它们相加产生一个新的上下文,这个也是输入,且允许你生成第二个词。

这里的神经网络看起来很像相当标准的RNN序列,这里有着上下文向量作为输出,我们可以一次一个词地生成翻译,我们也定义了如何通过这些注意力权重和输入句子的特征值来计算上下文向量。

重点来了,如何计算这些注意力权重?

L5W3-Seq2Seq - 图88,是你在生成第t个输出的翻译词时,应该花费在L5W3-Seq2Seq - 图89上的注意力的权重。公式如下

L5W3-Seq2Seq - 图90

softmax是为了确保这些权重加起来等于1。

那么,如何计算L5W3-Seq2Seq - 图91?一种方法是用下面这样的小的神经网络来计算e项。
L5W3-Seq2Seq - 图92

L5W3-Seq2Seq - 图93是 RNN 上个时间步的隐藏状态,也就是说上个时间步的的特征是另一个输入。直观来想就是,如果你想要决定要花多少注意力在 L5W3-Seq2Seq - 图94 的激活值上,上一个时间步的的隐藏状态的激活值似乎有着重要影响。

L5W3-Seq2Seq - 图95

所以训练这个小神经网络,去学习L5W3-Seq2Seq - 图96(即L5W3-Seq2Seq - 图97)。相信反向传播算法,相信梯度下降算法学到一个正确的函数。这个小型的神经网络做了一件相当棒的事情,告诉你L5W3-Seq2Seq - 图98应该花多少注意力在L5W3-Seq2Seq - 图99上面,然后这个式子确保注意力权重加起来等于1,于是当你持续地一次生成一个词,这个神经网络实际上会花注意力在右边的这个输入句子上,它会完全自动的通过梯度下降来学习。

这个算法的一个缺点就是时间复杂是L5W3-Seq2Seq - 图100#card=math&code=O%28n%5E3%29&id=BPAis),如果你有L5W3-Seq2Seq - 图101个输入单词和L5W3-Seq2Seq - 图102个输出单词,于是注意力参数的总数就会是L5W3-Seq2Seq - 图103,所以这个算法有着三次方的消耗。但是在机器翻译的应用上,输入和输出的句子一般不会太长,可能三次方的消耗是可以接受,但也有很多研究工作,尝试去减少这样的消耗。

那么讲解注意想法在机器翻译中的应用,就到此为止了。这个想法也被应用到了其他的很多问题中,比如给图片加标题(image captioning)。下面这篇论文显示了一个很相似的结构,在写图片标题的时候,一次只花注意力在一部分的图片上面。

[Xu et. al., 2015. Show, attend and tell: Neural image caption generation with visual attention]

在之前的练习中,你应用了注意力,在日期标准化的问题(the date normalization problem)上面,问题输入了像这样的一个日期,把它标准化成标准的形式。
July 20th 1969 → 1969-07 -20
23 April, 1564 → 1564-04-23
用一个序列的神经网络,即序列模型去标准化到这样的形式。

其他可以做的有意思的事情是看看可视化的注意力权重(the visualizations of the attention weights)。这个一个机器翻译的例子,这里被画上了不同的颜色,输入输出词对应的格子,可以看到注意力权重相对较高,因此这显示了当它生成特定的输出词时通常会花注意力在输入的正确的词上面。

L5W3-Seq2Seq - 图104

这就是注意力模型,在深度学习中真的是个非常强大的想法。在本周的编程练习中,我希望你可以享受自己应用它的过程。

3.9 Speech recognition

seq2seq模型应用于音频数据(audio data),比如语音(speech)。

现在你有一个音频片段L5W3-Seq2Seq - 图105an audio clip, x),你的任务是自动地生成文本L5W3-Seq2Seq - 图106。假如这个我说的音频片段的内容是:”the quick brown fox“(敏捷的棕色狐狸),这时我们希望一个语音识别算法(a speech recognition algorithm),通过输入这段音频,然后输出音频的文本内容。

考虑到人的耳朵并不会处理声音的原始波形,而是通过一种特殊的物理结构来测量这些不同频率和强度的声波。音频数据的常见预处理步骤,就是运行这个原始的音频片段,然后生成一个声谱图(a spectrogram),就像这样。同样地,横轴是时间,纵轴是声音的频率(frequencies),而图中不同的颜色,显示了声波能量的大小(the amount of energy),也就是在不同的时间和频率上这些声音有多大。

L5W3-Seq2Seq - 图107

通过这样的声谱图,或者你可能还听过人们谈到过伪空白输出(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小时的文本音频数据集,都被认为是合理的大小。

那么,如何建立一个语音识别系统呢?在上一节视频中,我们谈到了注意力模型,所以,你可以用一个注意力模型,在横轴上,也就是在输入音频的不同时间帧上,来输出文本描述,如”the quick brown fox“,或者其他语音内容。

L5W3-Seq2Seq - 图108

还有一种效果也不错的方法,就是用CTC损失函数来做语音识别。CTC就是Connectionist Temporal Classification,来自论文

[Graves et al., 2006. Connectionist Temporal Classification: Labeling unsegmented sequence data with recurrent neural networks]

算法思想如下:

假设语音片段内容是某人说:”the quick brown fox“,这时我们使用一个新的网络,结构如下图所示。我在这里画的只是一个简单的单向RNN结构,然而在实际中,它有可能是双向的LSTM结构,或者双向的GIU结构,并且通常是很深的模型。这里输入L5W3-Seq2Seq - 图109和输出L5W3-Seq2Seq - 图110的数量都是一样的。

L5W3-Seq2Seq - 图111

注意一下这里时间步的数量,它非常地大。在语音识别中,通常输入的时间步数量要比输出的时间步的数量多出很多。举个例子,比如你有一段10秒的音频,并且特征(features)是100赫兹的,即每秒有100个样本,于是这段10秒的音频片段就会有1000个输入。但可能你的输出就没有1000个字符。

输入输出长度不同怎么办呢?CTC损失函数允许RNN生成这样的输出:我们这里用下划线表示空白符,这句话开头的音可表示为ttth_eee ,然后这里可能有个空格,我们用这个来表示空格,之后是 qqq_,这样的输出也被看做是正确的输出。

CTC损失函数的一个基本规则是将空白符之间的重复的字符折叠起来,再说清楚一些,我这里用下划线来表示这个特殊的空白符(a special blank character),它和空格(the space character)是不一样的。所以thequick之间有一个空格符,所以我要输出一个空格,通过把用空白符所分割的重复的字符折叠起来,然后我们就可以把这段序列折叠成”the q“。这样一来,最后我们得到的文本会短上很多。

于是这句”the quick brown fox“包括空格一共有19个字符,通过允许神经网络有重复的字符和插入空白符,使得它能强制输出1000个字符来表示这段19个字符长的输出。

希望这能给你一个粗略的理解,理解语音识别模型是如何工作的,注意力模型是如何工作的,以及CTC模型是如何工作的,以及这两种不同的构建这些系统的方法。

3.10触发字检测(Trigger Word Detection)

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

触发字系统的例子包括Amazon echo,它通过单词Alexa唤醒;还有百度DuerOS设备,通过”小度你好”来唤醒;苹果的SiriHey Siri来唤醒;这就是触发字检测系统。假如你在卧室中,有一台Amazon echo,你可以在卧室中简单说一句: Alexa, 现在几点了?就能唤醒这个设备。它将会被单词”Alexa“唤醒,并回答你的询问。

有关于触发字检测系统的文献,还处于发展阶段。我这里就简单向你介绍一个能够使用的算法好了。现在有一个这样的RNN结构,我们要做的就是把一个音频片段(an audio clip)计算出它的声谱图特征(spectrogram features)得到特征向量L5W3-Seq2Seq - 图112, L5W3-Seq2Seq - 图113, L5W3-Seq2Seq - 图114..,然后把它放到RNN中,最后定义我们的目标标签L5W3-Seq2Seq - 图115

假如音频片段中的这一点是某人刚刚说完一个触发字,比如”Alexa“,或者”小度你好” ,那么在这一点之前,你就可以在训练集中把目标标签都设为0,然后在这个点之后把目标标签设为1。假如在一段时间之后,触发字又被说了一次,比如是在这个点说的,那么就可以再次在这个点之后把目标标签设为1。这样的标签方案对于RNN来说是可行的,并且确实运行得非常不错。不过该算法一个明显的缺点就是它构建了一个很不平衡的训练集(a very imbalanced training set),0的数量比1多太多了。

L5W3-Seq2Seq - 图116

这里还有一个解决方法,虽然听起来有点简单粗暴,但确实能使其变得更容易训练。比起只在一个时间步上去输出1,其实你可以在输出变回0之前,多次输出1,或说在固定的一段时间内输出多个1。这样的话,就稍微提高了1与0的比例。

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