学习笔记(深度学习)
参考课程: 李宏毅2021/2022春机器学习课程-
一、自注意力机制
应用场景:输入是很多大小不一的向量,并且不同向量向量之间有一定的关系,但是实际训练的时候无法充分发挥这些输入之间的关系而导致模型训练结果效果极差。比如机器翻译问题(序列to序列的问题,机器自己决定多少个标签),词性标注问题(一个向量对应一个标签),语义分析问题(多个向量对应一个标签)等文字处理问题
1.sequence to sequence模型:输入一句话做词性标注,输入一段语音识别为文字等
Each vector has a label.
2.输出长度为1(语句情感分析,语音识别)
The whole sequence has a label.
Self-Attention机制
传统的全连接神经网络无法考虑到上下文的关系,可以让FC可以考虑一个window,但是如果让一个window包括整个序列,但是这会让FC参数非常多,变得很复杂。
自注意力机制考虑一整个序列的上下文,进行特征提取,生成新的向量,再进行训练。这个向量b是考虑了所有的输入向量对a1产生的影响才得到的,这里有四个词向量a对应就会输出四个向量b
Dot-product得到相关参数α:两个向量作为输入,直接输出α,具体是输入的两个向量分别乘不同的矩阵,得到q,k,然后进行点乘即可得到α
计算出a1和每一个向量的关联性之后(包括自己)。再做一个softmax,也可以用别的函数,比如relu,这样就把相关程度归一化,通过数值就可以看出哪些向量是和a1最有关系
Wq和Wk为权重矩阵,需要学习来更新,用a1去和Wq相乘,得到一个向量q,然后使用a2和Wk相乘,得到一个数值k。最后使用q和k做点积,得到α。α也就是表示两个向量之间的相关联程度。得到α‘(1,1)这些之后,要根据α‘来抽取重要的信息,每一个向量乘以一个新的W(v)得到新的向量b1:
W(v):先求v,v就是键值value,v和q、k计算方式相同,也是用输入a乘以权重矩阵W,得到v后,与对应的α′ 相乘,每一个v乘与α’后求和,就可以得到输出b1。
如果 a1 和 a2 关联性比较高, α1,2′ 就比较大,那么,得到的输出 b1 就可能比较接近 v2 ,即attention score决定了该vector在结果中占的分量
以此类推可以得到b2/b3/b4,b1到b4不是依次产生的,是同时计算得到。
这一系列过程也可以通过矩阵相乘来表示:
其中,wq,wk,wv是模型需要学习的参数:
模型变形:Multi-head Self-attention,因为相关性有很多种不同的形式,有很多种不同的定义,所以有时不能只有一个q,要有多个q,不同的q负责不同种类的相关性
和上面一样,用a乘权重矩阵W得到qi,然后再用qi乘两个不同的W,得到两个不同的q^{i,n},i代表的是位置,有两个head,代表这个问题有两种不同的相关性,k和v也需要有多个,两个k、v的计算方式和q相同,都是先算出来ki和vi,然后再乘两个不同的权重矩阵
最后,把b{i,1},b{i,2}拼接成矩阵再乘权重矩阵W,得到b^i,也就是这个self- attention向量ai的输出
在训练self attention的时候,实际上对于位置的信息是缺失的,没有前后的区别,上面讲的a1,a2,a3不代表输入的顺序,只是指输入的向量数量,不像rnn,对于输入有明显的前后顺序,比如在翻译任务里面,对于“机器学习”,机器学习依次输入。而self-attention的输入是同时输入,输出也是同时产生然后输出的
Positional Encoding:在输入向量时一般加入一个位置特征的向量
Each position has a unique positional vector 𝑒,如果ai加上了ei,就会体现出位置的信息
其他应用场景与对比
也可以应用于图像处理,一个像素三个通道可视为一个向量输入
二、Transformer结构
Transformer结构处理问题的应用场景:Sequence-to-sequence (Seq2seq)模型
将这个模型整体看成是一个黑箱操作,输入一个序列,输出一个序列。
拆开这个黑箱,我们可以看到它是由编码组件、解码组件和它们之间的连接组成(transfomer是一个encoder-decoder模型)。其中,编码器将输入数据转化为了成了一个Feature Vector,然后再将这个Feature Vector输入至解码器解码并输出一段新的序列。编码组件部分由一堆编码器(encoder)构成,需要了解Encoder和Decoder的运行机制。
Encoder
Encoder:所有的编码器在结构上都是相同的,但它们没有共享参数。每个编码器都可以分解成两个子层,从编码器输入的句子首先会经过一个自注意力(self-attention)层。自注意力层的输出会传递到前馈(feed-forward)神经网络中
1:Input Embedding(词嵌入):将我们ID化的输入数据转化为One-Hot Representation,学习并更新出最佳的对应原始数据的词向量
2. Positional Encodding(位置编码):Transformer并不具备理解输入序列的顺序信息的能力,额外的将一些关于序列中元素的相对或绝对位置信息注入我们的词向量中。 为了这一目的, 我们在词嵌入模块后增加了一个层位置编码模块。该模块会生成一个与输入词向量相同尺寸的位置编码向量, 并将该位置向量直接与输入的词向量进行相加获得一个具备位置信息的词向量
3. Attention in Transformer:a. Self-Attention(自注意力机制). b. Multi-Head Attention(多头注意力机制)均可
4. 残差连接和Layer Normalization:
残差连接:ResNet
Y=X+H(X,W)
其中X 为输入数据, H 为神经网络的隐藏层,W 为隐藏层中可训练的参数
LayerNormalization的作用是把神经网络中隐藏层归一为标准正态分布,加快训练速度, 加速收敛
5. Feed Foward(非线性前向传播):对我们上一个Attention层(经过AddNorm)的输出进行其实就是两层线性映射并用在中间用一个非线性激活函数激活,完成了Feed Foward之后, 我们同样需要对其输出进行残差连接和Layer Normalization处理
Decoder
解码器整体结构以编码器基本一致。 唯一不同的其在Decoder Block中新增了一个Dec-Enc Multi-Head Attention模块。可称之为Cross Attention
计算Query时使用的输入则为同为Decoder的上一隐层的输出, 而计算Key和Value时使用的输入却是来自于Encoder的最后输出的,其他的部分(AddNorm,FeedFoward)都与Encoder Block一致
最后,当我们的数据经过了编码器与解码器之后, 我们需要对最终得输出进行一个线性变化,或者说pooling, 从而将每一个词向量对应得输出向量转换成一个长度为字典长度得向量, 然后在使用一个Softmax得到最终得输出。 得到这个输出后,我们就可以使用CrossEntropyLoss去计算损失,更新参数, 优化迭代模型了
三、各式各样的Attention
Attention矩阵的计算与序列长度N有关,当N比较大时,计算压力比较大。模型训练时间较长
所以为了简化Attention矩阵的计算,Attention结构有很多变形
Local Attention
对于Input Sequence,只考虑他周围左右的向量对他的影响因素,而序列中其他的序列对其影响尝试忽略不计,则对于的Attention矩阵,只需计算有颜色的部分,其余灰色,value置为0。
Stride Attention
与Local Attention类似,Stride Attention设置了一个步长,Local Attention是考虑了周围Vector的影响因素,Stride Attention则是考虑了步长距离的向量的影响因素,只计算影响向量的α值,矩阵其余value置为0。
Global Attention
Add special token into original sequence:设置或计算两个向量为全局Vector,可特殊指定,也可进行计算,special token特性:
1.Attend to every token → collect global information
2.Attended by every token → it knows global information
注:以上三种模型,可混合使用
Attention矩阵的计算思想:只关注重要的部分(value值较大,影响较大),对于small value,可以考虑Directly set to 0
Clustering
步骤1:通过聚类算法,对于sequence序列产生的query向量组和key向量组进行计算,对于不同的类型的向量进行打标签分类
步骤2:Attention矩阵部分,只计算同一类Vector的Attention值,不是同一类的直接置为0。
Sinkhorn Sorting Network
之前的几个Attention机制变种中,通过个人的主观意志,决定可以简化哪部分计算,跳过哪部分网格,来训练模型。而在Sinkhorn中,矩阵中那些网格被计算,哪些网格被跳过,也是可以通过神经网络学习出来的,即Input Sequence先去学习哪些网格需要被计算,再进行Attention机制的运算。
Representative key:Linformer
矩阵中存在很多冗余的key列,无需全部计算,可以选择出代表性的key,来简化计算过程:
选择出代表性的key Vector,也可以提取出序列的特征。常用方法包括:
可以采取卷积提取,或者d * N维的key Vector向量再去相乘一个N * K维的矩阵,来选出K个有代表性的向量。
Synthesizer
Do we need q and k to compute attention?
Synthesizer认为:Attention矩阵不一定要通过q和k来产生,也可以直接作为神经网络的参数