采用循环神经网络能够建立各种各样的序列模型(Sequence Model)。加入一些注意力机制,能够使这些序列模型更加强大。
Seq2Seq模型
2014年Cho等人在论文[Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation]中首次提出了Seq2Seq(Sequence-to-Sequence)模型。从机器翻译到语音识别,这种模型能够在各种序列到序列的转换问题中得到应用。
一个Seq2Seq模型中可分成编码器(Encoder)和译码器(Decoder)两部分,它们通常是两个不同的神经网络。如下图是谷歌机器翻译团队的Sutskever等人2014年在论文[Sequence to Sequence Learning with Neural Networks]中提出的机器翻译模型:
上面法语中的词依次输入作为编码器的RNN的时间步中,这个RNN可以是GRU或LSTM。将编码器的最后输出作为译码器的输入,译码器也是一个RNN,训练译码器作出正确的翻译结果。
这种Enconder-Decoder的结构,也可以应用在图像标注(Image Caption)上。2014年百度研究所的毛俊骅等人在论文[DDeep Captioning with Multimodal Recurrent Neural Networks (m-RNN)]中提出了如下图中的结构:
上面将图像输入了一个作为编码器的AlexNet结构的CNN中,最后的Softmax换成一个RNN作为译码器,训练网络输出图像的标注结果。
另外两篇论文[Show and Tell: A Neural Image Caption Generator]和 [Deep Visual-Semantic Alignments for Generating Image Descriptions]中, 也提到了这种结构。
机器翻译用到的Seq2Seq模型中,译码器所做的工作与前面讲过的语言模型的采样过程类似,只不过在机器翻译中,用编码器的输出代替语言模型中的
0
0
作为译码器中第一个时间步的输入,如下图所示:
换句话说,机器翻译其实是一个输入为法语的条件下,希望以对应的英语作为输出的语言模型,所以机器翻译的过程也就相当于建立一个条件语言模型(Conditional Language Model)的过程。
采用大量的数据训练好一个机器翻译系统后,对于一个相同的句子,由于译码器进行的是随机采样过程,输出的可能会是多种或好或坏的结果:
所以对训练好的机器翻译系统,还需要加入一些算法,使其总是输出最好的翻译结果。
考虑直接使用CS中的贪心搜索(Greedy Search)算法,让译码器中每个时间步都取概率最大的那个词,得到的翻译结果还是会不尽人意。
集束搜索
步骤
Seq2Seq模型中,译码器的输出结果总是在RNN中采样后得到,造成模型训练完毕后,得到测试的结果参差不齐,集束搜索(Beam Search)算法能很好地解决这个问题。这里还是以机器翻译的例子来说明这种算法。
将集束搜索算法运用到机器翻译系统的第一步,是设定一个束长(Bean Width),它代表了译码器中每个时间步的预选单词数量。如下图中
B=3
B
=
3
,则将第一个时间步中预测出的概率最大的
3
3
个词作为首词的预选词,同时保存它们的概率值大小:
如果第一步得到的三个预选词分别为“in”、“jane”和“September”,如下图所示,则第二步中,分别将三个预选词作为第一个时间步的预测结果
y⟨1⟩
y
⟨
1
⟩
输入第二个时间步,得到预测结果
y^⟨2⟩
y
^
⟨
2
⟩
,也就是条件概率值
p(y^⟨2⟩∣x,y⟨1⟩)
p
(
y
^
⟨
2
⟩
∣
x
,
y
⟨
1
⟩
)
:
根据条件概率公式,有:
分别以三个首词预选词作为 y⟨1⟩ y ⟨ 1 ⟩ 进行计算,将得到 30000 30000 个 p(y⟨1⟩,y^⟨2⟩∣x) p ( y ⟨ 1 ⟩ , y ^ ⟨ 2 ⟩ ∣ x ) 。之后还是取其中概率值最大的 B=3 B = 3 个,作为对应首词条件下的第二个词的预选词。比如第二个词的预选词分别是“in”为首词条件下的“September”,”jane”为首词条件下的“is”和“visits”,这样的话首词的预选词就只剩下了“in”和“jane”而排除了“September”。后面的过程以此类推,最后将输出一个最优的翻译结果。
优化
总的来说,集束搜索算法所做的工作就是找出符合以下公式的结果:
然而概率值都是小于 1 1 的值,多个概率值相乘后的结果的将会是一个极小的浮点值,累积到最后的效果不明显且在一般的计算机上达不到这样的计算精度。改进的方法,是取上式的值并进行标准化:
其中的 α α 是一个需要根据实际情况进行调节的超参数。
与CS中的精确查找算法–广度优先查找(Breadth First Search,BFS)、深度优先查找(Depth First Search,DFS)算法不同,集束搜索算法运行的速度虽然很快,但是并不保证能够精确地找到满足 arg max p(y∣x) a r g m a x p ( y ∣ x ) 的结果。
关于束长 B B 的取值,较大的值意味着同时考虑了更多的可能,最后的结果也可能会更好,但会带来巨大的计算成本;较小的 B B 值减轻了计算成本的同时,也可能会使最后的结果变得糟糕。通常情况下,值取一个 10 10 以下地值较为合适。还是要根据实际的应用场景,适当地选取。要注意的是,当 B=1 B = 1 时,这种算法就和贪心搜索算法没什么两样了。
错误分析
在前面的结构化机器学习项目课程中,已经了解过错误分析。集束搜索是一种启发式(Heuristic)搜索算法,它的输出结果不是总为最优的。结合Seq2Seq模型与集束搜索算法构建的机器翻译等系统出错时,差错到底是出现在前者的RNN还是后者的算法中,还是需要通过一些手段,来进行错误分析。
例如对图中的法语,发现机器翻译的结果
y^
y
^
与专业的人工翻译的结果
y∗
y
∗
存在较大的差别。要找到错误的根源,首先将翻译没有差别的一部分“Jane visits Africa”分别作为译码器中其三个时间步的输入,得到第四个时间步的输出为“in”的概率
p(y∗∣x)
p
(
y
∗
∣
x
)
和“last”的概率
p(y^∣x)
p
(
y
^
∣
x
)
,比较它们的大小并分析:
* 若
p(y∗∣x)>p(y^∣x)
p
(
y
∗
∣
x
)
>
p
(
y
^
∣
x
)
,说明是集束搜索时出现错误,没有选择到概率最大的词;
* 若
p(y∗∣x)≤p(y^∣x)
p
(
y
∗
∣
x
)
≤
p
(
y
^
∣
x
)
,说明是RNN模型的表现不够好,预测的第四个词为“in”的概率小于“last”。
分析过程中,可以建立一个如上所示的表格,提高错误查找效率。
机器翻译评估:BLEU指标
BLEU(Bilingual Evaluation Understudy)是一种用来评估机器翻译质量的指标,它早在2002年由Papineni等人在论文[BLEU: a Method for Automatic Evaluation of Machine Translation]中提出。BLEU的设计思想与评判机器翻译好坏的思想是一致的:机器翻译的结果越接近专业的人工翻译,则评估的分值越高。
最原始的BLEU算法很简单:统计机器翻译结果中的每个单词在参考翻译中出现的次数作为分子,机器翻译结果的总词数作为分母。然而这样得到结果很容易出现错误。
如上图的例子中,机器翻译得到的结果是
7
7
个“the”,分母为,每个“the”都在参考翻译中有出现,分子为
7
7
,得到翻译精确度为,这显然是不对的。改进这种算法,将参考翻译中“the”出现的最高次数作为分子,机器翻译结果中“the”的出现次数作为分母,可得精度为
27
2
7
。
上面的方法是一个词一个词进行统计,这种以一个单词为单位的集合统称为uni-gram(一元组)。以uni-gram统计得到的精度
p_1
p
_
1
体现了翻译的充分性,也就是逐字逐句地翻译能力。
两个单词为单位的集合则称为bi-gram(二元组),例如对以上机器翻译结果(
count
c
o
u
n
t
)及参考翻译(
count_clip
c
o
u
n
t
_
c
l
i
p
)以二元组统计有:
bi-gram | count c o u n t | count_clip c o u n t _ c l i p |
---|---|---|
the cat | 2 | 1 |
cat the | 1 | 0 |
cat on | 1 | 1 |
on the | 1 | 1 |
the mat | 1 | 1 |
Count | 6 | 4 |
根据上表,可得到机器翻译精度为 46 4 6 。
以此类推,以n个单词为单位的集合为n-gram(多元组),采用n-gram统计的翻译精度 pn p n 的计算公式为:
以n-gram统计得到的 pn p n 体现了翻译的流畅度。将uni-gram下的 p1 p 1 到n-gram下的 pn p n 组合起来,对这 N N 个值进行几何加权平均得到:
此外,注意到采用n-gram时,机器翻译的结果在比参考翻译短的情况下,很容易得到较大的精度值。改进的方法是设置一个最佳匹配长度(Best Match Length),机器翻译的结果未达到该最佳匹配长度时,则需要接受简短惩罚(Brevity Penalty,BP):
最后得到BLEU指标为:
注意力模型
人工翻译一大段文字时,一般都是阅读其中的一小部分后翻译出这一部分,在一小段时间里注意力只能集中在一小段文字上,而很难做到把整段读完后一口气翻译出来。用Seq2Seq模型构建的机器翻译系统中,输出结果的BLEU评分会随着输入序列长度的增加而下降,其中的道理就和这个差不多。
2014年Bahdanau等人在论文[Neural Machine Translation by Jointly Learning to Align and Translate]中提出了注意力模型(Attention Model)。最初只是用这种模型对机器翻译作出改进,之后其思想也在其他领域也得到了广泛应用,并成为深度学习领域最有影响力的思想之一。
注意力模型中,网络的示例结构如下所示:
底层是一个双向循环神经网络,需要处理的序列作为它的输入。该网络中每一个时间步的激活 a⟨t′⟩ a ⟨ t ′ ⟩ 中,都包含前向传播产生的和反向传播产生的激活:
顶层是一个“多对多”结构的循环神经网络,第 t t 个时间步以该网络中前一个时间步的激活、输出 y⟨t−1⟩ y ⟨ t − 1 ⟩ 以及底层的BRNN中多个时间步的激活 c c 作为输入。对第个时间步的输入 c c 有:
其中的参数 α⟨t,t′⟩ α ⟨ t , t ′ ⟩ 意味着顶层RNN中,第 t t 个时间步输出的中,把多少“注意力”放在了底层BRNN的第 t′ t ′ 个时间步的激活 a⟨t′⟩ a ⟨ t ′ ⟩ 上。它总有:
为确保参数 α⟨t,t′⟩ α ⟨ t , t ′ ⟩ 满足上式,常用Softmax单元来计算顶层RNN的第 t t 个时间步对底层BRNN的第个时间步的激活的“注意力”:
其中的 e⟨t,t′⟩ e ⟨ t , t ′ ⟩ 由顶层RNN的激活 s⟨t−1⟩ s ⟨ t − 1 ⟩ 和底层BRNN的激活 a⟨t′⟩ a ⟨ t ′ ⟩ 一起输入一个隐藏层中得到的,因为 e⟨t,t′⟩ e ⟨ t , t ′ ⟩ 也就是 α⟨t,t′⟩ α ⟨ t , t ′ ⟩ 的值明显与 s⟨t⟩ s ⟨ t ⟩ 、 a⟨t′⟩ a ⟨ t ′ ⟩ 有关,由于 s⟨t⟩ s ⟨ t ⟩ 此时还是未知量,则取上一层的激活 s⟨t−1⟩ s ⟨ t − 1 ⟩ 。在无法获知 s⟨t−1⟩ s ⟨ t − 1 ⟩ 、 a⟨t′⟩ a ⟨ t ′ ⟩ 与 e⟨t,t′⟩ e ⟨ t , t ′ ⟩ 之间的关系下,那就用一个神经网络来进行学习,如下图所示:
![参数阿尔法](https://ws1.sinaimg.cn/large/82e16446gy1fp91hlkm8wj20lk07xglp.jpg)
要注意的是,该模型的运算成本将达到 N2 N 2 。此外,在2015年Xu等人发表的论文[Show, Attend and Tell: Neural Image Caption Generation with Visual Attention]中,这种模型也被应用到了图像标注中。
应用
语音识别
在语音识别中,要做的是将输入的一段语音
x
x
转换为一段文字副本作为输出。
曾经的语音识别系统都是采用人工设计出的音素(Phonemes)识别单元来构建,音素指的是一种语言中能区别两个词的最小语音单位。现在有了端对端深度学习,已经完美没有必要采用这种识别音素的方法实现语音识别。
采用深度学习方法训练语音识别系统的前提条件是拥有足够庞大的训练数据集。在学术界的研究中,3000小时的长度被认为是训练一个语音识别系统时,需要的较为合理的音频数据大小。而训练商用级别的语音识别系统,需要超过一万小时甚至十万小时以上的音频数据。
语音识别系统可以采用注意力模型来构建:
2006年Graves等人在论文[Connectionist Temporal Classification: Labeling unsegmented sequence data with recurrent neural networks]中提出了一种名为CTC(Connectionist Temporal Classification)损失函数计算方法,给语音识别系统的训练过程带来很大帮助。
由于输入的是音频数据,采用RNN建立的语音识别系统中将包含多个时间步,且整个网络中输出的数量往往是小于输入的数量的,也就是说不是每一个时间步都有对于的输出。而CTC的主要优点,是可对没有对齐的数据进行自动对齐。
如上图中,以一句意为图中下面的句子,长度为10s频率为100Hz的语音作为输入,则这段语音序列可分为1000个部分,分别输入RNN的时间步中,而RNN可能不会将1000个作为输出。
CTC损失计算方法允许RNN输出一个如图中所示的结果,允许以“空白(Blank)”作为输出的同时,也会识别出词之间存在的“空格(Space)”标记,CTC还将把未被“空白”分隔的重复字符折叠起来。
关于CTC的更多细节详见论文内容。
触发词检测
触发词检测(Trigger Word Detection)现在已经被应用在各种语音助手以及智能音箱上。例如在Windows 10上能够设置微软小娜用指令“你好,小娜”进行唤醒,安卓手机上的Google Assistant则可以通过“OK,Google”唤醒。
想要训练一个触发词检测系统,同样需要有大量的标记好的训练数据。使用RNN训练语音识别系统实现触发词词检测的功能时,可以进行如下图所示的工作:
在以训练的语音数据中输入RNN中,将触发词结束后的一小段序列的标签设置为“”,以此训练模型对触发词的检测。
参考资料
- 吴恩达-序列模型-网易云课堂
- Andrew Ng-Sequence Model-Coursera
- deeplearning.ai
- sequence to sequence model小记-知乎专栏
- seq2seq中的beam search算法过程-知乎专栏
- 机器翻译自动评估-BLEU算法详解
- 深度学习方法:自然语言处理中的Attention Model注意力模型-csdn
- 白话CTC算法讲解-csdn
- 课程代码与资料-GitHub
注:本文涉及的图片及资料均整理翻译自Andrew Ng的Deep Learning系列课程,版权归其所有。翻译整理水平有限,如有不妥的地方欢迎指出。
更新历史:
* 2018.03.11 完成初稿
原文链接