《深度学习工程师-吴恩达》05序列模型—序列模型和注意力机制 学习笔记
作者:jliang
1.重点归纳
1)基础模型
(1)Sequence to sequence翻译模型
(2)Image to sequence图像描述模型:输入一张图片,它能自动地输出图片的描述
2)机器翻译
(1)机器翻译是建立一个条件语音模型
- 机器翻译模型则包含encode网络和decode网络,decode网络和语言模型的网络几乎一样,不同的是语言模型总是以零向量开始,而机器翻译模型以encode网络计算出的一系列向量来表示输入句子,并以这个向量开始decode网络。
- 相比语言模型输出任意句子的概率,翻译模型会输出句子的翻译(如英语),这取决于输入的句子(如法语),换句话来说就是将估计一个英文翻译的概率,所以它是一个条件语言模型。
(2)翻译模型将法语翻译成英语,输入法语句子,模型会告诉你各种英语翻译所对应的可能性,要找到一个英语句子y使得条件概率最大化。
- 使用Beam Search(束搜索)算法使得arg maxy<1>,…,y<T>P(y<1>,…,y<T>|x)最大化
- 贪心搜索生成第一个词的分布之后,它将会根据你的条件语言模型挑选出最有可能的第一个词,并不能使得整体的概率最大化,所以不能使用贪心算法。
3)定向搜索/束搜索(Beam Search)
(1)Beam Search算法首先挑选出输出的英语翻译中的第一个单词,保留概率最大的前B个单词及其概率。
(2)把前面得到的概率值最大的B个单词逐一输入解码网络的下一个时间步,再分别获取这个时间步输出单词的概率,保留py<1>,y<2>X概率最大的前B个两个单词对。注意,前面得到的B个单词的某些单词在此步有可能被排除。
(3)当B=1时,Beam search算法退化成贪婪算法。
4)改进定向搜索
(1)目标函数取log值来解决数据下溢的问题
- beam search算法就是最大化这个概率:argmaxyt=1TyP(y<t>|x,y<1>,…,y<t-1>),多个小于1的值相乘会造成数据下溢。
- 一般计算上面公式的log值来解决数据向下溢出的问题,因为log单调递增函数,所以求log后的最大值与求原来概率的最大值等价。
- 概率的log值通常小于等于1,所以加起来越的项越多,得到的结果就越负(越小)。
(2)对beam search算法进行长度归一化
- 这个目标函数有一个缺点,它可能不自然地倾向于简短的翻译结果。因为短句子的概率是由更少数量的小于1的数字乘积得到的,所以概率值更大。
- 把目标函数进行长度归一化
- α是算法的一个超参数,一般取值(0,1),需要调整大小来得到最好的结果。
- α=0时相当于不进行归一化。
(3)束宽B选择
- B越大,选择越多,你找到的句子可能越好。但同时,算法的计算代价越大,内存占用也会增大,因为需要把很多的选择保存起来。
- 如果使用很小的B值,结果会没有那么好,因为在算法运行中保存的选择更少,但算法运行速度很快,内存占用也小。
- 在实际应用中,可以把束宽设为10。对于产品系统来说束宽等于100很大,但对科研而言,为了有个最好的结果用来发论文,也经常看到大家使用束宽为1000或3000。在实现应用时,从束宽为1开始慢慢增大到一个很大的束宽。
5)定向搜索误差分析
(1)模型有两个主要部分
- 神经网络模型/RNN序列模型,实际上编码器和解码器
- 束搜索算法
(2)误差分析是为了找出翻译不好的原因是RNN模型还是束搜索算法的问题。
(3)误差分析方法:用这个模型来计算真实值的概率Py*x,同时也用你的RNN模型来计算预测值的概率P(y|x),然后比较Py*x和P(y|x)两个值哪个更大,再根据这个比较结果来定位是RNN还是束搜索算法的问题更大。此处忽略长度归一化这种情况,如果使用了某种长度归一化,那么要做的就是比较长度归一化后的最优化目标函数值。
- :束搜索算法上不能够给你一个使P(y|x)最大化的y值,因为束搜索算法的任务就是寻找一个y值来使得这P(y|x)最大化。
- :虽然y*是一个更好的翻译结果,RNN模型却赋予它更低的可能性,所以是RNN模型出了问题。
(4)此处忽略长度归一化这种情况,如果使用了某种长度归一化,那么要做的就是比较长度归一化后的最优化目标函数值。
(5)误差分析步骤
- 先遍历验证集,找出算法预测错误的样本。
- 逐一计算预测值以及label值的概率,并根据上面的两者情况判断是RNN出问题还是束搜索出问题,把结果记录在表格中。
- 通过上面的过程就能够执行误差分析,得出束搜索算法和RNN模型出错的比例是多少,通过这个能够发现这两部分中哪个是产生更多错误的原因。
- 如果是束搜索出了更多错,才值得花时间去增大束宽度。
- 如果是RNN模型出了更多错,那就可以进行更深层次的分析来决定是需要增大正则化还是获得更多的训练数据,或者是尝试不同的网络结构。
6)注意力模型
(1)普通RNN翻译模型翻译一个很长的句子,编码器会读取整个句子,然后记忆整个句子,再传递给解码器,解码器再生成英语翻译。人工翻译会读取句子的一小部分,然后翻译一部分,接着再读取并翻译下一部分。
(2)普通RNN翻译模型对短句子效果非常好,Bleu得分比较高,但随着句子长度加大得分变小。而注意力模型不会随着句子长度边长而得分变小。
(3)注意力翻译模型
- 使用双向RNN模型,为了计算每个输入单词的特征集,它们的输出会被加权输入到解码器中。
- 使用另外一个RNN来生成翻译,每一时间步t的输出都使用输入的几个时间步t'的输出值加权后作为输入,而注意力权重取决于解码器的上一步输出以及编码器的几个时间步的输出。
(4)解码器RNN向前进一次生成一个词,直到最终生成EOS。每一步的注意力权重α<t,t>告诉你当你尝试生成第T个英文单词时,它应该花多少注意力在第t个法语输入单词上面。当生成一个特定的英文单词时,这允许它在每个时间步去看周围词距内的法语输入单词要花多少注意力。
7)注意力模型
(1)解码器第一个单词输出对应的上下文c<1>取决于注意力参数α<1,1>、α<1,2>和α<1,3>等,α参数告诉我们上下文有多少取决于我们得到的特征,或者我们从不同时间步中得到的激活值。
(2)定义上下文的方式实际上来源于被注意力权重加权不同时间步中的特征值
α<t,t'>是在t'时花在a<t'>上的注意力大小,t为输出时间步,t'为输入时间步。即:当你生成t处生成输出词,你应该花多少注意力在第t'个输入词上面。
(3)注意力权重α<t,t'>
- 使用了softmax来确保这些权重加起来等于1:α<t,t'>=exp(e<t,t'>)t'Txexp(e<t,t'>)。
- 使用一个很小的神经网络来计算e<t,t'>,s<t-1>是解码器在上个时间步的状态,a<t'>是输入时间步t'的特征。
- 花多少注意力在t'的激活值上很大程度上取决于你上一个时间步隐藏状态的激活值。
- α<t,t'>和e<t,t'>取决于s<t-1>和a<t'>。但是我们不知道具体函数是什么,所以我们可以做的事情就是训练一个很小的神经网络去学习这个函数到底是什么,相信反向传播算法和梯度下降算法学到一个正确的函数。
- 这个算法的一个缺点就是它要花费三次方的时间,在机器翻译的应用上,输入和输出的句子一般不会太长,所以三次方的消耗是可以接受的。
(4)注意力机制也被应用到了其他的很多问题上,如给图片加标题,当你在写图片标题的时候,一次只花注意力在一部分的图片上面。
8)语音识别
(1)语音识别问题:输入一个音频片段x,自动生成文本y。
- 人的耳朵并不会处理声音的原始波形,而是通过一种特殊的物理结构来测量这些不同频率和强度的声波。音频数据的常见预处理步骤就是运行这个原始的音频片段,然后生成一个声谱图。横轴是时间,纵轴是声音的频率,颜色的不同显示了声波能量的大小(即不同时间和频率上的声音有多大)。
- 语音识别系统用音位来构建,人工设计的基本单元:the含有“th”和“e”的音,quick有“k”,“w”,“i”,“k”的音等。语音学家过去把这些音作为声音的基本单元写下来,把这些语音分解成这些基本的声音单元。语音学家认为用这些基本的音位单元来表示音频是做语音识别最好的办法。
- 在end-to-end模型中,使用一个很大的数据集构建一个系统,通过向系统中输入音频片段,然后直接输出音频的文本。
(2)注意力模型来做语音识别:在输入音频不同时间帧上使用一个注意力模型来输出文本描述,输出每个字符来组成句子。
(3)用CTC损失函数来做语音识别
- 我们使用一个新的网络(一个很深的双向GRU或LSTM模型),输入x和输出y的数量都是一样的。
- 通常输入的时间步数量要比输出的时间步的数量大很多,如:有一段10秒的音频,特征是100赫兹,即每秒有100个样本。这段10秒的音频片段就有1000个输入,但输出没有1000个字符。
- CTC损失函数运行RNN生成这样的输出:“ttt_h_eee___ ___qqq__”,CTC损失函数的一个基本规则是将空白符之间的重复的字符折叠起来,下划线“_”代表特殊的空白符,它和空格是不一样的。通过重复的字符折叠起来,然后我们就可以把这段序列折叠成“the q”。
- 9)触发字检测
(1)把音频片段计算出它的声谱特征x1, x2,x3,…,然后把它放到RNN中。
(2)然后定义输出类标y
- 假如音频片段中某一点(上图中第一条竖线处),某人刚刚说完一个触发字,比如“Alexa”。那么在这一点之前的输出标签都为0,在这一点时输出1。
- 假如在一段时间之后,触发字又被说了一次(上图中第二条竖线处),则这个第二个点的输出也为1,其他的点都是输出0。
(3)这是一个很不平衡的训练集,0比1多太多了,改进方案:
- 前面是只有在说触发字时输出1,此处可以在输出1之后继续多输出几个1,或者在固定的一段时间内输出多个1。
- 这样就可以稍微提高了1与0的比例,虽然有点简单粗暴,但是有效。
2. 基础模型
1)Sequence to sequence翻译模型
(1)先构建一个编码网络,它是一个RNN(GRU或LSTM)网络。逐一输入待翻译句子的每个单词,当是网络不进行预测。
(2)然后构建一个解码网络,编码网络的输出值a(以及c)输入到解码网络中,并进行预测输出,直至输出翻译后的完整句子才结束。
2)Image to sequence图像描述模型
(1)输入一张图片(如这张猫的图片),它能自动地输出图片的描述:一只猫坐在椅子上。
(2)将图片输入到卷积神经网络中,比如一个预训练的AlexNet结构,然后让其学习图片的编码。编码网络:删除softmax层,保留至最后一层全连接层,这个全连接层的数值就是一个n维(图中为4096维)的向量来表示图片。
(3)把这个向量输入到RNN中,RNN要做的就是生成图像的描述,类似翻译模型中的解码网络。
(4)该方法在图像描述领域相当有效,特别是当你想生成的描述不是特别长时更有效。
3. 选择最可能的句子
1)可以把机器翻译想成是建立一个条件语音模型
(1)在语言模型中,可以让你能够估计句子的可能性,也可以将它用于生成一个新的句子。
(2)机器翻译模型则包含encode网络和decode网络,decode网络和语言模型的网络几乎一样。机器翻译模型与语言模型非常相似,不同的是语言模型总是以零向量开始,而机器翻译模型以encode网络计算出的一系列向量来表示输入句子,并以这个向量开始decode网络。
(3)相比语言模型输出任意句子的概率,翻译模型会输出句子的翻译(如英语),这取决于输入的句子(如法语),换句话来说就是将估计一个英文翻译的概率,所以它是一个条件语言模型。
2)通过翻译模型将法语翻译成英语,输入法语句子,模型会告诉你各种英语翻译所对应的可能性
(1)并不是从得到的分布中进行随机采样,而是要找到一个英语句子y使得条件概率最大化
(2)在开发机器翻译系统时,想出一个算法来找出合适的y值,使得arg maxy<1>,…,y<T>P(y<1>,…,y<T>|x)最大化,解决这个问题的通用方法就是Beam Search(束搜索)。
(3)为什么不使用贪心搜索?
- 贪心搜索:生成第一个词的分布之后,它将会根据你的条件语言模型挑选出最有可能的第一个词。
- 而我们需要的是一次性选出整个单词序列,使得整体的概率最大化。贪心算法并不能使得整体的概率最大化。
(4)例子:以下两个句子中第一个句子翻译得更好,第二句太啰嗦。如果使用贪心搜索,在英语中going更加常见,“Jane is going”比“Jane is visiting”概率更大
- Jane is visiting Africa in September.
- Jane is going to be visiting Africa in September.
3)这个翻译模型和之前的语言模型的一个主要区别就是相比之前随机地生成句子,在该模型中,你要找到最有可能的英语翻译,但是可能的句子组合数量过于巨大,无法一一列举,所以我们需要一种合适的搜索算法(如Beam search算法)。
4. 定向搜索/束搜索—Beam Search
1)在机器翻译模型中,我们不想要输出一个随机的翻译结果,而是想要得到最有可能的翻译结果。对于语音识别也一样,给定一个输入的语音片段,我们不希望得到一个随机的文本翻译结果,而是希望得到最好的翻译结果。解决这个问题的常用方法是Beam Search。
2)例子:翻译句子:Jane is visiting Africa in September
(1)Beam Search算法首先挑选出输出的英语翻译中的第一个单词:用以下网络(绿色为编码网络,紫色为解码网络)来评估第一个单词的概率值,即给定序列X条件下第一个输出y的概率。
- 贪婪算法只会挑出最有可能的那个单词,然后继续。而Beam Search算法会挑出多个选择,会一个参数B(叫集束宽-beam width),即从解码网络中获取softmax输出概率最大的前面B个单词。
- 在这个例子中设B=3,意味着beam search不会只考虑一个可能结果,而是一次会考虑3个。
- 比如对第一个单词,有不同选择的可能性,最后找到了“in”、“jane”和“september”是英语输出的第一个单词的最有可能的三个选项。
- beam search算法会把结果保存起来,以便后面尝试用这三个词。
(2)把前面得到的概率值最大的B个单词逐一输入解码网络的下一个时间步,再分别获取这个时间步输出单词的概率,保留概率最大的前B个两个单词对。注意,前面得到的B个单词的某些单词在此步有可能被排除。
- 此时考虑的是要找到最可能的第一个和第二个单词对,而不仅仅是第二个单词有最大的概率。
- B个单词都有10000个输出概率(假设词库为10000),计算并保留最大的前B个单词对。
- 每一步只会保留B个输出单词序列,前面输出的B个单词可能会在此步被排除。
- 本例子中保留的3个词对为:“in september”、“jane is”和“jane visits”。
(3)继续第3个单词
3)当B=1时,Beam search算法退化成贪婪算法。
5. 改进定向搜索
1)长度归一化就是对beam search算法稍作调整的一种方式,帮助你得到更好的结果。
(1)beam search算法就是最大化这个概率:。由于这个连乘里面的每个概率都小于1(通常远小于1),很多小于1的树乘起来会造成数据下溢。
(2)实践中一般计算上面公式的log值来解决数据向下溢出的问题,因为log单调递增函数,所以求log后的最大值与求原来概率的最大值等价。
(3)如果句子很长,那么句子的概率会很低,所以这个目标函数有一个缺点,它可能不自然地倾向于简短的翻译结果。因为短句子的概率是由更少数量的小于1的数字乘积得到的,所以概率值更大。
(4)概率的log值通常小于等于1,所以加起来越的项越多,得到的结果就越负(越小)。
(5)对算法的另一个改进就是:把目标函数进行长度归一化
- 通常除以翻译结果的单词数量(即α=1),这样可以很明显地减少了对输出长度的结果的惩罚。
- α=1时相当于不进行归一化。
- α是算法的一个超参数,一般取值(0,1),需要调整大小来得到最好的结果。
- 但这样使用α实际上是试探性的,它并没有理论验证,但是大家都发现效果很好,所以很多人都这样做。
2)束宽B选择
(1)B越大,选择越多,你找到的句子可能越好。但同时,算法的计算代价越大,内存占用也会增大,因为需要把很多的选择保存起来。
(2)如果使用很小的B值,结果会没有那么好,因为在算法运行中保存的选择更少,但算法运行速度很快,内存占用也小。
(3)在实际应用中,可以把束宽设为10。对于产品系统来说束宽等于100很大,这也取决于不同的应用。但对科研而言,人们想压榨出全部性能,这样有个最好的结果用来发论文,所以也经常看到大家使用束宽为1000或3000。
(4)在实现应用时,尝试不同的束宽值。当B很大的时候,性能提高会越来越少。对于很多应用来说,从束宽为1开始慢慢增大到一个很大的束宽,也就是贪心算法。
6. 定向搜索的误差分析
1)束搜索算法是一种近似搜索算法,也被称为启发式搜索算法,它不总是输出可能性最大的句子,它仅记录着前3/10/100(取决于B值)种可能,所以需要进行误差分析。
2)对束搜索算法进行误差分析例子
待翻译句子:Jane visite I'Afrique en septembre.
(1)假设在机器人已的dev集中,人工翻译为:Jane visit Africa in September.
(2)当使用已经训练好的RNN模型进行翻译时得到的结果是:Jane visited Africa last September.
(3)模型有两个主要部分
- 神经网络模型/RNN序列模型,实际上编码器和解码器
- 束搜索算法,以某个集束宽度B运行
(4)找出这个不太好的翻译的原因是上面两部分中的哪一个,是RNN模型还是束搜索算法?
- 大家很容易想到去收集更多的训练数据,这总归没什么坏处。但是就像单纯获取更多的训练数据,可能并不能得到预期的表现结果,
- 大家也会想到不行就增大束宽,也是不会错的。但单纯增大束宽,也可能得不到预期的结果。
- 3)分解问题,弄清楚什么情况下该用什么解决办法
(1)RNN它会计算P(y|x)
- 结果表明,此时能做的最有效的事就是用这个模型来计算真实值的概率,同时也用你的RNN模型来计算预测值的概率。
(2)然后比较和两个值哪个更大,再根据这个比较结果来定位是RNN还是束搜索算法的问题更大。
情况一:
- 意味着束搜索算法出错了。
- 束搜索算法选择了y,但y*获得更大的输出概率。
- 束搜索算法上不能够给你一个使P(y|x)最大化的y值,因为束搜索算法的任务就是寻找一个y值来使得这P(y|x)最大化。
情况二:
- y*是比更好的翻译结果,不过根据RNN模型的结果。
- 虽然y*是一个更好的翻译结果,RNN模型却赋予它更低的可能性,所以是RNN模型出了问题。
(3)此处忽略长度归一化这种情况,如果使用了某种长度归一化,那么要做的就是比较长度归一化后的最优化目标函数值。
4)误差分析过程
(1)先遍历验证集,找出算法预测错误的样本。
(2)逐一计算预测值以及label值的概率,并根据上面的两者情况判断是RNN出问题还是束搜索出问题,把结果记录在表格中
(3)通过上面的过程就能够执行误差分析,得出束搜索算法和RNN模型出错的比例是多少,通过这个能够发现这两部分中哪个是产生更多错误的原因。
- 如果是束搜索出了更多错,才值得花时间去增大束宽度。
- 如果是RNN模型出了更多错,那就可以进行更深层次的分析来决定是需要增大正则化还是获得更多的训练数据,或者是尝试不同的网络结构。
7. Bleu得分(选修)
8. 注意力模型直观理解
1)注意力模型这种思想已经成为深度学习中的最重要的思想之一
(1)像例子中需要翻译这么长的一个法语句子,编码器会读取整个句子,然后记忆整个句子,再传递给解码器,解码器再生成英语翻译。
(2)人工翻译
- 人工翻译不会通过读取整个法语句子,再记忆里面的东西,然后从零开始翻译一个英语句子。
- 人工翻译首先会先翻译句子前面一小部分,再翻译下一部分,一直至翻译完整个句子。
- 人工翻译会通过句子一点一点地翻译,因为记忆整个这么长的句子是非常困难的。
(3)编码解码器对不同的句子长度的Bleu得分
- 在编码器解码器中会看大它对于短句子的效果非常好,它有一个相对高的Bleu得分。
- 对于长句子,它的表现就会变差,因为在神经网络中,记忆非常长的句子是非常困难的。
(4)使用注意力模型进行翻译时,我们看到不同长度的句子都能得到不错的Bleu得分
2)虽然注意力模型源于机器翻译,但它推广到了其他应用领域。
3)注意力模型例子
假设要翻译句子Jane visite I'Afrique en septembre.
(1)使用双向RNN模型,为了计算每个输入单词的特征集,图片中的输出y<1>,y<2>,y<4>,y<4>,y<5>并不是只翻译一个单词。对于句子里的每5个单词,计算一个句子中单词的特征集,也可能是周围的词。
(2)使用另外一个RNN来生成英文翻译
- 图中S值为隐藏状态
- 第一个生成的单词将会是jane,应该看输入的第一个单词,或者它附件的单词(第二第三个单词),但是不需要看太远之后的单词。
- 注意力模型会计算注意力权重(图片中的α<,>),α<1,1>表示生成第一个词时,应该放多少注意力在第一块信息处(此处为第一个输入单词);然后计算第二个注意力权重α<1,2>,代表计算第一个词时应该放多少注意力在第二个输入单词上面;同理还有α<1,3>。即第一个单词同时由输入的前面3个单词决定。
- 当生成第二个输出单词时,将会重新计算每个注意力权重α<2,1>,α<2,2>,α<2,3>,解码器的上一步输出也会输入到解码器中。于是就有了需要花注意力的上下文(图中的c向量)以及上一步的输出,它们一起生成第二个词。
- 注意力权重α<3,t>取决于上一个隐藏状态S<2>以及编码器的和的值。
(3)直观来想就是,解码器RNN向前进一次生成一个词,直到最终生成EOS。每一步的注意力权重α<t,t>告诉你当你尝试生成第T个英文单词时,它应该花多少注意力在第t个法语输入单词上面。当生成一个特定的英文单词时,这允许它在每个时间步去看周围词距内的法语输入单词要花多少注意力。
9. 注意力模型
1)使用双向RNN(GRU或LSTM)计算每个词的特征
(1)代表正向和方向传播RNN时间步t的隐藏状态
(2)解码器第一个单词输出对应的上下文c<1>取决于注意力参数α<1,1>、α<1,2>和α<1,3>等,α参数告诉我们上下文有多少取决于我们得到的特征,或者我们从不同时间步中得到的激活值。
(3)定义上下文的方式实际上来源于被注意力权重加权不同时间步中的特征值
- 于是更公式化的注意力权重将会满足非负的条件(就是大于等于 0),加起来总和等于1,即。
- 上下文:。
- α<t,t'>是在t'时花在a<t'>上的注意力大小,t为输出时间步,t'为输入时间步。即:当你生成t处生成输出词,你应该花多少注意力在第t'个输入词上面。
(4)解码器是标准的RNN序列,这里有着上下文向量作为输出,可以一次一个词地生成翻译。
2)计算注意力权重α<t,t'>
(1)α<t,t'>等于当第t个输出的翻译词y<t>应该放到a<t'>注意力的数量。
,关键是使用了softmax来确保这些权重加起来等于1。
(2)使用一个很小的神经网络来计算e<t,t'>,s<t-1>是解码器在上个时间步的状态,a<t'>是输入时间步t'的特征。
- 直观来想就是,花多少注意力在t'的激活值上很大程度上取决于你上一个时间步隐藏状态的激活值。
- 然后对于每一个词都看到它们的特征值。
- 很自然地,α<t,t'>和e<t,t'>取决于s<t-1>和a<t'>。但是我们不知道具体函数是什么,所以我们可以做的事情就是训练一个很小的神经网络去学习这个函数到底是什么,相信反向传播算法和梯度下降算法学到一个正确的函数。
(3)这个算法的一个缺点就是它要花费三次方的时间(时间复杂度为)。
- 如果你有Tx个输入单词和Ty个输出单词,注意力参数的总数就会是Tx*Ty,所以这个算法有着三次方的消耗。
- 在机器翻译的应用上,输入和输出的句子一般不会太长,所以三次方的消耗是可以接受的。
3)注意力机制也被应用到了其他的很多问题上,如给图片加标题
(1)图片加标题就是看一张图片,写下这张图片的标题。
(2)你可以有一个与上面非常类似的结构,看图片然后,当你在写图片标题的时候,一次只花注意力在一部分的图片上面。
4)注意力例子
(1)因为机器翻译是一个非常复杂的问题,在之前的练习中,你应该关注日期标准化的问题上面。
- 输入“July 20th 1969”的一个日期,把它标准化为1969-07-20。
- 输入“23 April, 1564”标准化为1564-04-23。
(2)可以训练一个神经网络(序列模型)输入任何形式的日期,然后使用注意力模型生成标准化的日期形式。
(3)一个有意思的事情就是看看可视化注意力权重,这里不同的权重被画上了不同的颜色。你可以发现对应的输入输出词注意力权重会变高,因此这里显示了当它生成特定的输出词时,通常会花注意力在输入的正确的词上面,包括学习花注意力在哪。
10. 语音辨识
1)语音识别问题
(1)输入一个音频片段x,自动生成文本y。
(2)下图是气压随着时间而变化的音频片段,横轴是时间,麦克风的作用是测量出微小的气压变化。人之所以能听到声音,是因为耳朵能够探测到这些微小的气压变化。
(3)人的耳朵并不会处理声音的原始波形,而是通过一种特殊的物理结构来测量这些不同频率和强度的声波。
- 音频数据的常见预处理步骤就是运行这个原始的音频片段,然后生成一个声谱图。
- 横轴是时间,纵轴是声音的频率,颜色的不同显示了声波能量的大小(即不同时间和频率上的声音有多大),如下声谱图:
- 伪空白输出也经常应用于预处理步骤,人耳所做的计算和这个预处理过程非常相似。
(4)曾经有一段时间,语音识别系统用音位来构建
- 也就是人工设计的基本单元。
- 如果用音位来表示“the quick brown fox”,the含有“th”和“e”的音,quick有“k”,“w”,“i”,“k”的音。
- 语音学家过去把这些音作为声音的基本单元写下来,把这些语音分解成这些基本的声音单元。语音学家认为用这些基本的音位单元来表示音频是做语音识别最好的办法。
(5)在end-to-end模型中,我们发现这种音位表示法已经不再必要了,而是可以构建一个系统,通过向系统中输入音频片段,然后直接输出音频的文本,而不需要使用这种人工设计的表示方法。
- 一个很大的数据集使这种方法成为了可能。
- 语音识别的研究数据集可能长达300小时,学术界甚至使用3000小时的文本音频数据集。
- 大量的论文所使用的数据集中,有几千种不同的声音,最好的商业系统现在已经训练了超过1万小时的数据,甚至10万小时,并且它还会继续变得更大。
2)用注意力模型来做语音识别
(1)在输入音频不同时间帧上使用一个注意力模型来输出文本描述。
(2)输出每个字符来组成句子。
3)用CTC损失函数来做语音识别
(1)CTC:Connectionist Temporal Classification
(2)假设语音片段内容是某人说“the quick brown fox”,这时我们使用一个新的网络,输入x和输出y的数量都是一样的。图片中使用了单向的RNN,实际可以使用双向LSTM或双向GRU,并且通常是很深的模型。
(3)时间步的数量是非常大的。
- 在语音识别中,通常输入的时间步数量要比输出的时间步的数量大很多。
- 例如:有一段10秒的音频,特征是100赫兹,即每秒有100个样本。这段10秒的音频片段就有1000个输入,但输出没有1000个字符。
(4)CTC损失函数运行RNN生成这样的输出:ttt_h_eee___ ___qqq__。
- 这样的输出也被看做是“the q”正确的输出。
- CTC损失函数的一个基本规则是将空白符之间的重复的字符折叠起来,下划线“_”代表特殊的空白符,它和空格是不一样的。通过重复的字符折叠起来,然后我们就可以把这段序列折叠成“the q”。
- 这样一来你的神经网络就可以有1000个输出了,因为有很多重复的字符和很多空白符。
11. 触发字检测
1)随着语音识别的发展,越来越多的设备可以通过你的声音来唤醒,这叫做触发字检测系统。
2)例子
Amazon Echo通过“Alexa”触发字来唤醒系统。
3)触发字检测系统的文献还处于发展状态,对于触发字检测最好的算法是什么,目前还没有一个广泛的定论。
4)其中一种触发字检测系统
(1)把音频片段计算出它的声谱特征x1, x2,x3,…,然后把它放到RNN中。
(2)然后定义输出类标y
- 假如音频片段中某一点(上图中第一条竖线处),某人刚刚说完一个触发字,比如“Alexa”。那么在这一点之前的输出标签都为0,在这一点时输出1。
- 假如在一段时间之后,触发字又被说了一次(上图中第二条竖线处),则这个第二个点的输出也为1,其他的点都是输出0。
(3)这样的标签方案可行,不过有一个明显的缺点,就是它构建了一个很不平衡的训练集,0比1多太多了。改进方案:
- 前面是只有在说触发字时输出1,此处可以在输出1之后继续多输出几个1,或者在固定的一段时间内输出多个1。
- 这样就可以稍微提高了1与0的比例,虽然有点简单粗暴,但是有效。