【各式各样的Attention】李宏毅2021/2022春机器学习课程笔记EP13(P51)
从今天开始我将学习李宏毅教授的机器学习视频,下面是课程的连接(强推)李宏毅2021/2022春机器学习课程_哔哩哔哩_bilibili。一共有155个视频,争取都学习完成吧。
那么首先这门课程需要有一定的代码基础,简单学习一下Python的基本用法,还有里面的NumPy库等等的基本知识。再就是数学方面的基础啦,微积分、线性代数和概率论的基础都是听懂这门课必须的。
本节课紧接着EP11(【自注意力机制】李宏毅2021/2022春机器学习课程笔记EP11(P38-P39) – -TobyKSKGD的个人博客-),接着说的是各式各样Self-attention的变体。
Self-attention处理的就是输入是一排向量(Sequence)的情况。在之前的笔记里面说,这个Sequence和Sequence的计算量非常大,所以我们想要用各种办法去减小计算量。
这里先说,当输入的Sequence非常长(比如图片)的时候,整个Transformer里面最主要的运算就会来自于Self-attention。所以当输入的Sequence很长的时候,下面对于Self-attention的变形效果才会明显。
先来说其中的一种变形:Local Attention / Truncated Attention。
这是一个可以加快Self-attention的运算方法,但是不一定可以给到非常好的结果。
Local Attention的方法简单来说就是每个位置上只需要看它们自己左右邻居即可,要是中间隔了一个位置,此时对于这个位置来说,此处的权重就是0。然后我们看右边query和key的注意力矩阵就可以发现,蓝色部分是我们计算的注意力权重,然后旁边灰色的地方我们就不需要去计算。这种思想其实类似于CNN,只注意重要部分的思想。
第二种是和Local Attention差不多的Stride Attention。
Stride Attention的做法就是隔指定的位置看发生什么事情,Local Attention就是看邻居,现在这个Stride Attention就是隔几个位置看,其它没有什么不同。那隔几个位置可以由我们中间来决定,这个根据具体的问题决定Stride Attention应该要长什么样子。
第三种叫做Global Attention。
那Global Attention的做法是有一个special token(粉色部分),然后它会关注这个资料集并且它与所以token都有联系,除此之外,其它的token(灰色部分)相互之间都是没有往来的,如果它们想看资料集,就会通过与special token联系来查看。那这个special token一般会把它设置成一个句子的首部或者标点符号这样比较特殊的位置上,或者你可以从外面加几个token当作special token。
事实上,从实验结果来看,把前面讲的这三种方式全部结合起来得到的效果是最好的。你可以在Self-attention里用不同的head去做不同的事情,对应前面不同的attention。
下面这个Longformer实际上就是直接把Local attention、Stride Attention和Global attention全部结合起来的结果了。
后面的这个Big Bird实际上就是在Longformer把Local attention、Stride Attention和Global attention全部结合起来的基础上加上了一个Random Attention的结果。这个Random Attention的做法就是随机选token位置,让他们彼此关注。
然后我们在看注意力矩阵的时候,其实可以只关注重要的信息,然后把注意力矩阵里面那些attention weight数值小的部分直接当作0处理。这样就可以进一步减少计算量。
所以说我们应该如何去辨别token的大小?
接下去来介绍Clustering。
第一步就是对query和key的向量进行分类,我们的目的是想让相近的向量属于同一类。然后我们的目的是减少计算量,所以在这个地方我们不想去进一步增加计算量了,因此这里的分类只是估测,它的速度快但是结果不一定准,但是我们不care。
第二步就是只计算query和key归到同一类的权重,我们把其它没有归类的地方都统统设成0。
这样子我们就用Clustering进一步简化了计算量。
前面说的都是我们人去主动调整的方法,我们还可以让机器自己学出来哪些地方要不要计算权重。
它的做法主要就是再另外学习一个网络来决定哪些地方需要计算权重。最后我们再用一些特殊的方法,把用另外一个网络计算得到的Attention矩阵做处理,得到最终的二进制矩阵。
接着我们再来思考,我们是否真的需要一整个的attention矩阵呢?
其实是不用的,这里不需要整个的注意力矩阵就叫做:Linformer。
Linformer的做法是选择出有代表性的key,然后再挑出有代表性的value,然后用之前一样计算Self-attention输出的方法计算输出即可。如果你忘记了,这里再简单提一下,如下图,就是用选出来的K去乘上query,然后再乘上V也就是value,最后再全面加起来得到一个输出。
你也许会想,key可以选出代表性的去减少key的长度,那query可不可以呢?
减少query长度在有些问题上是无妨的,但是在一些实际的问题上会出现问题(因为会改变output的长度)。所以我们还是需要根据实际问题去考虑要不要改变query的长度。
紧接着上面的问题,我们要怎么找出有代表性的key呢?
这里有两个方法,一种是把key的Sequence平均分组喂给CNN,让CNN计算出重要的key。还有一种方法是Linformer中的做法,就是把key的Sequence做一个线性组合作为重要的key。
然后还有Self-attention本身计算的简化。
先来回忆一些Self-attention的计算方法。如果你忘记了,传送门贴在这里了:【自注意力机制】李宏毅2021/2022春机器学习课程笔记EP11(P38-P39) – -TobyKSKGD的个人博客-。
那回顾Self-attention的计算方法,我们会发现这里最主要的计算量就在O ≈ V K Q这里,假设说我们先拿掉softmax层的话。
然后是用线性代数的内容去解释,这里直接说结论了。一般我们做Self-attention的时候是先让K乘上Q,然后这样的做乘法的次数是(d + d’)N2次。如果我们先计算V乘上K,就会大大减少计算量,这次的乘法次数是2dd’N次。
这里改变计算顺序的实际操作方法是,先把k向量中同一维度的元素与向量v相乘再全部加起来(把这里得到的结果称为M vectors),然后再把Φ(q)里的每一个元素与M vectors做权相加,得到最终的输出。
然后这里Φ(q)的产生方式,不同的文献有不同的产生方式,这里不做阐述。
最后再来介绍Synthesizer,也就是我们不需要q和k去计算得到注意力矩阵。
Synthesizer里直接把注意力矩阵变成神经网络中的一部分,里面的权重就是神经网络中的参数。
你问,既然是神经网络中的参数,那input不同的Sequence,attention的weight都是一样的啊?
是的。
那这样子模型的表现会不会变差?
不会。
就是这样。
所以我们会对attention的意义产生思考,既然没有attention也一样,那我们是否可以像丢弃RNN那样丢弃attention?实际上这也是一种在研究的方向。
那以上就是对Self-attention变形的讲解了。下面是对这次讲解的变形做的summary。
以上就是对Self-attention变形讲解的笔记。