自注意力和位置编码
2021-12-5
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
 
 
 

Why self-attention

RNN有什么样的问题呢?它的问题就在于:RNN很不容易并行化 (hard to parallel)
CNN、RNN共享单元和滑动结构类似,区别在于RNN具有记忆功能,被遍历的单元具有因果联系作用(记忆信息传送),上一时刻隐层的状态参与到了这个时刻的计算过程中,所以当前单元必须等上一单元计算结束,有多少单元就需要计算多少次。而CNN同一层次单元没有因果关系都是等价的,这样就可以依据单元核直接复制出所需所有单元核(参数相同),然后采用矩阵并行运算,只需计算一次。
notion image
表面上CNN和RNN可以做到相同的输入和输出,但是CNN只能考虑非常有限的内容。CNN也不是没有办法考虑很长时间的dependency的,只需要堆叠filter,多堆叠几层,上层的filter就可以考虑比较多的资讯,只要叠很多层,就能够看很长时间的资讯。
但是必须要叠很多层filter,才可以看到长时的资讯,所以有了一个想法:self-attention,使用self-attention layer取代RNN所做的事情
notion image
有了注意力机制之后,将词元序列输入注意力池化中, 以便同一组词元同时充当查询、键和值。 具体来说,每个查询都会关注所有的键-值对并生成一个注意力输出。 由于查询、键和值来自同一组输入,因此被称为 自注意力(self-attention) , 也被称为内部注意力(intra-attention)
 
 
 

self-attention是怎么运作的呢?

notion image
这里的每一个b都是考虑了所有的a产生的,比如 是考虑 ~ 产生的, 是考虑~ 产生的。
那么怎么产生 这个向量呢?
 
根据 找出这个sequence里面和 相关的其他向量
notion image
每一个向量和关联的程度,用一个数值α来表示。那么这个α是怎么产生的呢?就是给一个 ,怎么去决定它们之间的关联程度α是怎么样的呢?
 
Self-Attention计算 分别与 的相关性 。相关性表示了输入 是哪一个label的影响大小。而相关性 的计算方式共有Dot-product和Additive两种。
notion image
比较常见的是Dot-product,输入的两个向量,左边的向量乘上矩阵 得到矩阵 ,右边的向量乘上矩阵 得到矩阵 ,然后将矩阵 和矩阵 对应元素相乘并求和得到相关性
在Additive中同样也是先将两个输入向量与矩阵相乘得到。然后将矩阵串起来输入到一个激活函数中,在经过transfor得到相关性
 
为了提高模型能力,自注意力模型经常采用查询-键-值(Query-Key-Value,QKV)模型,其计算过程如下所示:
notion image
计算 的关联性 (一般也会计算与自己的相关性)。以Dot-product为例,分别将 , , 作为Dot-product的输入,求得对应的相关性
 
notion image
计算出跟每一个向量的关联性之后,将得到的关联性输入的softmax中,得到对应数量的 。(当然这里使用ReLU或其他激活函数代替softmax也是可以的,根据实际效果来)
 
 
每一个向量分别乘上矩阵 得到新的向量 ,然后把 都乘上Attention的分数 ,然后相加得到
notion image
假设 的关联性很强,则由这两个向量计算得到的 的值就很大,最后求得的 的值,就可能会比较接近 。所以哪一个向量的Attention的分数最大,那一个向量的 就会主导最后计算出来的结果
 

从矩阵乘法的角度

notion image
notion image
notion image
notion image
 
notion image
 
 

Multi-head Self-Attention

在Self-Attention中,我们是使用去寻找与之相关的,但是这个相关性并不一定有一种。那多种相关性体现到计算方式上就是有多个矩阵,不同的负责代表不同的相关性
以2 heads为例,先使用 计算得到 ,然后让 乘以两个矩阵 得到 ,代表2 heads,以同样的方式处理,如下图所示:
notion image
 
notion image
 
notion image
 
这里有一组Multi-head Self-attention的结果,其中绿色部分是一组query和key,红色部分是另外一组query和key,可以发现绿色部分其实更关注global的信息,而红色部分其实更关注local的信息
notion image
 
 
给定一个由词元组成的输入序列 , 其中任意 )。 该序列的自注意力输出为一个长度相同的序列 ,其中:
是注意力池化函数。
 
下面的代码片段是基于多头注意力对一个张量完成自注意力的计算, 张量的形状为(批量大小,时间步的数目或词元序列的长度, ),输出与输入的张量形状相同。
 
 

比较卷积神经网络、循环神经网络和自注意力

比较下面几个架构,目标都是将由 个词元组成的序列映射到另一个长度相等的序列,其中的每个输入词元或输出词元都由 维向量表示。顺序操作会妨碍并行计算,而任意的序列位置组合之间的路径越短,则能更轻松地学习序列中的远距离依赖关系。
notion image
考虑一个卷积核大小为 的卷积层。由于序列长度是 ,输入和输出的通道数量都是 , 所以卷积层的计算复杂度为 。卷积神经网络是分层的,因此为有 个顺序操作, 最大路径长度为 。 例如, 处于卷积核大小为3的双层卷积神经网络的感受野内。
当更新循环神经网络的隐状态时, 权重矩阵和 维隐状态的乘法计算复杂度为 。 由于序列长度为 ,因此循环神经网络层的计算复杂度为 。 根据上图所示, 有 个顺序操作无法并行化,最大路径长度也是
在自注意力中,查询、键和值都是 矩阵。 考虑缩放的”点-积“注意力, 其中 矩阵乘以 矩阵。 之后输出的 矩阵乘以 矩阵。 因此,自注意力具有 计算复杂性。 正如我们在图中看到的那样, 每个词元都通过自注意力直接连接到任何其他词元。 因此,有 个顺序操作可以并行计算, 最大路径长度也是
总而言之,卷积神经网络和自注意力都拥有并行计算的优势, 而且自注意力的最大路径长度最短。 但是因为其计算复杂度是关于序列长度的二次方,所以在很长的序列中计算会非常慢。
 

Self-attention for Image

notion image
notion image
 
那么用self-attention和用CNN处理图片有什么区别和联系呢?
notion image
如果我们用self-attention来处理图片,其中一个1产生query,用其他的像素产生key,那我们在做内积的时候,是考虑到整张图片的。但是如果我们是用卷积核,filter的话,就是我们只会考虑这里面的一部分信息,那么CNN就相当于是一种简化版的self-attention。 对于CNN来说,要划定感受野,它的范围的大小,是人为决定的。对于self-attention来说,它是机器自动学出来的。
这篇论文用数学关系严格的证明,CNN就是简化版的self-attention。self-attention只要设定一定的参数,可以做到和CNN一模一样的事情
notion image
 
 
把一张图片拆成16x16的patch,然后它就把每一个patch看成是一个word,(因为transformer一开始是用在NLP上面的),取了一个名字,叫做一张图价值16x16个文字。 横轴是训练的图片的量,10M就是一千万,比较了self-attention是浅蓝色这条线,CNN是深灰色这条线。随着资料量越来越多,self-attention的结果越来越好,但是在数据集小的时候,CNN的结果是要比self-attention要好的。
notion image
 
 
 
 
 
 
 

位置编码

notion image
在处理词元序列时,循环神经网络是逐个的重复地处理词元的, 而自注意力则因为并行计算而放弃了顺序操作。 没有考虑位置的信息,输入"A打了B"或者"B打了A"的效果是一样的。
为了使用序列的顺序信息,通过在输入表示中添加 位置编码(positional encoding)来注入绝对的或相对的位置信息。 每个位置设定一个专属的positional vector,用 表示,上标 代表位置。将 相加,然后再进行后续的计算就可以了。位置编码可以通过学习得到也可以直接固定得到。
 
为什么是 相加?
notion image
相加就等同于把原来的输入 concat一个表示位置的独热编码 ,再做transformation。
 
 
接下来描述的是基于正弦函数和余弦函数的固定位置编码
假设输入表示 包含一个序列中 个词元的 维嵌入表示。 位置编码使用相同形状的位置嵌入矩阵 输出 , 矩阵第 行、第 列和 列上的元素为:
乍一看,这种基于三角函数的设计看起来很奇怪。 在解释这个设计之前,先在下面的PositionalEncoding类中实现它。
 
在位置嵌入矩阵 中, 行代表词元在序列中的位置,列代表位置编码的不同维度。 在下面的例子中,我们可以看到位置嵌入矩阵的第 列和第 列的频率高于第 列和第 列。 第 列和第 列之间的偏移量(第 列和第 列相同)是由于正弦函数和余弦函数的交替。
notion image
 

绝对位置信息

为了明白沿着编码维度单调降低的频率与绝对位置信息的关系, 让我们打印出 二进制表示形式。 正如我们所看到的,每个数字、每两个数字和每四个数字上的比特值 在第一个最低位、第二个最低位和第三个最低位上分别交替。
在二进制表示中,较高比特位的交替频率低于较低比特位, 与下面的热图所示相似,只是位置编码通过使用三角函数在编码维度上降低频率。 由于输出是浮点数,因此此类连续表示比二进制表示法更节省空间。
notion image
 

相对位置信息

除了捕获绝对位置信息之外,上述的位置编码还允许模型学习得到输入序列中相对位置信息。 这是因为对于任何确定的位置偏移 ,位置 处 的位置编码可以线性投影位置 处的位置编码来表示。
这种投影的数学解释是,令 , 对于任何确定的位置偏移 ,任何一对 都可以线性投影到
投影矩阵不依赖于任何位置的索引
 
 
                                                                 图上是各种各样不同的位置向量
图上是各种各样不同的位置向量
 
 
  • PyTorch
  • 多头注意力Transformer
    目录