深度学习笔记之Seq2seq——注意力机制的执行过程
引言
上一节介绍了 Seq2seq \text{Seq2seq} Seq2seq中注意力机制 ( Attention ) (\text{Attention}) (Attention)的动机,并介绍了权重系数、 Score \text{Score} Score函数。本节将完整介绍注意力机制在 Seq2seq \text{Seq2seq} Seq2seq中的执行过程。
回顾:
经典 Seq2seq \text{Seq2seq} Seq2seq模型中 Context \text{Context} Context向量的缺陷
在经典的
Seq2seq
\text{Seq2seq}
Seq2seq模型结构中,关于解码器在各时刻的输出
y
(
i
)
(
i
=
1
,
2
,
⋯
,
T
′
)
y^{(i)}(i=1,2,\cdots,\mathcal T')
y(i)(i=1,2,⋯,T′)均使用共同的
Context
\text{Context}
Context向量
C
\mathcal C
C生成出来的结果:
其中
⟨
Start
⟩
\left\langle\text{Start}\right\rangle
⟨Start⟩无语义信息,后续省略。
{
y
(
1
)
=
f
(
C
,
⟨
Start
⟩
)
y
(
2
)
=
f
(
y
(
1
)
,
C
)
y
(
3
)
=
f
(
y
(
1
)
,
y
(
2
)
,
C
)
⋮
\begin{cases} y^{(1)} &= f(\mathcal C,\left\langle\text{Start}\right\rangle) \\ y^{(2)} & = f(y^{(1)},\mathcal C) \\ y^{(3)} & = f(y^{(1)},y^{(2)},\mathcal C) \\ & \vdots \end{cases}
⎩
⎨
⎧y(1)y(2)y(3)=f(C,⟨Start⟩)=f(y(1),C)=f(y(1),y(2),C)⋮
但从
Encoder
\text{Encoder}
Encoder中生成的
Context
\text{Context}
Context向量
C
\mathcal C
C虽然保留了输入序列数据
X
\mathcal X
X的完整序列信息,但因梯度消失问题,导致:
C
\mathcal C
C对序列数据
X
\mathcal X
X的初始时刻信息存在遗忘现象。
从而基于
C
\mathcal C
C在解码器中生成出的序列信息
Y
=
(
y
(
1
)
,
y
(
2
)
,
⋯
,
y
(
T
′
)
)
T
\mathcal Y = (y^{(1)},y^{(2)},\cdots,y^{(\mathcal T')})^T
Y=(y(1),y(2),⋯,y(T′))T,其初始时刻的序列信息并不准确。也就是说:生成出的初始时刻信息如
y
(
1
)
,
y
(
2
)
y^{(1)},y^{(2)}
y(1),y(2)等与输入序列数据
X
\mathcal X
X中的初始时刻信息如
x
(
1
)
,
x
(
2
)
x^{(1)},x^{(2)}
x(1),x(2)等关联性不强。这违背了翻译过程中的对齐逻辑
⇒
\Rightarrow
⇒ 对齐问题。
这里的
x
(
i
)
,
y
(
i
)
(
i
=
1
,
2
,
⋯
)
x^{(i)},y^{(i)}(i=1,2,\cdots)
x(i),y(i)(i=1,2,⋯)仅仅是举一个例子,它们仅描述‘初始时刻位置的信息’,但并不是说它们‘整整齐齐地对齐在一起’。因为
X
,
Y
\mathcal X,\mathcal Y
X,Y的序列长度可能存在差异。
注意力机制的动机
针对对齐问题,存在一个朴素想法:在解码器 i i i时刻生成 y ( i ) y^{(i)} y(i)时,我们更希望在编码器中找到与 y ( i ) y^{(i)} y(i)关联程度更高的若干个序列信息作为输入,而不是仅仅描述完整序列信息的 Context \text{Context} Context。
基于该想法,具体动机是:将编码器中所有时刻的序列信息 H = ( h ( 1 ) , h ( 2 ) , ⋯ , h ( T ) ) \mathcal H = (h^{(1)},h^{(2)},\cdots,h^{(\mathcal T)}) H=(h(1),h(2),⋯,h(T))都输出出来,并对每一个序列信息 h ( j ) ( j = 1 , 2 , ⋯ , T ) h^{(j)}(j=1,2,\cdots,\mathcal T) h(j)(j=1,2,⋯,T)与 y ( i ) y^{(i)} y(i)的相关性进行打分,分值越高,相关性越强;最终将 H \mathcal H H与相关性结果 S \mathcal S S做线性运算:
其中
h D ( i ) h_{\mathcal D}^{(i)} hD(i)表示
i i i时刻解码器的序列信息:而
C i \mathcal C_i Ci表示替代原始
Context \text{Context} Context向量作为解码器
i i i时刻的序列信息。
-
s
i
j
s_{ij}
sij
表示’解码器‘第
i i i时刻的序列信息
h D ( i ) h_{\mathcal D}^{(i)} hD(i)与’编码器‘中第
j j j时刻序列信息
h ( j ) h^{(j)} h(j)之间的评分结果。
{ s i j = Score ( h ( j ) , h D ( i ) ) S i = ( s i 1 , s i 2 , ⋯ , s i T ) T C i = [ S i ] T H = ∑ j = 1 T s i j ⋅ h ( j ) \begin{cases} \begin{aligned} s_{ij} & = \text{Score}(h^{(j)},h_{\mathcal D}^{(i)}) \\ \mathcal S_i & = (s_{i1},s_{i2},\cdots,s_{i\mathcal T})^T \\ \mathcal C_i & = [\mathcal S_i]^T \mathcal H \\ & = \sum_{j=1}^{\mathcal T} s_{ij} \cdot h^{(j)} \end{aligned} \end{cases} ⎩ ⎨ ⎧sijSiCi=Score(h(j),hD(i))=(si1,si2,⋯,siT)T=[Si]TH=j=1∑Tsij⋅h(j)
Seq2seq \text{Seq2seq} Seq2seq中的 Attention \text{Attention} Attention结构
在编码器部分,使用双向
GRU
\text{GRU}
GRU结构
(
Bidirectional GRU,BiGRU
)
(\text{Bidirectional GRU,BiGRU})
(Bidirectional GRU,BiGRU):
正常的
GRU
\text{GRU}
GRU结构仅捕捉到了正向个时刻的序列信息;而双向结构是在正向的基础上,增加了反向的序列信息:
其中
H
S
i
n
g
l
e
\mathcal H_{Single}
HSingle表示单向的序列信息;对应地,
H
B
i
\mathcal H_{Bi}
HBi表示双向的序列信息。
H
S
i
n
g
l
e
=
{
h
L
;
1
,
h
L
;
2
,
⋯
,
h
L
;
T
}
H
B
i
=
{
h
L
R
;
1
,
h
L
R
;
2
,
⋯
,
h
L
R
;
T
}
\mathcal H_{Single} = \{h_{\mathcal L;1},h_{\mathcal L;2},\cdots,h_{\mathcal L;\mathcal T}\} \\ \mathcal H_{Bi} = \{h_{\mathcal L\mathcal R;1},h_{\mathcal L\mathcal R;2},\cdots,h_{\mathcal L\mathcal R;\mathcal T}\}
HSingle={hL;1,hL;2,⋯,hL;T}HBi={hLR;1,hLR;2,⋯,hLR;T}
其中
h
L
R
;
i
h_{\mathcal L\mathcal R;i}
hLR;i表示第
i
i
i时刻正、反方向序列信息的拼接
(
Concatenate
)
(\text{Concatenate})
(Concatenate)结果,以此类推。
h
L
R
;
i
=
[
h
L
:
i
;
h
R
;
(
T
+
1
−
i
)
]
i
=
1
,
2
⋯
,
T
h_{\mathcal L\mathcal R;i} = \left[h_{\mathcal L:i};h_{\mathcal R;(\mathcal T +1 -i)}\right] \quad i=1,2\cdots,\mathcal T
hLR;i=[hL:i;hR;(T+1−i)]i=1,2⋯,T
在代码中序列信息的描述表示如下:
import torch
from torch import nn as nn
BatchSize = 100
SeqLength = 10
EmbedSize = 8
NumHiddens = 16
NumLayers = 1
x = torch.randn(BatchSize,SeqLength,EmbedSize).permute(1,0,2)
SingleRNN = nn.GRU(EmbedSize,NumHiddens,NumLayers)
BiRNN = nn.GRU(EmbedSize,NumHiddens,NumLayers,bidirectional=True)
Output,State = SingleRNN(x)
print(x.shape)
print(Output.shape,State.shape)
BiOutput,BiState = BiRNN(x)
print(BiOutput.shape,BiState.shape)
序列信息的张量格式 ( Shape ) (\text{Shape}) (Shape)结果表示如下:
# Embedding Shape
torch.Size([10, 100, 8])
# SingleGRU.Output shape;FinalState shape
torch.Size([10, 100, 16]) torch.Size([1, 100, 16])
# BiGRU.Output shape;FinalState shape
torch.Size([10, 100, 32]) torch.Size([2, 100, 16])
可以观察一下,随意选取一个时刻。例如
T
=
2
\mathcal T = 2
T=2时刻。它对应的序列信息可表示为:
h
L
R
;
2
=
[
h
L
;
2
;
h
R
;
T
−
1
]
h_{\mathcal L\mathcal R;2} = \left[h_{\mathcal L;2};h_{\mathcal R;\mathcal T-1}\right]
hLR;2=[hL;2;hR;T−1]
观察:
- h L ; 2 h_{\mathcal L;2} hL;2包含了正向序列数据 x ( 1 ) , x ( 2 ) x^{(1)},x^{(2)} x(1),x(2)的序列信息;
- h R ; T − 1 h_{\mathcal R;\mathcal T-1} hR;T−1包含了反向序列数据 x ( T ) , x ( T − 1 ) , ⋯ , x ( 3 ) , x ( 2 ) x^{(\mathcal T)},x^{(\mathcal T - 1)},\cdots,x^{(3)},x^{(2)} x(T),x(T−1),⋯,x(3),x(2)的序列信息。这两组信息所组成的融合信息以 t = 2 t=2 t=2时刻为核心,将完整序列的序列信息都涵盖到了。
因而: h L R ; 2 h_{\mathcal L\mathcal R;2} hLR;2相比单向结构的 h L ; 2 h_{\mathcal L;2} hL;2包含更加丰富的序列信息。
解码过程这里同样以第
2
2
2时刻的解码为例:
这里'查询向量'使用
h
D
(
1
)
,
h
D
(
2
)
h_{\mathcal D}^{(1)},h_{\mathcal D}^{(2)}
hD(1),hD(2)都是有道理的。详见
上一节——注意力机制的动机
y
(
2
)
=
G
(
y
(
1
)
,
C
2
,
h
D
(
2
)
)
y^{(2)} = \mathcal G(y^{(1)},\mathcal C_2,h_{\mathcal D}^{(2)})
y(2)=G(y(1),C2,hD(2))
描述生成
y
(
2
)
y^{(2)}
y(2)信息的复杂函数
G
(
⋅
)
\mathcal G(\cdot)
G(⋅)中,一共包含
3
3
3类信息:
- 上一时刻的输出 y ( 1 ) y^{(1)} y(1);
- 当前时刻产生的序列信息 h D ( 2 ) h_{\mathcal D}^{(2)} hD(2);
- 通过注意力机制
(
Attention
)
(\text{Attention})
(Attention)产生的,基于当前时刻具有注意力偏向的序列信息
C
2
\mathcal C_2
C2。在双向结构中
C
2
\mathcal C_2
C2表示如下:
类似于上面单向网络,
( Bi ) s 2 j (\text{Bi})s_{2j} (Bi)s2j描述’解码器‘第
2 2 2时刻的序列信息
h D ( 2 ) h_{\mathcal D}^{(2)} hD(2)与‘编码器’第
j j j时刻的双向序列信息
H B i ( j ) = [ h L ; j ; h R ; ( T + 1 − j ) ] \mathcal H_{Bi}^{(j)} = \left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right] HBi(j)=[hL;j;hR;(T+1−j)]之间的评分结果。
{ ( Bi ) s 2 j = Score ( H B i ( j ) , h D ( 2 ) ) ( Bi ) S 2 = ( Bi ) ( s 21 , s 22 , ⋯ , s 2 T ) T ⇐ j = 1 , 2 , ⋯ , T C 2 = [ ( Bi ) S 2 ] T ⋅ H B i = ∑ j = 1 T ( Bi ) s 2 j ⋅ [ h L ; j ; h R ; ( T + 1 − j ) ] \begin{cases} \begin{aligned} (\text{Bi}) s_{2j} & = \text{Score}(\mathcal H_{Bi}^{(j)},h_{\mathcal D}^{(2)}) \\ (\text{Bi})\mathcal S_{2} & = (\text{Bi})(s_{21},s_{22},\cdots,s_{2\mathcal T})^T \quad \Leftarrow j=1,2,\cdots,\mathcal T\\ \mathcal C_2 & = [(\text{Bi}) \mathcal S_2]^T \cdot \mathcal H_{Bi}\\ & = \sum_{j=1}^{\mathcal T} (\text{Bi})s_{2j} \cdot \left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right] \end{aligned} \end{cases} ⎩ ⎨ ⎧(Bi)s2j(Bi)S2C2=Score(HBi(j),hD(2))=(Bi)(s21,s22,⋯,s2T)T⇐j=1,2,⋯,T=[(Bi)S2]T⋅HBi=j=1∑T(Bi)s2j⋅[hL;j;hR;(T+1−j)]
这种将 H B i \mathcal H_{Bi} HBi中的所有时刻的序列信息均做加权求和求解 C 2 \mathcal C_2 C2的方式称作软注意力机制 ( Soft-Attention ) (\text{Soft-Attention}) (Soft-Attention);
相反,与软注意力机制对应的是硬注意力机制
(
Hard-Attention
)
(\text{Hard-Attention})
(Hard-Attention)。这种注意力机制将
Score
\text{Score}
Score评分结果仅仅集中在若干个离散的序列信息中。也就是说,仅有
1
1
1个/若干个结果有
Score
\text{Score}
Score值,其余值均无影响。
但硬注意力机制比较困难,因为它在函数空间中并不处处可导。相反,软注意力机制在函数空间中处处可导,从而可以在反向传播过程中梯度进行传播。
注意力模型的数学推导整理
这里有一点啰嗦,不是一天写的,担待一下~
回顾机器翻译任务,最终目标是求解:给定输入序列数据
X
\mathcal X
X以及解码器前
t
−
1
t-1
t−1个时刻的输出信息
{
y
(
1
)
,
y
(
2
)
,
⋯
,
y
(
t
−
1
)
}
\{y^{(1)},y^{(2)},\cdots,y^{(t-1)}\}
{y(1),y(2),⋯,y(t−1)}条件下,求解
t
t
t时刻输出信息
y
(
t
)
y^{(t)}
y(t)的条件概率:
P
(
y
(
t
)
∣
X
,
y
(
1
)
,
y
(
2
)
,
⋯
,
y
(
t
−
1
)
)
\mathcal P(y^{(t)} \mid \mathcal X,y^{(1)},y^{(2)},\cdots,y^{(t-1)})
P(y(t)∣X,y(1),y(2),⋯,y(t−1))
从注意力机制的角度,将这个概率描述成函数的形式:
P
(
y
(
t
)
∣
X
,
y
(
1
)
,
y
(
2
)
,
⋯
,
y
(
t
−
1
)
)
=
G
(
y
(
t
−
1
)
,
h
D
(
t
)
,
C
t
)
\mathcal P(y^{(t)} \mid \mathcal X,y^{(1)},y^{(2)},\cdots,y^{(t-1)}) = \mathcal G(y^{(t-1)},h_{\mathcal D}^{(t)},\mathcal C_t)
P(y(t)∣X,y(1),y(2),⋯,y(t−1))=G(y(t−1),hD(t),Ct)
其中
y
(
t
−
1
)
y^{(t-1)}
y(t−1)表示解码器
t
−
1
t-1
t−1时刻的输出信息,作为
t
t
t时刻输入的一部分;
h
D
(
t
)
h_{\mathcal D}^{(t)}
hD(t)作为解码器当前时刻的序列信息,它表示为如下形式:
这里的‘复杂函数’
f
(
⋅
)
f(\cdot)
f(⋅)就是指循环神经网络系列的模型:
LSTM,GRU,RNN
\text{LSTM,GRU,RNN}
LSTM,GRU,RNN
h
D
(
t
)
=
f
(
y
(
t
−
1
)
,
h
D
(
t
−
1
)
,
C
t
)
h_{\mathcal D}^{(t)} = f(y^{(t-1)},h_{\mathcal D}^{(t-1)},\mathcal C_t)
hD(t)=f(y(t−1),hD(t−1),Ct)
关于
C
t
\mathcal C_t
Ct就是编码器各时刻的输出与相应
Score
\text{Score}
Score的加权求和结果:
这里仍然用‘双向循环网络’结构示例。
C
t
=
∑
j
=
1
T
s
t
j
⋅
[
h
L
;
j
;
h
R
;
(
T
+
1
−
j
)
]
\mathcal C_t = \sum_{j=1}^{\mathcal T} s_{tj} \cdot \left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]
Ct=j=1∑Tstj⋅[hL;j;hR;(T+1−j)]
关于编码器第
j
j
j个时刻的输出
[
h
L
;
j
;
h
R
;
(
T
+
1
−
j
)
]
\left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]
[hL;j;hR;(T+1−j)]与解码器
t
t
t时刻的序列信息
h
D
(
t
)
h_{\mathcal D}^{(t)}
hD(t)之间
Score
\text{Score}
Score结果
s
t
j
s_{tj}
stj的计算共分两个步骤:
-
用内积、或者构建神经网络的方式求解 Score \text{Score} Score结果;
关于两种方法的描述详见上一节:
注意力机制的动机
e t j = Score ( h D ( t ) ; [ h L ; j ; h R ; ( T + 1 − j ) ] ) j = 1 , 2 , ⋯ , T e_{tj} = \text{Score}(h_{\mathcal D}^{(t)};\left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]) \quad j=1,2,\cdots,\mathcal T etj=Score(hD(t);[hL;j;hR;(T+1−j)])j=1,2,⋯,T
这里以构建神经网络为例,描述 Score \text{Score} Score输出 E t ( e t 1 , e t 2 , ⋯ , e t T ) T \mathcal E_t (e_{t1},e_{t2},\cdots,e_{t\mathcal T})^T Et(et1,et2,⋯,etT)T的执行过程:- 将
h
D
(
t
)
h_{\mathcal D}^{(t)}
hD(t)(或者
h
D
(
t
−
1
)
h_{\mathcal D}^{(t-1)}
hD(t−1))与编码器输出
[
h
L
;
j
;
h
R
;
(
T
+
1
−
j
)
]
\left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]
[hL;j;hR;(T+1−j)]之间做向量拼接
(
Concatenate
)
(\text{Concatenate})
(Concatenate),并作为
Attn
\text{Attn}
Attn线性计算层的输入:
O ~ t = Attn ( h D ( t ) , [ h L ; j ; h R ; ( T + 1 − j ) ] ) = W Attn ⋅ [ Concat ( h D ( t ) , [ h L ; j ; h R ; ( T + 1 − j ) ] ) ] + b Attn \begin{aligned} \widetilde{\mathcal O}_t & = \text{Attn} \left(h_{\mathcal D}^{(t)},\left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]\right) \\ & = \mathcal W_{\text{Attn}} \cdot \left[\text{Concat}\left(h_{\mathcal D}^{(t)},\left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]\right)\right] +b_{\text{Attn}} \end{aligned} O t=Attn(hD(t),[hL;j;hR;(T+1−j)])=WAttn⋅[Concat(hD(t),[hL;j;hR;(T+1−j)])]+bAttn -
Attn
\text{Attn}
Attn层的激活函数选择
Tanh
\text{Tanh}
Tanh激活函数:
个人理解:在
数值稳定性、模型初始化与激活函数中介绍了激活函数的本质。激活函数的目的是:
维持低次项数值稳定的基础上(激活函数的线性近似区逼近 y = x y=x y=x,即恒等映射),去学习高次项特征。
关于激活函数作用的输出分布
O ~ ( t ) \widetilde{\mathcal O}^{(t)} O (t),从物理意义的角度,它仅仅是
h D ( t ) h_{\mathcal D}^{(t)} hD(t)与
[ h L ; j ; h R ; ( T + 1 − j ) ] \left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right] [hL;j;hR;(T+1−j)]之间关系的一个‘抽象’描述。但不可否认的是:
O ~ ( t ) \widetilde{\mathcal O}^{(t)} O (t)中的分量对表示两者之间关系存在实际价值。如果使用
ReLU \text{ReLU} ReLU激活函数去稀疏这个信息(使一部分分量置
0 0 0),个人认为不太可取。
O t = Tanh ( O ~ t ) \mathcal O_t = \text{Tanh}(\widetilde{\mathcal O}_t) Ot=Tanh(O t)
其次,从泰勒公式的角度,明显能够看出
Tanh \text{Tanh} Tanh激活函数在
低次项数值的映射结果中,它比
Sigmoid \text{Sigmoid} Sigmoid函数更接近‘恒等映射’:
{ Sigmoid ( x ) = 1 2 + 1 4 x − 1 48 x 3 + O ( x 5 ) Tanh ( x ) = 0 + x − 1 3 x 3 + O ( x 5 ) \begin{cases} \begin{aligned} \text{Sigmoid}(x) & = \frac{1}{2} + \frac{1}{4}x - \frac{1}{48} x^{3} + \mathcal O(x^5) \\ \text{Tanh}(x) & = 0 + x - \frac{1}{3}x^3 + \mathcal O(x^5) \end{aligned} \end{cases} ⎩ ⎨ ⎧Sigmoid(x)Tanh(x)=21+41x−481x3+O(x5)=0+x−31x3+O(x5)
并且
Tanh \text{Tanh} Tanh激活函数的映射范围是
( − 1 , 1 ) (-1,1) (−1,1),因此关于一些信息的非线性映射,
Tanh \text{Tanh} Tanh激活函数效果更优。
-
Tanh
\text{Tanh}
Tanh函数映射结束后,
O
t
\mathcal O_t
Ot中每一个分量的输出大小是解码器的隐藏层神经元数量。在此基础上,使用神经元权重
V
\mathcal V
V学习
O
t
\mathcal O_t
Ot的特征信息,并将
O
t
\mathcal O_t
Ot中每一个分量映射为标量信息:
E t = V T O t V ∈ R N D e × 1 \mathcal E_t = \mathcal V^T \mathcal O_t \quad \mathcal V \in \mathbb R^{\mathcal N_{De} \times 1} Et=VTOtV∈RNDe×1
- 将
h
D
(
t
)
h_{\mathcal D}^{(t)}
hD(t)(或者
h
D
(
t
−
1
)
h_{\mathcal D}^{(t-1)}
hD(t−1))与编码器输出
[
h
L
;
j
;
h
R
;
(
T
+
1
−
j
)
]
\left[h_{\mathcal L;j};h_{\mathcal R;(\mathcal T+1 - j)}\right]
[hL;j;hR;(T+1−j)]之间做向量拼接
(
Concatenate
)
(\text{Concatenate})
(Concatenate),并作为
Attn
\text{Attn}
Attn线性计算层的输入:
-
计算出的关于 Score \text{Score} Score的结果向量 E t = ( e t 1 , e t 2 , ⋯ , e t T ) T \mathcal E_t = (e_{t1},e_{t2},\cdots,e_{t\mathcal T})^T Et=(et1,et2,⋯,etT)T不能直接使用,需要将其映射成概率形式—— Softmax \text{Softmax} Softmax函数:
{ s t j = exp ( e t j ) ∑ k = 1 T exp ( e t k ) j = 1 , 2 , ⋯ , T S t = ( s t 1 , s t 2 , ⋯ , s t T ) T \begin{cases} \begin{aligned} s_{tj} & = \frac{\exp(e_{tj})}{\begin{aligned}\sum_{k=1}^{\mathcal T} \exp(e_{tk})\end{aligned}} \quad j = 1,2,\cdots,\mathcal T \\ \mathcal S_t & = (s_{t1},s_{t2},\cdots,s_{t\mathcal T})^T \end{aligned} \end{cases} ⎩ ⎨ ⎧stjSt=k=1∑Texp(etk)exp(etj)j=1,2,⋯,T=(st1,st2,⋯,stT)T
最终通过线性计算,求出 C t \mathcal C_t Ct。
至此,关于
3
3
3个信息:
y
(
t
−
1
)
,
h
D
(
t
)
,
C
t
y^{(t-1)},h_{\mathcal D}^{(t)},\mathcal C_t
y(t−1),hD(t),Ct都已求出,针对
3
3
3个信息构建神经网络,对
y
(
t
)
y^{(t)}
y(t)的后验概率
G
(
y
(
t
−
1
)
,
h
D
(
t
)
,
C
t
)
\mathcal G(y^{(t-1)},h_{\mathcal D}^{(t)},\mathcal C_t)
G(y(t−1),hD(t),Ct)进行预测:
对应函数的执行过程表示如下:
需要注意的是:这里的
y ( t − 1 ) y^{(t-1)} y(t−1)是上一时刻的输出特征,在作为下一时刻输入时,需将其重新转化为
Embedding \text{Embedding} Embedding向量信息。
关于
MaxOut \text{MaxOut} MaxOut激活函数,该函数一次比对若干个连续结果的大小,并取出其中最大的元素进行输出;移动窗口,执行下一次比较。其效果类似于
卷积神经网络中的最大池化层,用于“保留信息的基础上,降低特征维数。”这里使用窗口大小为
2 2 2进行示例。
{
h
~
t
=
U
o
⋅
h
D
(
t
)
+
V
o
⋅
C
t
+
C
o
⋅
Embedding
(
y
(
t
−
1
)
)
h
t
=
max
{
h
~
t
;
2
i
−
1
,
h
~
t
;
2
i
}
V
t
=
W
o
⋅
h
t
P
t
=
Softmax
(
V
t
)
\begin{cases} \begin{aligned} \widetilde{h}_t & = \mathcal U_o \cdot h_{\mathcal D}^{(t)} + \mathcal V_o \cdot \mathcal C_t + \mathcal C_o \cdot \text{Embedding}(y^{(t-1)}) \\ h_t & = \max\{\widetilde{h}_{t;2i-1},\widetilde{h}_{t;2i}\} \\ \mathcal V_t & = \mathcal W_o \cdot h_t \\ \mathcal P_t & = \text{Softmax}(\mathcal V_t) \end{aligned} \end{cases}
⎩
⎨
⎧h
thtVtPt=Uo⋅hD(t)+Vo⋅Ct+Co⋅Embedding(y(t−1))=max{h
t;2i−1,h
t;2i}=Wo⋅ht=Softmax(Vt)
最终使用
Argmax
\text{Argmax}
Argmax选择出对应位置的词语结果即可。
相关参考:
seq2seq与attention机制
激活函数(
ReLU,Swish,Maxout
\text{ReLU,Swish,Maxout}
ReLU,Swish,Maxout)
Seq2seq进阶,双向GRU