本文作为自己学习李宏毅老师2021春机器学习课程所做笔记,记录自己身为入门阶段小白的学习理解,如果错漏、建议,还请各位博友不吝指教,感谢!!


全连接网络的输入是一个向量,但是当输入是一个变长的向量序列时,就不能再使用全连接网络了。这种情况通常可以使用卷积网络或循环网络进行编码来得到一个相同长度的输出向量序列

基于卷积或循环网络的序列编码都是一种局部的编码方式,只建模了输入信息的局部依赖关系。虽然循环网络理论上可以建立长距离依赖关系,但是由于信息传递的容量以及梯度消失问题,实际上也只能建立短距离依赖关系。

要建立输入序列之间的长距离依赖关系,可以通过如下两种方法:

  1. 增加网络的层数,通过一个深层网络来获取远距离的信息交互;
  2. 使用全连接网络。

全连接网络是一种非常直接的建模远距离依赖的模型,但是如上边所说无法处理变长的输入序列。不同的输入长度(此处指的是向量序列的长度),其连接权重的大小也是不同的。这种情况我们就可以利用注意力机制来“动态”地生成不同连接地权重,即自注意力模型(Self-Attention Model)


输入/输出

  1. 自注意力模型输入:如下图所示,左侧的变长的输入序列即是自注意力模型的输入数据,注意这个向量序列的长度不是固定的


自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算


  1. 自注意力模型输出:自注意力模型的输出有三种情况:
  • 输出序列长度和输入序列长度一样,这种情况下,输入序列中的向量和结果序列中的元素一一对应,也就是为每一个输入序列中的向量给出一个label。如下图所示:


自注意力层的注意力权重如何计算_全连接_02


  • 输出序列的长度为1,此时相当于一个分类任务,比如像对正面/负面评论的分析。如下图所示:


自注意力层的注意力权重如何计算_依赖关系_03


  • 输出序列的长度是不定的,这种情况其实也就是Seq2Seq模型,比如机器翻译。如下图所示:


自注意力层的注意力权重如何计算_全连接_04



Attention函数




自注意力层的注意力权重如何计算_Self_05

自注意力层的注意力权重如何计算_依赖关系_06


因为要建立输入向量序列的长依赖关系,所以模型要考虑整个向量序列的信息。如上边左图所示,Self-Attention的输出序列长度是和输入序列的长度一样的,对应的输出向量考虑了整个输入序列的信息。然后将输出向量输入到Fully-Connected网络中,做后续处理。当然Self-Attention可以和Fully-Connected交替使用多次以提高网络的性能,如上边右图所示。

上边我们提到,Self-Attention可以使用多次,那么输入可能是整个网络的输入,也可能是前一个隐藏层的输出,这里我们使用自注意力层的注意力权重如何计算_Self_07来表示输入,使用自注意力层的注意力权重如何计算_全连接_08表示输出为例。



自注意力层的注意力权重如何计算_全连接_09


首先Self-Attention会计算自注意力层的注意力权重如何计算_Self_10分别与自注意力层的注意力权重如何计算_Self_07的相关性自注意力层的注意力权重如何计算_Self_12。相关性表示了输入自注意力层的注意力权重如何计算_Self_07自注意力层的注意力权重如何计算_Self_10是哪一个label的影响大小。而相关性自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_15的计算方式共有Dot-product和Additive两种。

Dot-product



自注意力层的注意力权重如何计算_依赖关系_16


在Dot-product中,输入的两个向量,左边的向量乘上矩阵自注意力层的注意力权重如何计算_Self_17得到矩阵自注意力层的注意力权重如何计算_依赖关系_18,右边的向量乘上矩阵自注意力层的注意力权重如何计算_全连接_19得到矩阵自注意力层的注意力权重如何计算_全连接_20,然后将矩阵自注意力层的注意力权重如何计算_依赖关系_18和矩阵自注意力层的注意力权重如何计算_全连接_20对应元素相乘并求和得到相关性自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_15

Additive



自注意力层的注意力权重如何计算_全连接_24


在Additive中同样也是先将两个输入向量与矩阵自注意力层的注意力权重如何计算_Self_17和矩阵自注意力层的注意力权重如何计算_全连接_19相乘得到矩阵自注意力层的注意力权重如何计算_依赖关系_18自注意力层的注意力权重如何计算_全连接_20。然后将矩阵自注意力层的注意力权重如何计算_依赖关系_18自注意力层的注意力权重如何计算_全连接_20串起来输入到一个激活函数(tanh)中,在经过Transform得到相关性自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_15


Self-Attention计算过程

为了提高模型能力,自注意力模型经常采用查询-键-值(Query-Key-Value,QKV)模型,其计算过程如下所示:

  1. 首先计算自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_32自注意力层的注意力权重如何计算_依赖关系_33的关联性自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_34(实践时一般也会计算与自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_32自己的相关性)。以Dot-product为例,我们分别将自注意力层的注意力权重如何计算_Self_36,自注意力层的注意力权重如何计算_依赖关系_37,自注意力层的注意力权重如何计算_全连接_38作为Dot-product的输入,求得对应的相关性自注意力层的注意力权重如何计算_全连接_39,如下图所示:


自注意力层的注意力权重如何计算_Self_40


  1. 计算出自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_32跟每一个向量的关联性之后,将得到的关联性输入的softmax中,这个softmax和分类使用的softmax时一样的,得到对应数量的自注意力层的注意力权重如何计算_依赖关系_42。(当然这里使用ReLU或其他激活函数代替softmax也是可以的,根据实际效果来)


自注意力层的注意力权重如何计算_Self_43


  1. 先将自注意力层的注意力权重如何计算_Self_44每一个向量分别乘上矩阵自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_45得到新的向量自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_46,然后把自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_46都乘上Attention的分数自注意力层的注意力权重如何计算_依赖关系_42,然后相加得到自注意力层的注意力权重如何计算_全连接_49


自注意力层的注意力权重如何计算_Self_50


假设自注意力层的注意力权重如何计算_Self_10自注意力层的注意力权重如何计算_Self_52的关联性很强,则由这两个向量计算得到的自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_53的值就很大,最后求得的自注意力层的注意力权重如何计算_全连接_08的值,就可能会比较接近自注意力层的注意力权重如何计算_Self_55。所以哪一个向量的Attention的分数最大,那一个向量的自注意力层的注意力权重如何计算_依赖关系_56就会主导最后计算出来的结果自注意力层的注意力权重如何计算_依赖关系_57


Self-Attention计算矩阵

由上边计算过程可知,每个输入自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_58都会产生自注意力层的注意力权重如何计算_依赖关系_18自注意力层的注意力权重如何计算_全连接_20自注意力层的注意力权重如何计算_依赖关系_56三个矩阵。这里还是以自注意力层的注意力权重如何计算_Self_07为输入为例:

  1. 我们将自注意力层的注意力权重如何计算_Self_44按照公式自注意力层的注意力权重如何计算_Self_64依次乘以矩阵自注意力层的注意力权重如何计算_Self_65得到自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_66,那我们将自注意力层的注意力权重如何计算_Self_44作为4列拼成一个矩阵自注意力层的注意力权重如何计算_Self_68,将自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_66作为4列拼成一个矩阵自注意力层的注意力权重如何计算_全连接_70得到计算矩阵如下:(矩阵自注意力层的注意力权重如何计算_Self_71自注意力层的注意力权重如何计算_全连接_72的计算方式一样)


自注意力层的注意力权重如何计算_Self_73


  1. 我们得到自注意力层的注意力权重如何计算_全连接_70自注意力层的注意力权重如何计算_Self_75自注意力层的注意力权重如何计算_依赖关系_76三个矩阵之后,下一步就是由矩阵自注意力层的注意力权重如何计算_全连接_70自注意力层的注意力权重如何计算_Self_75计算关联性自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_34,先以计算自注意力层的注意力权重如何计算_依赖关系_80的关联性为例,将矩阵自注意力层的注意力权重如何计算_依赖关系_80分别与矩阵自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_82相乘得到自注意力层的注意力权重如何计算_依赖关系_83(我们现在是看作矩阵运算,为了方便计算,我们先对矩阵自注意力层的注意力权重如何计算_全连接_84进行转置,在和矩阵自注意力层的注意力权重如何计算_依赖关系_80相乘):


自注意力层的注意力权重如何计算_依赖关系_86


  1. 我们将第一步中得到的矩阵自注意力层的注意力权重如何计算_Self_75整体转置,与矩阵自注意力层的注意力权重如何计算_全连接_70相乘,得到所有的相关性矩阵自注意力层的注意力权重如何计算_Self_89;然后对attention分数(相关性)做normalization,即每次对自注意力层的注意力权重如何计算_Self_89中的一列(每列对应着一个自注意力层的注意力权重如何计算_Self_91)做softmax(也可以是其他激活函数),让每一列的值相加为1,得到矩阵自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_92,如下图所示:


自注意力层的注意力权重如何计算_Self_93


  1. 我们将矩阵自注意力层的注意力权重如何计算_依赖关系_76依次乘以矩阵自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_92中的每一列得到输出自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_96,如下图所示:


自注意力层的注意力权重如何计算_Self_97


综上所述,矩阵计算公式如下:

  1. 计算自注意力层的注意力权重如何计算_全连接_98自注意力层的注意力权重如何计算_依赖关系_99自注意力层的注意力权重如何计算_依赖关系_100三个矩阵
    自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_101
  2. 计算相关性并使用softmax作normalization:
    自注意力层的注意力权重如何计算_全连接_102
  3. 计算最后的输出
    自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_103

通过上述计算过程,我们可以看出只有自注意力层的注意力权重如何计算_Self_65自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_105自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_45三个矩阵是未知的,需要我们通过训练资料将他们学习出来


Multi-head Self-Attention

Self-Attention有一个使用非常广泛的的进阶版Multi-head Self-Attention,具体使用多少个head,是一个需要我们自己调节的超参数(hyper parameter)。

在Self-Attention中,我们是使用自注意力层的注意力权重如何计算_依赖关系_18去寻找与之相关的自注意力层的注意力权重如何计算_全连接_20,但是这个相关性并不一定有一种。那多种相关性体现到计算方式上就是有多个矩阵自注意力层的注意力权重如何计算_Self_109,不同的自注意力层的注意力权重如何计算_Self_109负责代表不同的相关性。我们以2 heads为例,先使用自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_58计算得到自注意力层的注意力权重如何计算_依赖关系_18,然后让自注意力层的注意力权重如何计算_依赖关系_18乘以两个矩阵自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_114自注意力层的注意力权重如何计算_Self_115得到自注意力层的注意力权重如何计算_全连接_116自注意力层的注意力权重如何计算_依赖关系_117,代表2 heads,以同样的方式处理自注意力层的注意力权重如何计算_全连接_20自注意力层的注意力权重如何计算_依赖关系_56,如下图所示:



自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_120


在后续的计算中,我们只将属于相同相关性的矩阵进行运算,如下图所示:



自注意力层的注意力权重如何计算_全连接_121


  1. 自注意力层的注意力权重如何计算_全连接_122分别与自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_123自注意力层的注意力权重如何计算_依赖关系_124计算得到自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_125自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_126
  2. 然后将自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_125自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_126分别与自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_129自注意力层的注意力权重如何计算_依赖关系_130相乘得到自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_131
  3. 我们以同样的方式,得到矩阵自注意力层的注意力权重如何计算_全连接_132,将自注意力层的注意力权重如何计算_自注意力层的注意力权重如何计算_131自注意力层的注意力权重如何计算_全连接_132拼起来乘以一个矩阵自注意力层的注意力权重如何计算_Self_135得到最后的输入自注意力层的注意力权重如何计算_依赖关系_136


自注意力层的注意力权重如何计算_全连接_137



Positional Encoding

通过前边的了解,可以发现对于每一个input是出现在sequence的最前面,还是最后面这样的位置信息,Self-Attention是无法获取到的。这样子可能会出现一些问题,比如在做词性标记(POS tagging)的时候,像动词一般不会出现在句首的位置这样的位置信息还是非常重要的。

我们可以使用positional encoding的技术,将位置信息加入到Self-Attention中。



自注意力层的注意力权重如何计算_Self_138


如上图所示,我们可以为每个位置设定一个专属的positional vector,用自注意力层的注意力权重如何计算_全连接_139表示,上标自注意力层的注意力权重如何计算_依赖关系_140代表位置。我们先将自注意力层的注意力权重如何计算_全连接_139自注意力层的注意力权重如何计算_全连接_142相加,然后再进行后续的计算就可以了。自注意力层的注意力权重如何计算_全连接_139向量既可以人工设置,也可以通过某些function或model来生成,具体可以查阅相关论文。


参考资料:
《神经网络与深度学习》 邱锡鹏