一、self-attention
自注意力self-attention和一般attention区别仅在于:自注意力的“自”,就是key,value,query都来自 自己。
给定一个长度为n的序列x1,...,xn,其中xi向量是一个长度为d的特征。
对于上图的yi,xi是query,key-value pair就是x1-x1,...,xn-xn。自注意力输入一个序列,就可以对序列中每一个元素有一个输出。
处理序列的方法对比(n为序列长度,k为kernel窗口大小,每一个token用长度为d的向量表示):
计算复杂度/时间复杂度:估计乘法操作的次数
并行度O(n):假设输出有n个,这n个可以并行做运算
最长路径:距离为n的两个结点(x1的信息要传递到xn)传递信息所经历的路径长度。对于CNN,每次kernel只看长度为k的区域,如果k很大,一次就可以看到整个序列,如果k小,则需要很多层才可以看到足够长的序列,在CNN里这个最长路径大致可以理解为网络深度(从某节点出发,走过最长路径的长度到达的节点,在该节点上可以看到整个序列)。
也就是说最大路径长度,可以认为是深度/层数,即我需要走几层可以看到整个序列。序列中两个元素进行交互所需经过的最大路径长度。
由上表格总结:自注意力适合处理很长的序列,因为最长路径O(1)(站在某个节点上,走1步到达的节点,站在这个节点上,就可以看到很宽的序列/可以得到很宽的序列的信息。任何输出可以看到整个序列信息),但计算量大。
CNN中的感受野Receptive Field:是指特征图feature map上的某个点能看到的输入图像的区域,即特征图上的点是由输入图像中 感受野 大小区域的计算得到的。
关于CNN处理文本序列:可参考CNN进行文本分类
关于上述三种方法的各指标对比:可参考计算复杂度等求解方式和对比
二、位置编码
和CNN/RNN不同,CNN的窗口kernel是有位置信息在里面的,RNN中序列自然有记录位置信息,但自注意力没有记录位置信息。
加入位置信息的方法:位置编码,但不是把位置信息加入模型(一旦加入模型,CNN每次要看一个很长的序列,RNN并行度低),所以不改变注意力机制本身让它既能看得宽又能并行度高。做法是:将位置信息注入到输入里,
n:一行一个样本,d:一列一个特征。
具体P的计算(-1~1的数):
对每一个样本,每一个特征,不同位置加不一样的值。
位置编码(用-1~1之间的数来编码)类似计算机的二进制编码,都有周期,每个样本的编码可以用一定长度的特征表示位置信息:
为什么位置编码要用sin/cos来做:因为编码的是相对位置信息,关注绝对位置i是有问题的,
具体如下,
关于位置编码:可以参考position encoding ,Transformer模型的位置编码
三、总结