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