赞
踩
Encoder-Decoder框架是一种深度学习领域的研究模式,应用场景异常广泛。图1是文本处理领域里常用的Encoder-Decoder框架抽象的一种表示。
图1 文本处理领域的Encoder-Decoder框架
文本处理领域的Encoder-Decoder框架可以用一种直观的方式来理解:可以把它看作适合处理由一个句子(或篇章)生成另外一个句子(或篇章)的通用处理模型。对于句子对 ( S o u r c e , T a r g e t ) (Source,Target) (Source,Target),我们的目标是给定输入句子 S o u r c e Source Source,期望通过Encoder-Decoder框架来生成目标句子 T a r g e t Target Target。 S o u r c e Source Source 和 T a r g e t Target Target 可以是同一种语言,也可以是两种不同的语言。而 S o u r c e Source Source 和 T a r g e t Target Target 分别由各自的单词序列构成:
S
o
u
r
c
e
=
⟨
x
1
,
x
2
…
x
m
⟩
Source =\langle\mathbf{x_1},\mathbf{x_2}\ldots\mathbf{x_m}\rangle
Source=⟨x1,x2…xm⟩
T
a
r
g
e
t
=
⟨
y
1
,
y
2
…
y
n
⟩
Target=\langle\mathbf{y_1},\mathbf{y_2}\ldots\mathbf{y_n}\rangle
Target=⟨y1,y2…yn⟩
Encoder顾名思义就是对输入句子 S o u r c e Source Source 进行编码,将输入句子通过非线性变换转化为中间语义表示 C C C:
C = F ( x 1 , x 2 … x m ) \mathbf{C}={\mathcal F}(\mathbf{x_{1}},\mathbf{x_{2}}\ldots\mathbf{x_{m}}) C=F(x1,x2…xm)
对于解码器Decoder,其任务是根据句子 S o u r c e Source Source 的中间语义表示 C C C 和之前已经生成的历史信息 y 1 , y 2 … y i − 1 \mathbf{y_1},\mathbf{y_2}\ldots\mathbf{y_{i-1}} y1,y2…yi−1,来生成 i i i 时刻要生成的单词 y i \mathbf{y_i} yi。
每个 y i \mathbf{y_i} yi 都依次这么产生,那么看起来就是整个系统根据输入句子 S o u r c e Source Source,生成了目标句子 T a r g e t Target Target。如果 S o u r c e Source Source 是中文句子, T a r g e t Target Target 是英文句子,那么这就是解决机器翻译问题的Encoder-Decoder框架;如果 S o u r c e Source Source 是一篇文章, T a r g e t Target Target 是概括性的几句描述语句,那么这是文本摘要的Encoder-Decoder框架;如果 S o u r c e Source Source 是一句问句, T a r g e t Target Target 是一句回答,那么这是问答系统或者对话机器人的Encoder-Decoder框架。由此可见,在文本处理领域,Encoder-Decoder的应用领域相当广泛。
Encoder-Decoder框架不仅仅在文本领域广泛使用,在语音识别、图像处理等领域也经常使用。比如对于语音识别来说,图1所示的框架完全适用,区别无非是Encoder部分的输入是语音流,Decoder部分的输出是对应的文本信息;而对于“图像描述”任务来说,Encoder部分的输入是一副图片,Decoder的输出是能够描述图片语义内容的一句描述语。一般而言,文本处理和语音识别的Encoder部分通常采用RNN模型,图像处理的Encoder一般采用CNN模型。
本节先以机器翻译作为例子讲解最常见的Soft Attention模型的基本原理,之后抛离Encoder-Decoder框架抽象出了注意力机制的本质思想,然后简单介绍最近广为使用的Self Attention的基本思路。
图1中展示的Encoder-Decoder框架是没有体现出“注意力模型”的,所以可以把它看作是注意力不集中的分心模型。为什么说它注意力不集中呢?请观察下目标句子 T a r g e t Target Target 中每个单词的生成过程如下:
y
1
=
f
(
C
)
y
2
=
f
(
C
,
y
1
)
y
3
=
f
(
C
,
y
1
,
y
2
)
其中 f f f 是Decoder的非线性变换函数。从这里可以看出,在生成目标句子的单词时,不论生成哪个单词,它们使用的输入句子 S o u r c e Source Source 的语义编码 C C C 都是一样的,没有任何区别。
而语义编码 C C C 是由句子 S o u r c e Source Source 的每个单词经过Encoder编码产生的,这意味着不论是生成哪个单词, y 1 y_1 y1, y 2 y_2 y2 还是 y 3 y_3 y3,其实句子 S o u r c e Source Source 中任意单词对生成某个目标单词 y i y_i yi 来说,影响力都是相同的,这就是为何说这个模型没有体现出注意力的缘由。这类似于人类看到眼前的画面,但是眼中却没有注意焦点一样。
如果拿机器翻译来解释这个分心模型的Encoder-Decoder框架更好理解,比如输入的是英文句子:Tom chase Jerry,Encoder-Decoder框架逐步生成中文单词:“汤姆”,“追逐”,“杰瑞”。
在翻译“杰瑞”这个中文单词的时候,分心模型里面的每个英文单词对于翻译目标单词“杰瑞”贡献是相同的,很明显这是不太合理的,显然“Jerry”对于翻译成“杰瑞”更重要,但是分心模型是无法体现这一点的,这就是为何说它没有引入注意力的原因。
没有引入注意力的模型在输入句子比较短的时候问题不大,但是如果输入句子比较长,此时所有语义完全通过一个中间语义向量来表示,单词自身的信息已经消失,可想而知会丢失很多细节信息,这也是为何要引入注意力模型的重要原因。
上面的例子中,如果引入Attention模型的话,应该在翻译“杰瑞”的时候,体现出英文单词对于翻译当前中文单词不同的影响程度,比如给出类似下面一个概率分布值:
( T o m , 0.3 ) , ( C h a s e , 0.2 ) , ( J e r r y , 0.5 ) (Tom,0.3), (Chase,0.2), (Jerry,0.5) (Tom,0.3),(Chase,0.2),(Jerry,0.5)
每个英文单词的概率代表了翻译当前单词“Jerry”时,注意力分配模型分配给不同英文单词的注意力大小。这对于正确翻译目标语单词肯定是有帮助的,因为引入了新的信息。
同理,目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。这意味着在生成每个单词 y i y_i yi 的时候,原先都是相同的中间语义表示 C C C 会被替换成根据当前生成单词而不断变化的 C i C_i Ci。理解Attention模型的关键就是这里,即由固定的中间语义表示 C C C 换成了根据当前输出单词来调整加入注意力模型的变化的 C i C_i Ci。增加了注意力模型的Encoder-Decoder框架理解起来如图2所示。
图2 引入注意力模型的Encoder-Decoder框架
也就是生成目标句子单词的过程成了下面的形式:
y
1
=
f
1
(
C
1
)
y
2
=
f
1
(
C
2
,
y
1
)
y
3
=
f
1
(
C
3
,
y
1
,
y
2
)
而每个 C i C_i Ci 可能对应着不同的源语句子单词的注意力分配概率分布,比如对于上面的英汉翻译来说,其对应的信息可能如下:
C
汤姆
=
g
(
0.6
∗
f
2
(
T
o
m
)
,
0.2
∗
f
2
(
C
h
a
s
e
)
,
0.2
∗
f
2
(
J
e
r
r
y
)
\mathbf{C} _{\text{汤姆}}= \mathbf{g} ( 0.6* \mathbf{f} 2( \mathbf{Tom}) , 0.2* \mathbf{f} 2( \mathbf{Chase}) , 0.2* \mathbf{f} 2( \mathbf{Jerry})
C汤姆=g(0.6∗f2(Tom),0.2∗f2(Chase),0.2∗f2(Jerry)
C
追逐
=
g
(
0.2
∗
f
2
(
T
o
m
)
,
0.7
∗
f
2
(
C
h
a
s
e
)
,
0.1
∗
f
2
(
J
e
r
r
y
)
\mathbf{C} _{\text{追逐}}= \mathbf{g} ( 0.2* \mathbf{f} 2( \mathbf{Tom}) , 0.7* \mathbf{f} 2( \mathbf{Chase}) , 0.1 * \mathbf{f} 2( \mathbf{Jerry})
C追逐=g(0.2∗f2(Tom),0.7∗f2(Chase),0.1∗f2(Jerry)
C
杰瑞
=
g
(
0.3
∗
f
2
(
T
o
m
)
,
0.2
∗
f
2
(
C
h
a
s
e
)
,
0.5
∗
f
2
(
J
e
r
r
y
)
\mathbf{C} _{\text{杰瑞}}= \mathbf{g} ( 0.3* \mathbf{f} 2(\mathbf{Tom}) , 0.2* \mathbf{f} 2( \mathbf{Chase}) , 0.5* \mathbf{f} 2( \mathbf{Jerry})
C杰瑞=g(0.3∗f2(Tom),0.2∗f2(Chase),0.5∗f2(Jerry)
其中, f 2 f2 f2 函数代表Encoder对输入英文单词的某种变换函数,比如如果Encoder是用的RNN模型的话,这个 f 2 f2 f2 函数的结果往往是某个时刻输入 x i x_i xi 后隐层节点的状态值; g g g 代表Encoder根据单词的中间表示合成整个句子中间语义表示的变换函数,一般的做法中, g g g 函数就是对构成元素的加权求和:
C i = ∑ j = 1 L x a i j h j C_i=\sum_{j=1}^{L_x}a_{ij}h_j Ci=∑j=1Lxaijhj
其中, L x L_x Lx 代表输入句子 S o u r c e Source Source 的长度, a i j a_{ij} aij 代表在 T a r g e t Target Target 输出第 i i i 个单词时, S o u r c e Source Source 输入句子中第 j j j 个单词的注意力分配系数,而 h j h_j hj 则是 S o u r c e Source Source 输入句子中第 j j j 个单词的语义编码。假设下标 i i i 就是上面例子所说的“汤姆”,那么 L x L_x Lx 就是3, h 1 = f ( “ T o m ” ) , h 2 = f ( “ C h a s e ” ) , h 3 = f ( “ J e r r y ” ) h1=f(“Tom”),h2=f(“Chase”),h3=f(“Jerry”) h1=f(“Tom”),h2=f(“Chase”),h3=f(“Jerry”) 分别是输入句子每个单词的语义编码,对应的注意力模型权值则分别是 0.6 , 0.2 , 0.2 0.6,0.2,0.2 0.6,0.2,0.2,所以 g g g 函数本质上就是个加权求和函数。如果形象表示的话,翻译中文单词“汤姆”的时候,数学公式对应的中间语义表示 C i C_i Ci 的形成过程类似图3。
图3 Attention的形成过程
这里还有一个问题:生成目标句子某个单词,比如“汤姆”的时候,如何知道Attention模型所需要的输入句子单词的注意力分配概率分布值呢?就是说“汤姆”对应的输入句子 S o u r c e Source Source 中各个单词的概率分布: ( T o m , 0.6 ) , ( C h a s e , 0.2 ) , ( J e r r y , 0.2 ) (Tom,0.6), (Chase,0.2), (Jerry,0.2) (Tom,0.6),(Chase,0.2),(Jerry,0.2) 是如何得到的呢?
为了便于说明,我们假设对图1的非Attention模型的Encoder-Decoder框架进行细化,Encoder采用RNN模型,Decoder也采用RNN模型,这是比较常见的一种模型配置,则图2的框架转换为图4。
图4 RNN作为具体模型的Encoder-Decoder框架
那么用图5可以较为便捷地说明注意力分配概率分布值的通用计算过程。
图5 注意力分配概率计算
对于采用RNN的Decoder来说,在时刻 i i i,如果要生成 y i y_i yi 单词,我们是可以知道 T a r g e t Target Target 在生成 Y i Y_i Yi 之前的时刻 i − 1 i-1 i−1时,隐层节点 i − 1 i-1 i−1 时刻的输出值 H i − 1 H_{i-1} Hi−1的,而我们的目的是要计算生成 Y i Y_i Yi 时,输入句子中的单词“Tom”、“Chase”、“Jerry”对 Y i Y_i Yi 来说的注意力分配概率分布,那么可以用 T a r g e t Target Target 输出句子 i − 1 i-1 i−1 时刻的隐层节点状态 H i − 1 H_{i-1} Hi−1去一一和输入句子 S o u r c e Source Source 中每个单词对应的RNN隐层节点状态 h j h_j hj 进行对比,即通过函数 F ( h j , H i − 1 ) F(h_j,H_{i-1}) F(hj,Hi−1) 来获得目标单词 y i y_i yi 和每个输入单词对应的对齐可能性,这个 F F F 函数在不同论文里可能会采取不同的方法,然后函数 F F F 的输出经过 S o f t m a x Softmax Softmax 进行归一化,就得到了符合概率分布取值区间的注意力分配概率分布数值。
绝大多数Attention模型都是采取上述的计算框架来计算注意力分配概率分布信息,区别只是在 F F F 的定义上可能有所不同。
上述内容就是经典的Soft Attention模型的基本思想,那么怎么理解Attention模型的物理含义呢?一般在自然语言处理应用里会把Attention模型看作是输出 T a r g e t Target Target 句子中某个单词和输入 S o u r c e Source Source 句子每个单词的对齐模型,这是非常有道理的。
目标句子生成的每个单词对应输入句子单词的概率分布,可以理解为输入句子单词和这个目标生成单词的对齐概率,这在机器翻译语境下是非常直观的:传统的统计机器翻译一般在做的过程中会专门有一个短语对齐的步骤,而注意力模型其实起的是相同的作用。
如果把Attention机制从上文讲述例子中的Encoder-Decoder框架中剥离,并进一步做抽象,可以更容易看懂Attention机制的本质思想。
图6 Attention机制的本质思想
我们可以这样来看待Attention机制(参考图6):将 S o u r c e Source Source 中的构成元素想象成是由一系列的 < K e y , V a l u e > <Key,Value> <Key,Value>数据对构成,此时给定 T a r g e t Target Target 中的某个元素 Q u e r y Query Query,通过计算 Q u e r y Query Query 和各个 K e y Key Key 的相似性或者相关性,得到每个 K e y Key Key 对应 V a l u e Value Value 的权重系数,然后对 V a l u e Value Value 进行加权求和,即得到了最终的Attention数值。所以本质上Attention机制是对 S o u r c e Source Source 中元素的 V a l u e Value Value 值进行加权求和,而 Q u e r y Query Query 和 K e y Key Key 用来计算对应 V a l u e Value Value 的权重系数。其本质思想改写为如下公式:
Attention(Query,Source) = ∑ i = 1 l x Similarity ( Q u e r y , Key i ) ∗ V a l u e i \text{Attention(Query,Source)}=\sum_{i=1}^{l_x}\text{Similarity}(Query,\text{Key}_i)*Value_i Attention(Query,Source)=∑i=1lxSimilarity(Query,Keyi)∗Valuei
其中, L x = ∣ ∣ S o u r c e ∣ ∣ L_x=||Source|| Lx=∣∣Source∣∣ 代表 S o u r c e Source Source 的长度。上文所举的机器翻译的例子里,因为在计算Attention的过程中, S o u r c e Source Source 中的 K e y Key Key 和 V a l u e Value Value 合二为一,指向的是同一个东西,也即输入句子中每个单词对应的语义编码,所以可能不容易看出这种能够体现本质思想的结构。
当然,从概念上理解,把Attention仍然理解为从大量信息中有选择地筛选出少量重要信息并聚焦到这些重要信息上,忽略大多不重要的信息,这种思路仍然成立。聚焦的过程体现在权重系数的计算上,权重越大越聚焦于其对应的 V a l u e Value Value 值上,即权重代表了信息的重要性,而 V a l u e Value Value 是其对应的信息。
从图6可以引出另外一种理解,即将Attention机制看作一种软寻址(Soft Addressing): S o u r c e Source Source 可以看作存储器内存储的内容,元素由地址 K e y Key Key 和值 V a l u e Value Value 组成,当前有个 K e y = Q u e r y Key=Query Key=Query 的查询,目的是取出存储器中对应的 V a l u e Value Value 值,即Attention数值。通过 Q u e r y Query Query 和存储器内元素 K e y Key Key 的地址进行相似性比较来寻址,之所以说是软寻址,是因为不像一般寻址只从存储内容里面找出一条内容,而是可能从每个 K e y Key Key 地址都会取出内容,取出内容的重要性根据 Q u e r y Query Query 和 K e y Key Key 的相似性来决定,之后对 V a l u e Value Value 进行加权求和,这样就可以取出最终的 V a l u e Value Value 值,也即Attention值。所以不少研究人员将Attention机制看作软寻址的一种特例,这也是非常有道理的。
至于Attention机制的具体计算过程,如果对目前大多数方法进行抽象的话,可以将其归纳为两个过程:第一个过程是根据 Q u e r y Query Query 和 K e y Key Key 计算权重系数,第二个过程根据权重系数对 V a l u e Value Value 进行加权求和。而第一个过程又可以细分为两个阶段:第一个阶段根据 Q u e r y Query Query 和 K e y Key Key 计算两者的相似性或者相关性;第二个阶段对第一阶段的原始分值进行归一化处理。这样,可以将Attention的计算过程抽象为如图7展示的三个阶段。
图7 三阶段计算Attention过程
在第一个阶段,可以引入不同的函数和计算机制,根据 Q u e r y Query Query 和某个 K e y i Key_i Keyi,计算两者的相似性或者相关性,最常见的方法包括:求两者的向量点积、求两者的向量Cosine相似性或者通过再引入额外的神经网络来求值,即如下方式:
点积:
Similarity(Query,Key
i
)
=
Query
⋅
Key
i
Cosine 相似性:
Similarity
(
Query,Key
i
)
=
Query Key
i
∣
∣
Query
∣
∣
⋅
∣
∣
Key
i
∣
∣
MLP 网络:
Similarity(Query,Key
i
)
=
MLP(Query,Key
i
)
第一阶段产生的分值根据具体产生的方法不同,其数值取值范围也不一样,第二阶段引入类似 S o f t M a x SoftMax SoftMax 的计算方式对第一阶段的得分进行数值转换,一方面可以进行归一化,将原始计算分值整理成所有元素权重之和为1的概率分布;另一方面也可以通过 S o f t M a x SoftMax SoftMax 的内在机制更加突出重要元素的权重。即一般采用如下公式计算:
a i = S o f t m a x ( S i m i ) = e S i m i Σ j = 1 L x e S i m j a_{i}=Softmax(Sim_{i})=\frac{e^{Sim_{i}}}{\Sigma_{j=1}^{L_{x}}e^{Sim_{j}}} ai=Softmax(Simi)=Σj=1LxeSimjeSimi
第二阶段的计算结果 a i a_i ai 即为 v a l u e i value_i valuei 对应的权重系数,然后进行加权求和即可得到Attention数值:
Attention(Query,Source ) = ∑ i = 1 L x a i ⋅ V a l u e i \text{Attention(Query,Source})=\sum_{i=1}^{L_x}a_i\cdot Value_i Attention(Query,Source)=∑i=1Lxai⋅Valuei
通过如上三个阶段的计算,即可求出针对 Q u e r y Query Query 的Attention数值,目前绝大多数具体的注意力机制计算方法都符合上述的三阶段抽象计算过程。
通过上述对Attention本质思想的梳理,我们可以更容易理解本节介绍的Self Attention模型。Self Attention也经常被称为intra Attention(内部Attention),最近一年也获得了比较广泛的使用,比如Google最新的机器翻译模型内部大量采用了Self Attention模型。
在一般任务的Encoder-Decoder框架中,输入 S o u r c e Source Source 和输出 T a r g e t Target Target 内容是不一样的,比如对于英-中机器翻译来说, S o u r c e Source Source 是英文句子, T a r g e t Target Target 是对应的翻译出的中文句子,Attention机制发生在 T a r g e t Target Target 中的元素 Q u e r y Query Query 和 S o u r c e Source Source 中的所有元素之间。而Self Attention顾名思义,指的不是 T a r g e t Target Target 和 S o u r c e Source Source 之间的Attention机制,而是 S o u r c e Source Source 内部元素之间或者 T a r g e t Target Target 内部元素之间发生的Attention机制,也可以理解为 T a r g e t = S o u r c e Target=Source Target=Source 这种特殊情况下的注意力机制。其具体计算过程是一样的,只是计算对象发生了变化而已,所以此处不再赘述其计算过程细节。
如果是常规的 T a r g e t Target Target 不等于 S o u r c e Source Source 情形下的注意力计算,其物理含义正如上文所讲,比如对于机器翻译来说,本质上是目标语单词和源语单词之间的一种单词对齐机制。那么如果是Self Attention机制,一个很自然的问题是:通过Self Attention到底学到了哪些规律或者抽取出了哪些特征呢?或者说引入Self Attention有什么增益或者好处呢?我们仍然以机器翻译中的Self Attention来说明,图8和图9是可视化地表示Self Attention在同一个英语句子内单词间产生的联系。
图8 可视化Self Attention实例
图9 可视化Self Attention实例
从两张图(图8、图9)可以看出,Self Attention可以捕获同一个句子中单词之间的一些句法特征(比如图8展示的有一定距离的短语结构)或者语义特征(比如图9展示的its的指代对象Law)。
很明显,引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN或者LSTM,需要依次序进行序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。
但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此外,Self
Attention对于增加计算的并行性也有直接帮助作用。这是为何Self Attention逐渐被广泛使用的主要原因。
Attention机制在深度学习的各种应用领域都有广泛的使用场景。上文在介绍过程中我们主要以自然语言处理中的机器翻译任务作为例子,下面分别再从图像处理领域和语音识别选择典型应用实例来对其应用做简单说明。
图10 图片-描述任务的Encoder-Decoder框架
图片描述(Image-Caption)是一种典型的图文结合的深度学习应用,输入一张图片,人工智能系统输出一句描述句子,语义等价地描述图片所示内容。很明显这种应用场景也可以使用Encoder-Decoder框架来解决任务目标,此时Encoder输入部分是一张图片,一般会用CNN来对图片进行特征抽取,Decoder部分使用RNN或者LSTM来输出自然语言句子(参考图10)。
此时如果加入Attention机制能够明显改善系统输出效果,Attention模型在这里起到了类似人类视觉选择性注意的机制,在输出某个实体单词的时候会将注意力焦点聚焦在图片中相应的区域上。
图11给出了另外四个例子形象地展示了这种过程,每个例子上方左侧是输入的原图,下方句子是人工智能系统自动产生的描述语句,上方右侧图展示了当AI系统产生语句中划横线单词的时候,对应图片中聚焦的位置区域。比如当输出单词dog的时候,AI系统会将注意力更多地分配给图片中小狗对应的位置。
图11 图像描述任务中Attention机制的聚焦作用
语音识别的任务目标是将语音流信号转换成文字,所以也是Encoder-Decoder的典型应用场景。Encoder部分的 S o u r c e Source Source 输入是语音流信号,Decoder部分输出语音对应的字符串流。
图12 语音识别中音频序列和输出字符之间的Attention
图12可视化地展示了在Encoder-Decoder框架中加入Attention机制后,当用户用语音说句子
how much would a woodchuck chuck时,输入部分的声音特征信号和输出字符之间的注意力分配概率分布情况,颜色越深代表分配到的注意力概率越高。从图中可以看出,在这个场景下,Attention机制起到了将输出字符和输入语音信号进行对齐的功能。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。