本文是邱锡鹏教授撰写的《神经网络与深度学习》一书中 第8章:注意力机制与外部记忆 的读书笔记,主要内容是一些本人觉得比较值得记录的内容,中间也会包括一些拓展和思考。
以下为注意力机制的流程图,查询 q \boldsymbol q q 通过注意力评分函数 a a a 与键 k \boldsymbol k k 作用,并通过softmax得到对应 k \boldsymbol k k 的概率分布值,最后这些概率分布值与值 v \boldsymbol v v 做加权和:
写成数学公式:
f ( q , ( k 1 , v 1 ) , ⋯ , ( k m , v m ) ) = ∑ i = 1 m softmax ( a ( q , k i ) ) v i = ∑ i = 1 m exp ( a ( q , k i ) ) ∑ j = 1 m exp ( a ( q , k j ) ) v i f(\boldsymbol q, (\boldsymbol k_1,\boldsymbol v_1),\cdots, (\boldsymbol k_m,\boldsymbol v_m)) = \sum_{i=1}^m \text{softmax}(a(\boldsymbol q,\boldsymbol k_i)) \boldsymbol v_i = \sum_{i=1}^m \frac{\text{exp}(a(\boldsymbol q,\boldsymbol k_i))}{\sum_{j=1}^m \text{exp}(a(\boldsymbol q,\boldsymbol k_j))} \boldsymbol v_i f(q,(k1,v1),⋯,(km,vm))=i=1∑msoftmax(a(q,ki))vi=i=1∑m∑j=1mexp(a(q,kj))exp(a(q,ki))vi
常用的注意力评分函数有 加性注意力 和 点积注意力 两种:
加性注意力:
a ( q , k ) = w v T tanh ( W q ⋅ q + W k ⋅ k ) ∈ R a(\boldsymbol q,\boldsymbol k) = \boldsymbol w_v^T\text{tanh}(\boldsymbol W_q \cdot \boldsymbol q + \boldsymbol W_k\cdot \boldsymbol k) \in \mathbb{R} a(q,k)=wvTtanh(Wq⋅q+Wk⋅k)∈R
其中可学习参数 W q ∈ R h × q , W k ∈ R h × k , w v ∈ R h \boldsymbol W_q \in \mathbb{R}^{h\times q}, \boldsymbol W_k \in \mathbb{R}^{h\times k}, \boldsymbol w_v \in \mathbb{R}^{h} Wq∈Rh×q,Wk∈Rh×k,wv∈Rh
点积注意力
a ( q , k i ) = q T k i d a(\boldsymbol q,\boldsymbol k_i) = \frac{\boldsymbol q^T \boldsymbol k_i}{\sqrt{d}} a(q,ki)=dqTki
点积评分函数计算效率更高,但是要求 q \boldsymbol q q 和 k \boldsymbol k k 具有相同的长度 d d d
在实践中,可以考虑批量计算注意力值来提升效率:
softmax ( Q K T d ) V ∈ R n × v \text{softmax}(\frac{\boldsymbol Q\boldsymbol K^T}{\sqrt{d}}) \boldsymbol V \in \mathbb{R}^{n\times v} softmax(dQKT)V∈Rn×v
其中 Q ∈ R n × d \boldsymbol Q \in \mathbb{R}^{n\times d} Q∈Rn×d 表示 n n n 个查询, K ∈ R m × d \boldsymbol K \in \mathbb{R}^{m\times d} K∈Rm×d 表示 m m m 个键, V ∈ R m × v \boldsymbol V \in \mathbb{R}^{m\times v} V∈Rm×v 表示 m m m 个值。
Note:在training时,decoder可以直接使用 y_gold 与 c \boldsymbol c c 拼接作为输入;而在inference时,由于 y_gold 是不可知的,因此使用上一时间步的输出与 c \boldsymbol c c 拼接
这种结构的seq2seq会有一个问题:decoder所有时间步从encoder中获得的信息都是一样的,没有区分。但这与实际情况往往是不相符的,例如对于翻译模型,target language中的某个词往往会与source language的某一两个词具有强相关性,而跟其它的词相关性很弱。而注意力机制恰好就可以解决这样的问题。
带注意力机制的seq2seq模型中,上下文变量 c \boldsymbol c c 不再简单的采用encoder的输出,而是encoder层隐变量与decoder上一时间步的注意力输出:
c t = ∑ i = 1 n softmax ( a ( s t − 1 , h i ) ) h i \boldsymbol c_t = \sum_{i=1}^n \text{softmax}(a(\boldsymbol s_{t-1},\boldsymbol h_i)) \boldsymbol h_i ct=i=1∑nsoftmax(a(st−1,hi))hi
其中 s t − 1 \boldsymbol s_{t-1} st−1 是decoder上一时间步的隐层输出, h i \boldsymbol h_i hi 是encoder最后隐层的所有时间步的输出。
所谓“多头”,是通过给{查询,键,值}组合施加不同的线性变换来实现的,每个头的定义如下:
h i = ∑ t = 1 n softmax ( a ( W i q q , W i k k t ) ) W i v v t ∈ R p v h_i = \sum_{t=1}^n \text{softmax}(a(\boldsymbol W^{q}_i \boldsymbol q, \boldsymbol W^{k}_i \boldsymbol k_t)) \boldsymbol W^{v}_i \boldsymbol v_t \in \mathbb{R}^{p_v} hi=t=1∑nsoftmax(a(Wiqq,Wikkt))Wivvt∈Rpv
其中 W i q ∈ R p d × d q , W i k ∈ R p k × d k , W i v ∈ R p v × d v \boldsymbol W^{q}_i \in \mathbb{R}^{p_d \times d_q}, \boldsymbol W^{k}_i \in \mathbb{R}^{p_k \times d_k}, \boldsymbol W^{v}_i \in \mathbb{R}^{p_v \times d_v} Wiq∈Rpd×dq,Wik∈Rpk×dk,Wiv∈Rpv×dv 是可学习参数。
之后所有的头需要经过一个线性转换:
W o [ h 1 ⋮ h h ] ∈ R p o \boldsymbol W^o\begin{bmatrix} \boldsymbol h_1\\ \vdots\\ \boldsymbol h_h \end{bmatrix} \in \mathbb{R}^{p_o} Wo⎣⎢⎡h1⋮hh⎦⎥⎤∈Rpo
其中 W o ∈ R p o × h p v \boldsymbol W^{o} \in \mathbb{R}^{p_o \times hp_v} Wo∈Rpo×hpv 也是可学习参数。
对同一 {查询,键,值} 施加不同的线性变换,并将这些结果组合起来,以此让模型学到比简单加权平均值更复杂的表示。
为了能够并行计算多个头,需要设置 p d = p k = p v = p o h p_d = p_k = p_v = \frac{p_o}{h} pd=pk=pv=hpo
论文地址:Attention Is All You Need
正如标题所表达的,Transfomer完全摒弃了循环神经网络的结构:
关于Transformer中注意力机制的详细使用情况,可以参加本人的另一篇博客 Transfomer矩阵维度分析及MultiHead详解
Reference:
动手学深度学习