赞
踩
PPT链接:
self-attention:https://speech.ee.ntu.edu.tw/~hylee/ml/ml2021-course-data/self_v7.pdf
Transformer:https://speech.ee.ntu.edu.tw/~hylee/ml/ml2021-course-data/seq2seq_v9.pdf
输出的类型分为三种,一种是有输入输出一样多,又称为sequence labeling,例如词性标注;一种是有多个输入只有一个输出,例如情感分析;一种是有模型自己确认有几个输出,例如翻译,语音识别
使用self-attention是模型在训练时考虑到整个输入序列的信息
self-attention运作机制:self-attention会处理整个输入的序列,输入几个vector(最下方4个方格)同时就会输出几个vector(处理后带黑色边框的方格,此时新的vector是考虑整个序列信息得到的新vector),再把的到的新的vector输入到全连接神经网络,然后得到希望输出的东西,如此依赖全连接神经网络便是考虑了全局的信息,而不是部分或者某个窗口内的信息。self-attention可以用多次,即下发的网络结构
关于self-attention最出名文章即Attention is all you need,本篇文章中谷歌提出Tansformer架构,Tansformer中最重要的model即self-attention
self-attention运作方式
self-attention的输入是一串的vector,这些vector可能是整个网络的输入,也可能是某个隐藏层的输出,每个b向量都是考虑所有的a向量而生成的
如何产生b1向量:(其他同理)
第一步:找出这些序列中(a1-a4)跟a1相关的向量,每个向量跟a1的关联程度使用数值α表示
如何决定两个向量的相关性呢,以a1与a4举例,通常使用一个函数直接计算出两个对应的α,有多种方法:
法1(上图左):常见的方法是dot product(点积),两个向量分别乘以两个不同的矩阵(Wq,Wk),得到两个新的向量(q,k),再将q和k做点积便得到alpha。法2(上图右):在得到q与w后将两个向量串起来,通过激活函数,再通过一个转换得到α。后续讨论中均使用上图左方法
在self-attention中,a1与a2,a3,a4分布计算相关性,把a1乘以wq得到q1(q有个名字叫query),a2乘以wk得到k2(k称之为key),然后q1与q2做内积得到α1,2,α1,2称为a1与a2的attention score,a3与a4同理得到a1,3和a1,4,
通常在实操中a1也会跟自己算关联性得到α1,1,得到每个关联性后做一个softmax。操作方式:α做一个exp(α1,i),再除以 所有exp(α1,i)加和 做一个归一化(normalized),得到最终输出(α`1,i)。【不一定用softmax,也可以relu,其他的激活函数都行,可以多多尝试】
已经知道哪些向量和a1最相关,接下来要抽取相关的信息,抽取方式:将所有向量(a1-a4)乘以wv得到新的向量得到v1-v4,然后再将v1-v4分别乘以对应的α,然后再做一个加和。可以看到的是,对于关联性最高的向量,假设是a2,则得到的α也更大,最终结果b1也就更加多的包含v2的信息
以同样的方式得到b2,b3,b4,在计算b1,b2,b3,b4时可以并行进行,不用一个个挨个算。
b2的计算方式,与b1同理
以上是self-attention的运作过程,接下来从矩阵乘法的角度再讲一次self-attention是怎么运作的
a1到a4每一个都要产生对应的q,k,v
每一个a1-a4都要乘以Wq得到q1-q4,因此可以把a1-a4拼接起来得到一个矩阵 I ,矩阵I乘以Wq得到Q,Q的四个列向量(column)就是q1-q4,Wq是学习参数;同理算出4个k1-k4和v1-v4。总结来说就是将输入的矩阵乘以三个不同的矩阵得到Q、K、V
q1乘以由k1-k4组成的矩阵得到alpha1,1-alpha-1,4
同理得到q2-q4对应的分数
将A通过softmax得到A`
同理A`乘以V得到O
整体步骤:对于输入的矩阵I分别与Wq,Wk,Wv想乘得到矩阵Q、K、V,然后矩阵Q乘以矩阵K的转置得到矩阵A,矩阵A经过处理后得到矩阵A`,也称为Attention Matrix,
然后矩阵A`乘以矩阵V得到最终的矩阵O,矩阵O就是self-attention层的输出,对于self-attention层输入是I,输出是O,要学习的参数仅是Wq,Wk,Wv
Multi-head Self-attention?
Multi-head Self-attention 是self-attention的进阶版本,需要用多少head是超参数,为什么需要用多个head?在做self-attention时候就是用q找相关的k,但是相关可能有很多的形式和定义,所有也许需要多个q,不同的q负责不同的相关性。(以2 heads为例,认为有两种不同的相关性)
在a乘以矩阵得到q后,再让q乘以两个不同的矩阵得到qi,1和qi,2,q有两个那么k和v也各有两个
做self-attention就是1的一类一起做,忽略2的一类,2的一类一起做,有多个head也是一样的操作
然后再将bi,1与bi,2拼接起来乘以一个矩阵得到bi,将bi送入下一层
在上述做self-attention的过程中,对于一个self-attention层而言,没有每一个input所处句子的位置信息(句中,句首,句尾),每个词所做的操作都一样,对于系统而言没有任何区别,对self-attention来说,q1和q4的距离没有很远,q2与q3的距离也没有很近,所有位置之间的距离都是一样的,没有谁是在句首的,也没有谁是在句尾的,但是有时位置信息也很重要,比如说在做词性标记时,如果一个单词在句首,那很它是动词的概率就会很低,目前的的self-attention没有包含位置信息。如果觉得位置信息很重要,那么就可以将位置信息加入进去,方法就是Positional Encoding。
为每一个位置设定一个vector (ei,上标i表示位置),称为pisitional vector,不同的位置有专属的ei,把ei加上ai就结束了。在最先的self-attention is all you need论文中使用每个列代表每个ei,把第一个向量加到第一个a上,第二个向量加到第二个a上,依次类推,每个位置都有专属的e,通过给每个位置不同的e,模型在处理input时能够知道现在input的位置信息。问题在于这个positional vector是人为设置的有一些问题,例如当前设置的长度为128,但是输入的长度是129,在self-attention is all you need不存在这种问题,因为在该论文中位置长度是通过某种规则产生的(sin,cos),可以创造新的方法产生positional encoding
四种方式,目前还不知道哪种更好,可以创造自己的方法
self-attention在Transformer和BERT中都有应用,不止在文本,self-attention在语音中也有着广泛的应用
在做语音时需要对self-attention做一下小改动,因为如果要把一段语音信号表示成一个向量,这个向量可能会很长,在做语音识别时,要把声音信号表示成一排向量,一个向量只代表了10ms的长度,所以1s的声音信号就有100个向量,随便讲一句话就是上千个向量,过长的sequence会造成一些问题,在计算attention matrix时的复杂度是计算的长度的平方,要计算A`,需要做LL次的内积,L值很大需要计算的次数和内存都会很大,因此在self-attention时用到Truncated Self-attention来处理,在做self-attention时不看整句话,只看一个小范围就好,这样就可以加快运算速度
self-attention也可以运用在图像上
在前面的讲述中提到self-attention是输入为一排向量时适用的,在CNN中是把图片可做是一个很长的向量,一个图片可以通过把每个位置的像素看做一个三维的向量,上图就是一个510个向量,这时图片就成为了一个向量序列
上图中的工作就是把self-attention用在了出现处理上
比较CNN与self-attention的差异与关联,假设上方格处像素产生query,其他地方产生key,在做内积时,不是考虑小的范围的信息,而是考虑整张图像的信息
但是在做CNN是只考虑了小范围的信息,CNN因此可以看做小范围的self-attention
On the Relationship between Self-Attention and Convolutional Layers中用数学的方式证明了CNN就是self-attention的特例,CNN只要设置合适的参数可以做到self-attention同样的效果
随着训练数据的增多self-attention的效果优于CNN,self-attention和CNN也可以同时用
self-attention也可以用在图上面,在graph中,不仅有note的信息(每个note可以表示为一个向量),还有edge的信息,知道哪些note有关联,也就是知道哪些向量间有关联,在之前做attention时关联性是network自己找出的,现在有了graph和edge的信息,就不需要network自己找出,在计算attention Matrix时只需要计算有关联的note即可,没有关联直接设置为0即可,
Long Range Arena: A Benchmark for Efficient Transformers中总结了不同self-attention的变形,self-attention的问题在于计算量很大,怎么减少self-attention的计算量是一个重点,新的变形都称为**former。
各种nlp问题都可以看做QA问题,QA问题又可以用sequence to sequence模型来解决,解决方式:输入问题和文章,输出问题的答案,但是针对任务定制模型会有更好的效果。
sequence to sequence是一个很有用的模型,通常来讲他的一部分是Encoder,一部分是Decoder
Encoder要做的就是给一排向量输出另一排向量,这件事情很多模型都可以做到,例如self-attention,RNN,CNN。
在当前Encoder中会有很多block,每个block都会输入一排向量,输出一排向量,在Transformer的encoder里,每个block大概做的事情是:先根据input做一个self-attention,考虑整个sequence的信息,输出另一排向量,接下来会将这排向量丢入全连接网络,输出另一排向量,这排向量就是block的输出。
事实上在原来的Transformer里面,做的事情更复杂,self-attention后不只是输出a这个vector,而是把输入b直接和a(output)加起来得到新的output,这种架构叫做residual connection,这种应用已经很广泛,得到新的output后做一个normalization,使用的是layer Norm,layer Norm做的是输入一个向量输出一个向量,计算input的mean和standard deviation,做上图的操作后得出layer Norm的输出,这个输出才是全连接网络的输入,全连接网络这边也有residual架构,所以会把全连接网络的input和output加起来做residual得到新的输出,得到的输出需要再做一次layer Norm,得到的输出才是一个block的输出。
上图就是刚才讲的那件事情,在input处加上了位置信息positional Encoding,Multi-Head Attention就是self-attention block,add & Norm就是Residual + Layer norm,然后再下来就是全连接网络feed forward,再做一次Add & Norm。这个block在BERT里面也会用得到。
Decoder有两种,常见的是Autoregressive 一种是Non-autoregressive
(以语音识别为例)Decoder将Encoder的输出读入,然后首先要给输入多加一个特殊的符号代表开始(缩写是BOS),可以用独热编码表示该符号,接下来Decoder会输出一个向量,向量的长度与vocabulary size一样,vocabulary size与决定要输出的单位个数(假设要做的是中文语音识别,那么vocabulary size就可能是汉字的数目,常用的汉字个数可能有两三千个,不同语音单位不同,比如说应用单位可能是字母,或者单词),让Decoder输出哪些可能的汉字,让其列出来,每个字都会对应一个数值,这些值加起来为1,分数最高的字就是输出,此处为“机”字。
然后再将“机”字(独热编码表示)与BEGIN一同输入,之前是只输入BEGIN,得到新的输出
Decoder会把自己的输出当成自己的输入,所有在产生一个句子时有可能看到错误的东西,还是需要根据错误的输入产生正确的结果,但也有可能造成一步错步步错的结果
Transformer中Decoder的结构
比较Encoder与Decoder,发现把Decoder中间部分遮起来后,两者差别不大。Masked是什么呢?
这是原来的self-attention
Masked是产生b1时不能用a2,a3,a4的信息,产生b2时不能用a1,a2的信息,产生b3时只能考虑a1,a2,a3的信息,不能考虑a4的信息,产生a4时可以用整个序列的信息,这就是Masked self-attention
不考虑右边的地方。为什么使用Masked?
因为在Decoder时结果是一个个生成的,现有a1,再有a2,然后a3,a4,所有只能考虑左边的东西。
如何让模型知道要输出多少呢?在此例子中模型在输出“机器学习”后可能会将“机器学习”接着输入模型产生新的输出,无穷无尽。。。
所以要除了所有汉字外还以额外准备一个表示结束的END,在很多程序里BEGIN与END是用的同一个符号
期待将“机器学习”输入后模型会输出END表示结束
NAT:一次生成整个句子
蓝色的输入来自于Encoder,绿色的来自于Decoder
在原始文献中Decoder都是拿Encoder最后一层的输出,但是不一定需要这些,可以尝试不同的方式
与分类很像
希望所有cross entropy最小,记得要有END
有一个需要注意的事情,在训练时,会给Decoder输入正确的答案,这件事情就叫Teacher Forcing
训练sequence to sequence模型的Tips
在前面我们都要求Decoder自己产生输出,但是对于很多任务而言,也许Decoder没有必要自己创造输出,需要做的事是从输入的东西中复制一些过来,这些东西在一些场景可以用到,例如聊天机器人,比如在输入我是库洛洛时,模型可能不知道库洛洛这个词,但是如果此时能够直接将输入复制过来,效果就会比较好
或者在做摘要时,copy的能力更为重要
课外链接
对于答案明确的任务Beam Search就会有帮助,对于需要发挥创造力的Beam Search就不好
防止一步错步步错,就是给训练加入一些错误的东西
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。