最近在学DETR,看源码的时候,发现自己对位置编码的理解很肤浅,只知道公式是这样的,但是深入的一些原理完全不懂。所以打算重新学习一下transformer相关的理论。然后推荐一个b站up: 去钓鱼的程序猿,和他的个人博客: 二十三岁的有德,他讲transformer讲的太好了。
这一节从头梳理一下Attention、Self-Attention、Muti-Head Self-Attention、Positional Encoding的原理。
人体视觉注意力:人眼的视野是比较开阔的,但是我们关注的焦点只有一个小范围,通常会更关注于更重要的区域,更感兴趣的区域;
注意力机制:让模型去关注在图片中的更重要的区域,忽略更不重要的区域;
不同角度理解注意力机制:
从概念角度:从大量信息中,有选择的筛选出少量重要信息,并聚焦到这些少量重要信息上,忽略大多不重要的信息。
从模型角度:通过Q去查询K当中哪些是比较重要的,得到相应的权重矩阵,再乘以V,让V去关注更重要的信息,忽略更不重要的信息。
从相似度角度:其实求取重要性的过程就是求取相似度的过程(相似度匹配),相似度越大说明重要性越高,越关注这部分。
如何做注意力:
一些需要注意的点:
Self-Attention 的关键点在于,Q、K、V是同一个东西,或者三者来源于同一个X,三者同源。
通过X找到X里面的关键点,从而更关注X的关键信息,忽略X的不重要信息。
Attention和Self-Attention的区别:
如何做自注意力:
3. 通过共享参数 W Q W_Q WQ、 W K W_K WK、 W V W_V WV和X运算得带Q、K、V;
4. 接下来和注意力机制一模一样;
如上是对Thinking Machines这句话进行自注意力的全过程,最终得到 z 1 z_1 z1和 z 2 z_2 z2两个新向量。其中 z 1 z_1 z1表示的是thinking这个词向量的新的向量表示(通过thinking这个词向量,去查询和thinking machine这句话里面每个单词和thinking之间的相似度),也就是说 z 1 z_1 z1这个新的向量表示其实还是thinking这个词向量表示,还是有联系的,只不过它还包含thinking machine这句话对thinking而言哪个词向量更重要/更相关的信息。
自注意力机制的意义?
如上图,如果不做自注意力机制,its词向量就是单纯的its词向量,没有任何附加信息。而做了自注意力信息,its就有了law和application这层意思,可以包含law的信息,挖掘潜在意思,翻译起来就更加准确。
总结:self-attention整个过程
Z本质上还是X向量,只不过包含了一些新的信息:包含X中每个向量和所有向量之间的相似度,让x1/x2…去关注更重要的词向量
Self-Attention和RNN、LSTM的比较
RNN
梯度消失:RNN梯度=近距离梯度+远距离梯度。而RNN远距离梯度可能会消失,导致梯度被近距离梯度主导。所以RNN无法做长序列,所以有长序列依赖问题。
无法并行,只能串行。
LSTM
通过引入门机制,来控制特征的流通和流失,解决RNN的长期依赖问题和梯度消失问题。
Self-Attention
解决长序列依赖问题:self-attention可以计算句子中每个词向量和所有词向量的相关性,再长的单词也没关系(一般50个左右的单词最好 因为太长的话计算量过大)。
解决并行问题:矩阵计算,可以同时计算所有单词和其他所有单词的相关性。
self-attention得到的新的词向量具有语法特征(如making -> more/difficult)和语义特征(如its -> law/application),对词向量的表征更完善。
缺点:计算量变大了。位置编码问题。
Multi-Head Self-Attention得到的新的词向量可以比Self-Attention得到的词向量有进一步提升。
什么是多头?(一般是使用8头)
源码:
为什么多头?有什么作用?
机器学习的本质:y = σ ( w x + b ) \sigma(wx+b) σ(wx+b),其实就是在做非线性变换。把数据x(它是不合理的),通过非线性变换,变成数据y(合理)。
非线性变换的本质:空间变换,改变空间上的位置坐标。
self-attention本质,通过非线性变换,把原始数据空间上的X点位置映射到新空间上的点Z上。
muti-head self-attention:把输入数据X,再把X通过非线性变换,映射到8个不同的子空间上,然后通过这8个不同的子空间去找最终的新空间上的点Z。这样可以捕捉更加丰富的特征信息,效果更好。
为什么需要位置编码?
之前提到,self-attention可以解决长序列依赖问题,并且可以并行。但是并行就意味着它是可以同时计算每个位置和其他位置的相关性的,也就是说词与词之间是不存在顺序关系的。所以如果打乱一句话,那么这句话里的词向量依然不变,即无位置关系。
总结:self-attention不像RNN那样有先后顺序,可以找到每个序列的位置,self-attention只是负责计算每个位置和其他位置的相关性。为了解决这个问题,就提出了位置编码。
位置编码的生成方式
1、正余弦生成
位置编码底层解释
前面我们知道位置编码其实就是让t1知道x1和x2,x1和x3的位置关系。从公式角度理解为什么?
sin(pos+k) = sin(pos)*cos(k) + cos(pos)*sin(k) # sin 表示的是偶数维度
cos(pos+k) = cos(pos)*cos(k) - sin(pos)*sin(k) # cos 表示的是奇数维度
这个公式告诉我们:位置pos + k 是 位置pos 和 位置k 的线性组合
即当我知道 位置pos+k 那内部就会暗含 位置pos 和 位置k 的信息
所以,此时即使打乱了词的位置关系,位置编码也会发生改变 这就解决了transformer的问题
2、自学习生成
这种方式比较简单,就直接随机初始化和x1一样shape的随机变量,然后训练网络的时候自动学习即可。
b站: 09 Transformer 之什么是注意力机制(Attention)
b站: 10 Transformer 之 Self-Attention(自注意力机制)
b站: 10 Attention 和 Self-Attention 的区别(还不能区分我就真的无能为力了)
b站: 11 Self-Attention 相比较 RNN 和 LSTM 的优缺点
b站: 13 Transformer的多头注意力,Multi-Head Self-Attention(从空间角度解释为什么做多头)
b站: 14 位置编码公式详细理解补充
b站: 14 Transformer之位置编码Positional Encoding (为什么 Self-Attention 需要位置编码)
b站: 躺懂Transformer !学不会来打我(doge)
个人网站: Transformer、GPT、BERT,预训练语言模型的前世今生(目录) _