什么是Self-attention

Self-attention用于解决输入是许多向量的情况(向量个数不固定),即sequence。比如在NLP中,我们的输入是一个句子,把句子中的每一个单词看成一个向量,那么这个句子就是诸多向量的集合;并且由于句子长度会变化,这个集合的大小也会变。

这种模型输出可能有3种:

  • 每个向量都对应一个输出,输入和输出的长度一致。每个输出可以是数值(Regression),可以是类别(Classification)。这种输出模式称为Sequence Labeling

    image-20241219222131885

    比如说NLP中的词性标注,每一个单词都对应一个词性就适用这种输出。

  • 整个向量集合就一个输出。

    image-20241219222458878

    比如去判断某句话是positive还是negative就适用这种输出。

  • 输出数由模型自己决定,这种任务即seq2seq的任务。

    image-20241219230444412

    比如翻译任务,输入和输出是不同的语言,就属于seq2seq的任务。

Self-attention怎么架构?

下面的介绍都以Sequence Labeling为例。

总的来说

image-20241219232459383

这里的Self-attention层需要考虑输入的全部向量,并且对于每个向量都给出相对应的一个输出,让每个输出经过一个全连接层得到最后的label。

当然这里的Self-attention层也可以叠很多层,与全连接层交替使用:

image-20241219232753874

具体每个输出的向量怎么来?

image-20241219233215994

这里的b1、b2、b3、b4都需要考虑a1、a2、a3、a4这4个向量才能生成,下面来具体叙述一下生成过程(以b1为例):当然这里b1、b2、b3、b4都是并行生成的,它们之间没有依赖关系。

  • 衡量a1向量与其他向量间的相关度α\alpha。这个的计算方法有很多种,下面列出了两种:

    image-20241219233749464

    这里的WqW^qWkW^k代表两个不同的矩阵,它们是神经网络的参数。在Dot-product方法里,待计算相关度的两个向量分别与这两个矩阵相乘得到向量qqkk,把向量qqkk各项相乘再相加就得到相关度α\alpha

    image-20241220002302572

    这里也不一定要经过Soft-max层,可以是ReLU等等函数。这层的作用实际上是在正规化,让正规化后的四个值相加为1即可。

  • 根据attention score抽取每个输出向量的关键部分

    image-20241220002616854

以矩阵的形式来表示如下:

image-20241220162525125 image-20241220163015863 image-20241220163156685

在整个训练过程中,只有矩阵WqW^qWkW^kWvW^v三个的数值是需要我们通过数据集去找出的。

Multi-head Self-attention

两个向量之间的“相关”可能不单单是一个层面上的,可以有多个方面的相关,Multi-head Self-attention就用于处理这种情况。以2-head为例,

image-20241220164528073

在得到qiq^i后,把qiq^i乘上另外两个矩阵,得到qi,1q^{i,1}qi,2q^{i,2}(对kik^iviv^i的处理一致)。然后对同为1或者2的q、k、v做dot product和相加这种操作,最后得到的向量是bi,1b^{i,1}bi,2b^{i,2}这两个。把这两个向量接起来,再做一个变换变成b向量。

image-20241221184657867

这里的head数也是一个超参数。

考虑上位置因素?

在前面的所有讨论中,每个输入向量不论处于哪个位置,对该向量的处理都是一样的,没有涉及到“这个向量在哪里”这个问题。

比如在词性辨识中,第一个单词是助词的概率很小,而是名词形容词的概率就比较大,我们需要考虑上这一点。

考虑位置的操作即Positional Encoding,是采用往aia^i上加上一个新向量eie^i来实现的。而这个新向量eie^i可以通过人工去设定,也可以从数据集中学到。

image-20241221195200876

自注意力机制不仅仅适用于NLP

语音数据:Truncated Self-attention

当我们在做语音辨识时,由于音频所产生的向量数非常多,就会导致矩阵WqW^qWkW^kWvW^v非常大以至于存不进内存。在这种情况下我们会考虑Truncated Self-attention这种方法,即每个Self-attention层不是考虑全部的输入向量,而是考虑一部分输入向量。

例如对于输出向量b3b^3而言,其需要考虑的输入向量是a3a^3及其前后几个向量,至于具体是几个那这也是一个超参数。

图片数据如何Self-attention?

image-20241221203324786

我们将每个像素点上RGB三个channel的值作为输入的向量。

可以比较一下处理图片时的CNN和Self-attention:

  • CNN只考虑Receptive field中的像素点(比如3*3大小)。
  • Self-attention会涉及到图片中任意两个像素点间向量的dot product,利用attention去找出相关性,相当于Receptive field是被“学”出来的而不是人为设定的,因此实际上是考虑了全图。
  • 由此可见CNN是简化版的Self-attention。而由于Self-attention更加灵活,其训练需要的数据量会更大。(训练数据少会过拟合)

同样是处理序列数据,也可以比较一下RNN和Self-attention:

image-20241221204726070
  • 对于RNN末尾的输出而言,其想要考虑到输入的第一个向量是比较困难的,因为它要把初始向量存在memory里一直带到最后。
  • RNN的后项输出依赖前项的输出,不能像Self-attention一样进行并行处理。

Self-attention处理Graph

在Graph中,每个Node是Self-attention中的输入向量,每个Edge能代表两个Node间的相关性。因此在使用Self-attention时,在计算Attention Matrix时,可以只计算有Edge连接的两个Node向量间的相关性,其余直接设0即可。这种网络架构即GNN(图神经网络)

image-20241221211402712