10.4 注意力机制 367
10.4 注意力机制
前面提到的 GNMT 系统就使用了注意力机制,那么注意力机制究竟是什么?回
顾一下第二章提到的一个观点:世界上不同事物之间的相关性是不一样的,有些事
物之间的联系会很强,而其他的联系可能很弱。自然语言也完美地契合了这个观点。
比如,再重新看一下前面提到的根据上下文补全缺失单词的例子,
中午 没 吃饭 ,又 刚 打 了 一 下午 篮球 ,我 现在 很 饿 ,我 想 。
之所以能想到在横线处填“吃饭”、“吃东西”很有可能是因为看到了“没/吃饭”、“很/饿”
等关键信息。也就是这些关键的片段对预测缺失的单词起着关键性作用。而预测“吃
饭”与前文中的“中午”、“又”之间的联系似乎不那么紧密。也就是说,在形成“吃
饭”的逻辑时,在潜意识里会更注意“没/吃饭”、“很/饿”等关键信息。也就是我们
的关注度并不是均匀地分布在整个句子上的。
这个现象可以用注意力机制进行解释。注意力机制的概念来源于生物学的一些
现象:当待接收的信息过多时,人类会选择性地关注部分信息而忽略其他信息。它
在人类的视觉、听觉、嗅觉等方面均有体现,当我们在感受事物时,大脑会自动过
滤或衰减部分信息,仅关注其中少数几个部分。例如,当看到图
10.16时,往往不是
“均匀地”看图像中的所有区域,可能最先注意到的是小狗的嘴,然后才会关注图片
中其他的部分。那注意力机制是如何解决神经机器翻译的问题呢?下面就一起来看
一看。
图
10.16
戴帽子的狗
10.4.1 翻译中的注意力机制
早期的神经机器翻译只使用循环神经网络最后一个单元的输出作为整个序列的
表示,这种方式有两个明显的缺陷:
• 首先,虽然编码器把一个源语言句子的表示传递给解码器,但是一个维度固定
的向量所能包含的信息是有限的,随着源语言序列的增长,将整个句子的信息
编码到一个固定维度的向量中可能会造成源语言句子信息的丢失。显然,在翻
368 Chapter 10. 基于循环神经网络的模型 肖桐 朱靖波
译较长的句子时,解码器可能无法获取完整的源语言信息,降低翻译性能;
• 此外,当生成某一个目标语言单词时,并不是均匀地使用源语言句子中的单词
信息。更普遍的情况是,系统会参考与这个目标语言单词相对应的源语言单词
进行翻译。这有些类似于词对齐的作用,即翻译是基于单词之间的某种对应关
系。但是,使用单一的源语言表示根本无法区分源语言句子的不同部分,更不
用说对源语言单词和目标语言单词之间的联系进行建模了。
更直观的,如图10.17,目标语言中的“very long”仅依赖于源语言中的“很长”。
这时如果将所有源语言编码成一个固定的实数向量,“很长”的信息就很可能被其他
词的信息淹没掉。
这
是 个
很长
的
句子
This is
a
very
long
sentence
Encoder
表示
Decoder
词语的关注度
图 10.17 源语言词和目标语言词的关注度
显然,以上问题的根本原因在于所使用的表示模型还比较“弱”。因此需要一个
更强大的表示模型,在生成目标语言单词时能够有选择地获取源语言句子中更有用
的部分。更准确的说,对于要生成的目标语言单词,相关性更高的源语言片段应该
在源语言句子的表示中体现出来,而不是将所有的源语言单词一视同仁。在神经机
器翻译中引入注意力机制正是为了达到这个目的
[22, 25]
。实际上,除了机器翻译,注意
力机制也被成功地应用于图像处理、语音识别、自然语言处理等其他任务。也正是
注意力机制的引入,使得包括机器翻译在内很多自然语言处理系统得到了飞跃发展。
神经机器翻译中的注意力机制并不复杂。对于每个目标语言单词 y
j
,系统生成
一个源语言表示向量 C
j
与之对应,C
j
会包含生成 y
j
所需的源语言的信息,或者说
C
j
是一种包含目标语言单词与源语言单词对应关系的源语言表示。不同于用一个静
态的表示 C,注意机制使用的是动态的表示 C
j
。C
j
也被称作对于目标语言位置 j 的
上下文向量(Context Vector)。图10.18对比了未引入注意力机制和引入了注意力机制
的编码器- 解码器结构。可以看出,在注意力模型中,对于每一个目标语言单词的生
成,都会额外引入一个单独的上下文向量参与运算。
10.4.2 上下文向量的计算
神经机器翻译中,注意力机制的核心是:针对不同目标语言单词生成不同的上
下文向量。这里,可以将注意力机制看做是一种对接收到的信息的加权处理。对于
更重要的信息赋予更高的权重即更高的关注度,对于贡献度较低的信息分配较低的
权重,弱化其对结果的影响。这样,C
j
可以包含更多对当前目标语言位置有贡献的
10.4 注意力机制 369
这
是 个
很长
的
句子
This is
a
very
long
sentence
Encoder
表示
Decoder
(a) 简单的编码器-解码器框架
这
是 个
很长
的
句子
This is
a
very
long
sentence
Encoder Decoder
表示 C
1
表示 C
2
表示 C
j
... ...
(b) 引入注意力机制的编码器-解码器框架
图 10.18 不使用 (a) 和使用 (b) 注意力机制的翻译模型对比
源语言片段的信息。
根据这种思想,上下文向量 C
j
被定义为对不同时间步编码器输出的状态序列
{h
1
,...,h
m
} 进行加权求和,如下式:
C
j
=
X
i
α
i,j
h
i
(10.16)
其中,α
i,j
是注意力权重(Attention Weight),它表示目标语言第 j 个位置与源语言
第 i 个位置之间的相关性大小。这里,将每个时间步编码器的输出 h
i
看作源语言位
置 i 的表示结果。进行翻译时,解码器可以根据当前的位置 j,通过控制不同 h
i
的权
重得到 C
j
,使得对目标语言位置 j 贡献大的 h
i
对 C
j
的影响增大。也就是说,C
j
实
际上就是 {h
1
,...,h
m
} 的一种组合,只不过不同的 h
i
会根据对目标端的贡献给予不同
的权重。图10.19展示了上下文向量 C
j
的计算过程。
h
1
h
2
...
h
m
s
j−1
s
j
α
1,j
α
2,j
α
m,j
C
j
输出层
编码器输出
(位置 1)
编码器输出
(位置 2)
编码器输出
(位置 m)
C
j
=
P
i
α
i,j
h
i
α
i,j
=
exp(β
i,j
)
P
i
′
exp(β
i
′
,j
)
β
i,j
= a(s
j−1
,h
i
)
图 10.19 上下文向量 C
j
的计算过程
如图10.19所示,注意力权重 α
i,j
的计算分为两步:
370 Chapter 10. 基于循环神经网络的模型 肖桐 朱靖波
• 使用目标语言上一时刻循环单元的输出 s
j−1
与源语言第 i 个位置的表示 h
i
之
间的相关性,其用来表示目标语言位置 j 对源语言位置 i 的关注程度,记为 β
i,j
,
由函数 a(·) 实现,其具体计算如下:
β
i,j
= a(s
j−1
,h
i
) (10.17)
a(·) 可以被看作是目标语言表示和源语言表示的一种“统一化”,即把源语言和
目标语言表示映射在同一个语义空间,进而语义相近的内容有更大的相似性。
该函数有多种计算方式,比如,向量乘、向量夹角和单层神经网络等,具体数
学表达如公式(10.18):
a(s,h) =
sh
T
向量乘
cos(s,h) 向量夹角
sWh
T
线性模型
Tanh([s,h]W)v
T
拼接[s,h] + 单层网络
(10.18)
其中 W 和 v 是可学习的参数。
• 进一步,利用 Softmax 函数,将相关性系数 β
i,j
进行指数归一化处理,得到注
意力权重 α
i,j
,具体计算如下:
α
i,j
=
exp(β
i,j
)
P
i
′
exp(β
i
′
,j
)
(10.19)
最终,{α
i,j
} 可以被看作是一个矩阵,它的长为目标语言句子长度,宽为源语
言句子长度,矩阵中的每一项对应一个 α
i,j
。图10.20给出了 {α
i,j
} 的一个矩阵
表示。图中蓝色方框的大小表示不同的注意力权重 α
i,j
的大小,方框越大,源
语言位置 i 和目标语言位置 j 的相关性越高。能够看到,对于互译的中英文句
子,{α
i,j
} 可以较好的反应两种语言之间不同位置的对应关系。
0.4
0.3 0.4
0.3
0.3
0.8
0.8
0.7
Have
you
learned
nothing
?
⟨eos⟩
你
什么
都
没
学
到
?
⟨eos⟩
图 10.20 一个汉英句对之间的注意力权重α
i,j
的矩阵表示
10.4 注意力机制 371
图10.21展示了一个上下文向量的计算过程实例。首先,计算目标语言第一个单
词“Have”与源语言中的所有单词的相关性,即注意力权重,对应图中第一列 α
i,1
,
则当前时刻所使用的上下文向量 C
1
=
P
8
i=1
α
i,1
h
i
;然后,计算第二个单词“you”的
注意力权重对应第二列 α
i,2
,其上下文向量 C
2
=
P
8
i=1
α
i,2
h
i
,以此类推,可以得到
任意目标语言位置 j 的上下文向量 C
j
。很容易看出,不同目标语言单词的上下文向
量对应的源语言词的权重 α
i,j
是不同的,不同的注意力权重为不同位置赋予了不同
的重要性。
0.4
0.3
0.4
0.3
0.3
0.8
0.8
0.7
Have
you
learned
nothing
?
⟨eos⟩
你
什么
都
没
学
到
?
⟨eos⟩
0.4 0.4 0 0.1 0
...
0.2 0.3 0.2 0 0
...
不同 C
j
所对应的源语言词的权重是不同的
C
2
= 0.4 × h(“你”) + 0.4 × h(“什么”)+
0 × h(“都”) + 0.1 × h(“没”) + ..
P
P
C
1
=
P
8
i=1
α
i1
h
i
C
2
=
P
8
i=1
α
i2
h
i
图 10.21 上下文向量计算过程实例
在10.3.1节中,公式(10.4)描述了目标语言单词生成概率 P (y
j
|y
<j
,x)。在引入注
意力机制后,不同时刻的上下文向量 C
j
替换了传统模型中固定的句子表示 C。描述
如下:
P (y
j
|y
<j
,x) = P (y
j
|s
j−1
,y
j−1
,C
j
) (10.20)
这样,可以在生成每个 y
j
时动态的使用不同的源语言表示 C
j
,并更准确地捕捉
源语言和目标语言不同位置之间的相关性。表10.7展示了引入注意力机制前后译文
单词生成公式的对比。
表 10.7 引入注意力机制前后译文单词生成公式
引入注意力之前 引入注意力之后
have = argmax
y
1
P (y
1
|C,y
0
) have = argmax
y
1
P (y
1
|C
1
,y
0
)
you = argmax
y
2
P (y
2
|s
1
,y
1
) you = argmax
y
2
P (y
2
|s
1
,C
2
,y
1
)
10.4.3 注意力机制的解读
从前面的描述可以看出,注意力机制在机器翻译中就是要回答一个问题:给定
一个目标语言位置 j 和一系列源语言的不同位置上的表示 {h
i
},如何得到一个新的
372 Chapter 10. 基于循环神经网络的模型 肖桐 朱靖波
表示
ˆ
h,使得它与目标语言位置 j 对应得最好?
那么,如何理解这个过程?注意力机制的本质又是什么呢?换一个角度来看,实
际上,目标语言位置 j 可以被看作是一个查询,我们希望从源语言端找到与之最匹
配的源语言位置,并返回相应的表示结果。为了描述这个问题,可以建立一个查询系
统。假设有一个库,里面包含若干个 key-value 单元,其中 key 代表这个单元的索引
关键字,value 代表这个单元的值。比如,对于学生信息系统,key 可以是学号,value
可以是学生的身高。当输入一个查询 query,我们希望这个系统返回与之最匹配的结
果。也就是,希望找到匹配的 key,并输出其对应的 value。比如,当查询某个学生的
身高信息时,可以输入学生的学号,之后在库中查询与这个学号相匹配的记录,并
把这个记录中的 value(即身高)作为结果返回。
图10.22展示了一个这样的查询系统。里面包含四个 key-value 单元,当输入查询
query,就把 query 与这四个 key 逐个进行匹配,如果完全匹配就返回相应的 value。
在图中的例子中,query 和 key
3
是完全匹配的(因为都是横纹),因此系统返回第三
个单元的值,即 value
3
。当然,如果库中没有与 query 匹配的 key,则返回一个空结
果。
value
1
value
2
value
3
value
4
key
1
key
2
key
3
key
4
query
匹配
返回结果
图 10.22 传统查询模型
也可以用这个系统描述翻译中的注意力问题,其中,query 即目标语言位置 j 的
某种表示,key 和 value 即源语言每个位置 i 上的 h
i
(这里 key 和 value 是相同的)。
但是,这样的系统在机器翻译问题上并不好用,因为目标语言的表示和源语言的表
示都在多维实数空间上,所以无法要求两个实数向量像字符串一样进行严格匹配,或
者说这种严格匹配的模型可能会导致 query 几乎不会命中任何的 key。既然无法严
格精确匹配,注意力机制就采用了一个“模糊”匹配的方法。这里定义每个 key
i
和
query 都有一个 0~1 之间的匹配度,这个匹配度描述了 key
i
和 query 之间的相关程
度,记为 α
i
。而查询的结果(记为 value)也不再是某一个单元的 value,而是所有
单元 value 用 α
i
的加权和,具体计算如下:
value =
X
i
α
i
·value
i
(10.21)
也就是说所有的 value
i
都会对查询结果有贡献,只是贡献度不同罢了。可以通过设
计 α
i
来捕捉 key 和 query 之间的相关性,以达到相关度越大的 key 所对应的 value
对结果的贡献越大。
重新回到神经机器翻译问题上来。这种基于模糊匹配的查询模型可以很好的满
10.4 注意力机制 373
足对注意力建模的要求。实际上,公式(10.21)中的 α
i
就是前面提到的注意力权重,它
可以由注意力函数 a(·) 计算得到。这样,value 就是得到的上下文向量,它包含了所
有 {h
i
} 的信息,只是不同 h
i
的贡献度不同罢了。图10.23展示了将基于模糊匹配的
查询模型应用于注意力机制的实例。
h(你) h(什么) h(也) h(没)
h(你)
h(什么)
h(也)
h(没)
s(you)
query
α
1
= 0.4
α
2
= 0.4
α
3
= 0.1
α
4
= 0.1
图 10.23 注意力机制所对应的查询模型
最后,从统计学的角度,如果把 α
i
作为每个 value
i
出现的概率的某种估计,即:
P (value
i
) = α
i
,于是可以把公式(10.21)重写为:
value =
X
i
P (value
i
) ·value
i
(10.22)
显然,value
就是
value
i
在分布
P
(value
i
)
下的期望,即:
E
∼P (value
i
)
(value
i
) =
X
i
P (value
i
) ·value
i
(10.23)
从这个观点看,注意力机制实际上是得到了变量 value 的期望。当然,严格意义
上说,α
i
并不是从概率角度定义的,在实际应用中也并不必须追求严格的统计学意
义。
10.4.4 实例 - GNMT
循环神经网络在机器翻译中有很多成功的应用,比如:RNNSearch
[22]
、Nematus
[471]
等系统就被很多研究人员作为实验系统。在众多基于循环神经网络的系统中,GNMT
系统是非常成功的一个
[456]
。GNMT 是谷歌 2016 年发布的神经机器翻译系统。
GNMT 使用了编码器-解码器结构,构建了一个 8 层的深度网络,每层网络均由
LSTM 组成,且在编码器-解码器之间使用了多层注意力连接。其结构如图10.24,编
码器只有最下面 2 层为双向 LSTM。GNMT 在束搜索中也加入了长度惩罚和覆盖度
因子来确保输出高质量的翻译结果。
实际上,GNMT 的主要贡献在于集成了多种优秀的技术,而且在大规模数据上
证明了神经机器翻译的有效性。在引入注意力机制之前,神经机器翻译在较大规模
的任务上的性能弱于统计机器翻译。加入注意力机制和深层网络后,神经机器翻译
性能有了很大的提升。在英德和英法的任务中,GNMT 的 BLEU 值不仅超过了当时
优秀的神经机器翻译模型 RNNSearch 和 LSTM(6 层),还超过了当时处于领导地位
374 Chapter 10. 基于循环神经网络的模型 肖桐 朱靖波
···
···
···
···
···
··· ··· ···
···
你
什么
⟨eos⟩
注意力机制
···
···
···
···
··· ··· ···
···
···
⟨sos⟩
Have
?
Have you ⟨eos⟩
8 层
8 层
编码器
解码器
图 10.24 GNMT 结构
的基于短语的统计机器翻译模型(PBMT)(表10.8)。相比基于短语的统计机器翻译
模型,在人工评价中,GNMT 能将翻译错误平均减少 60%。这一结果也充分表明了
神经机器翻译带来的巨大性能提升。
表 10.8 GNMT 与其他翻译模型对比
[456]
翻译模型
BLEU[%]
英德 英法
EN-DE EN-FR
PBMT 20.7 37.0
RNNSearch 16.5 -
LSTM(6 layers) - 31.5
Deep-Att 20.6 37.7
GNMT 24.6 39.0