以 t 时刻为例,decoder输入共有三个: s_{t-1} , y_{t-1} , c_t 。其中s_{t-1}是上一个时刻的hidden state(一般用 h 表示encoder的hidden state,用 s 表示decoder的hidden state); y_{t-1} 是上一个时刻的输出,用来当做这个时刻的输入; c_t 叫做context,即由所有的encoder output(即 h ,不定长)得到一个定长的向量,代表输入序列的全局信息,作为当前decoder step的context(上下文)。计算方法为:
c
i
=
∑
j
=
1
T
x
α
i
j
h
j
c_i=\sum_{j=1}^{T_x}\alpha_{ij}h_j
ci=∑j=1Txαijhj,其中\alpha_{ij}是权重,又称为alignment;h 就是encoder所有step的hidden state,又叫做value或者memory; i 代表decoder step, j 代表encoder step。
那么,这个权重
α
i
j
\alpha_{ij}
αij 如何计算呢?
α i j = exp ( e i j ) ∑ k = 1 T x exp ( e i k ) \alpha_{ij}=\frac{\exp(e_{ij})}{\sum_{k=1}^{T_x}\exp(e_{ik})} αij=∑k=1Txexp(eik)exp(eij) ,其中 e i j = a ( s i − 1 , h j ) e_{ij}=a(s_{i-1},h_j) eij=a(si−1,hj) 。看上去有点复杂,先说第一个公式,其实就是一个softmax,因为我们要算一组权重,这组权重的和为1。那这个 e i j e_{ij} eij 又是什么呢?是通过某种度量 a ( ∙ ) a(\bullet) a(∙) 计算出来的 s i − 1 s_{i-1} si−1 和 h j h_j hj 的相关程度。即对于某个既定的decoder step,计算上个时刻的hidden state和所有encoder step的输出的相关程度,并且用softmax归一化;这样,相关度大的 h 权重就大,在整个context里占得比重就多,decoder在当前step做解码的时候就越重视它(这就是attention的思想)。
对
s
i
−
1
s_{i-1}
si−1 做一个线性映射,得到的向量叫做query,记做 q_i ;
对
h
j
h_j
hj 做一个线性映射,得到的向量叫做key,记做 k_j ;
e
i
j
=
v
T
⋅
(
q
i
+
k
j
)
e_{ij}=v^T \cdot (q_i+k_j)
eij=vT⋅(qi+kj) 。k_j和q_i的维度必须相同,记为 d ; v 是一个
d
×
1
d \times 1
d×1 的向量。