@toc[文章目录]
一. 从RNN到Transformer
文字数据由于天然具有序列特性,与图像数据是不同的,因此最初的特征提取器(类似于图像中的CNN)采用了RNN结构:
对RNN有一定了解的话,就会知道RNN的两个明显问题:
- 效率问题:需要逐个词进行处理,后一个词要等到前一个词的隐状态输出以后才能开始处理,因此无法并行处理
- 如果传递距离过长还会有梯度消失、梯度爆炸和遗忘问题
为了解决第二个问题,就需要在RNN的隐层里设计各种门结构,代表作有:
-
LSTM
-
GRU
但是上述第一个问题依旧无法解决。终于,2017年Google在神作《Attention is all you need》提出了Transformer结构,后来出世的Bert模型(类比于CV中的Resnet)正是采用Transformer作为特征提取器在NLP11项任务上取得了SOTA效果,一举让RNN结构成为历史。
Transfromer是一个N进N出的结构,也就是说每个Transformer单元相当于一层的RNN层,接收一整个句子所有词作为输入,然后为句子中的每个词都做出一个输出。但是与RNN不同的是,Transformer能够同时处理句子中的所有词,并且任意两个词之间的操作距离都是1,这么一来就很好地解决了上面提到的RNN的效率问题和距离问题。(这是什么鬼?!看下面Transformer结构…)
二. 解析Transformer
2.1 Transformer结构
宏观层面
Transformer本质上是一个Encoder-Decoder结构:
如论文中所设置的,编码器由6个编码block组成,同样解码器是6个解码block组成,每个block结构相同,但不共享参数。与所有的生成模型相同的是,编码器的输出会作为解码器的输入,如图所示:
微观层面
Ok,我们再来看一下每个encoder和decoder内部长什么样:
定义输入序列首先经过 word embedding,再和 positional encoding 相加后,输入到 encoder 中。输出序列经过的处理和输入序列一样,然后输入到 decoder。
最后,decoder 的输出经过一个线性层,再接 Softmax。
(是不是看起来很可怕?)不着急,后面会具体解析每个模块,现在先在脑子里先记住几个重要的单词!!!
- Self-attention
- Feed forward
- Add&Norm
记好了下面就开始了:
encoder
encoder由 6 层相同的层组成,每一层分别由两部分组成:
- 第一部分是 multi-head self-attention
- 第二部分是 position-wise feed-forward network,是一个全连接层
两个部分,都有一个残差连接(residual connection),然后接着一个 Layer Normalization。
decoder
和 encoder 类似,decoder 也是由6个相同的层组成,每一个层包括以下3个部分:
- 第一个部分是 multi-head self-attention mechanism
- 第二部分是 multi-head context-attention mechanism
- 第三部分是一个 position-wise feed-forward network
和 encoder 一样,上面三个部分的每一个部分,都有一个残差连接,后接一个 Layer Normalization。
decoder 和 encoder 不同的地方在 multi-head context-attention mechanism。
2.2 Attention
Transformer堪称把attention发挥到了极致,本节讲讲multi-head self-attention模块。
2.2.1 self-attention是什么
直观表示
如上图所示,我们想知道句子中的"it"是指什么,“animal”, “street” 或者其他单词,很显然,这里"it"指的就是"animal”,所以"it"会将更多的attention放在单词"animal"上。也就是说,"it"对于"animal"的权重是最大的。
个人理解,self-attention就是算出每个词对于这个词的权重,然后将这个词表示为所有词的加权和。
数学表示
为了求出这个权重大小,论文中给出了名为Scaled Dot-Product Attention的操作:
首先对于每个输入的embedding词向量x(论文中设为512维),利用线性变化矩阵Wq, Wk, Wv, 生成三个向量q(query), k(key), v(value), 论文中每个向量均为64维。
对于每一个词,为句子中的每个词计算一个score: score = qi . kj;
之后再对每个score除以 sqrt(dk)进行归一化,再计算其 softmax输出 score;
对于每个 value 向量的 score 加权和即为 当前词的attention输出。
利用向量表示为:
2.2.2 Multi-head Attention
这个模块即是将各个 self-attention模块的输出concat起来后再做一个线性变换。
论文中 h取为8, 采用multi-head的优点为:
- 扩展模型能力可以注意到不同位置,一个注意力模型的关注点也许是错的,通过多个注意力模型可以提高这种泛化能力;
- 使得注意力层具有多个表示子空间,比如说上文的8个注意力模型,经过训练后,我们就可以将输入的词嵌入映射到8个不同的表示子空间;
2.3 Position-wise Feed Forward Network
对于输入向量Z, 这就是一个前馈网络