Transformer(变形金刚)的一个重要应用是bert
Transformer是一种seq2seq模型,它的特殊之处是大量地用了self-attention layer
处理sequence最常使用的架构是RNN,如下图左侧。它的问题是:不容易被平行化
非平行化:想输出b3,需要将a1、a2、a3全部看一遍;想输出b4,需要将a1、a2、a3、a4全部看一遍;如果是双向RNN,则不论输出什么,均需将全部输入都看一遍
可以简单理解为不能并行计算,算b3的时候不能同时计算b4
为了解决不能平行化的问题,有人提出用CNN取代RNN的想法,如上图右侧。每个三角形代表一个filter,每一个的输入是输入sequence的其中一小段。这样通过多个filter,可做到和RNN相类似的效果:输入是一个sequence,输出是另外一个sequence。
但是问题是,每一个CNN只能够考虑非常有限的内容。但是当叠加很多层CNN后,上层的就可以考虑比较多的信息。第二层的filter会把第一层的output当成是它的input。
平行化:图中每一个三角的filter都可以同时计算,不需要等第一个算完再算第二个,可以全部的filter同时计算。甚至不需要等第一层的算完再算第二层,全部可以同时计算。
但CNN的缺点是,必须要叠很多层,它才能够看到比较长的信息。如果第一层的filter就需要看比较长的信息,做不到,只能看很小的范围。
为了解决CNN看不到很多信息的问题,有了self-attention,想要取代原来RNN可以做的事情。简单来讲:有一种新的layer,叫做self-attention layer,它的输入和输出和RNN是一样的,都是seq2seq,可以注意到全部的输入,并且可以完全地平行化。如下图:
基本可以用self-attention代替RNN做任何事情(一种可以并行计算的RNN)。
下面为self-attention的详细过程:
可以通过调节不同位置α的值,控制输出的结果需要注意的不同输入的注意力多少。即既可以全部都注意,也可以只注意一部分,既可以注意近的,也可以注意远的。避免了RNN中句子过长记不住导致的问题。
同时可以并行计算出b2:
下面详细讲解self-attention是怎么做平行化的(矩阵计算):
矩阵乘法可以轻易地用GPU加速。
self-attention的变形:多头self-attention。以2头为例:
多头的好处是:有可能不同的head关注的点不一样。如有的head想要看的就是local邻居的信息,有的head想要看的是较长时间的。有了多头之后,每个head可以各司其职,自己做想做的事情。 self-attention没有时间信息,无论远的还是近的都一样,天涯若比邻。这样的话就考虑不到句子的上下文信息了。所以解决办法是,xi变成ai之后,要加上一个位置矩阵ei来表示位置信息。 那为什么用加而不是矩阵拼接呢?矩阵加起来不就将信息混在一起了吗?可以解释为:将xi拼接上一个one-hot位置矩阵,然后做运算,则可分别得出ai和ei相加的结果。如下图:
奇怪的是,ei不是学出来的,是人手设的,wp也不是学出来的。试图学习之后效果不好,所以用了一个式子生成wp。Wp的可视化表示如下图:
上面讲的是self-attention取代RNN。下面讲解self-attention在seq2seq模型中如何使用。
下图为原始的seq2seq模型模型,有encoder和decoder,都是使用RNN。其中encoder使用双向RNN:
使用self-attention取代RNN是即得到transformer:
Attention的可视化表示:
每个词两两之间都有attention,联系约紧密的线条越粗
一个神奇的现象:
It可自动学习,指代不同的内容
动物没有过马路,因为它太累了(它指动物)
动物没有过马路,因为它太宽了(它指马路)
多头的每一组QKV所做的事情都不同:
会注意不同的attention,如红色的注意了附近的词,绿色的注意了远处的词
总结:只要是能使用seq2seq模型的,都可以用transformer。使用self-attention取代RNN的seq2seq模型就是transformer。
使用了transformer之后,可以比之前使用RNN处理更多的数据量。如Google使用文本集合,集中直接生成摘要。例子:
Transformer的变种:
Transformer之前被用在文本上,现在也可以用在图像上: