首页IT科技自注意力机制qkv(【学习】自注意力机制的改进方法、non-autoregressive sequence generation、point network)

自注意力机制qkv(【学习】自注意力机制的改进方法、non-autoregressive sequence generation、point network)

时间2025-08-05 17:27:46分类IT科技浏览5217
导读:一、如何让自注意机制更有效? 在自注意机制里面,我们输入一个序列,输出是另一个序列。输入序列之后我们可以得到一个query和一个key的向量序列,长度为分别都为N(跟输入序列长度相同)。那么在attention matrix里面,我们要做的就是把query和key进行点积,那这个运算的...

一                、如何让自注意机制更有效?

在自注意机制里面               ,我们输入一个序列                       ,输出是另一个序列                。输入序列之后我们可以得到一个query和一个key的向量序列        ,长度为分别都为N(跟输入序列长度相同)                       。那么在attention matrix里面               ,我们要做的就是把query和key进行点积                       ,那这个运算的就是NN级别的       。所以我们要想办法解决这个机制的运算量大的问题        。虽然self attention运算量可能会很惊人        ,但是我们的self attention毕竟是我们的神经网络中的一个小小的一部分(可能有很多个self attention还有别的结构组成)                       。

虽然self attention会对网络的计算量影响很大       ,但是也有可能被其他计算量更大的结构主导网络                       ,那么我们优化self attention计算就没有什么显著的优化               。那什么时候self attention主导网络的计算量呢?当self attention的N很大的时候                ,这样我们加快self attention 才会对神经网络有帮助        。我们经常把self attention应用在图像识别的时候                       。我们的一个图片如果N是256256       ,那我们的运算就会非常大!

1                       、local attention/truncated attention

在self attention里面                      ,我们最大的计算量就是要计算N*N的矩阵               。那我们可以怎么优化呢?也许我们不需要计算这个矩阵所有位置的数值                ,我们可以用人类知识填充!有些问题不需要看整个attention,可以只看前后的邻居。在self attention如果我们只看邻居                      ,那我们就能把很远的地方的值设为0.下图我们把灰色地方设为0                       ,因为那些地方没有必要参与运算                       。而蓝色的就需要计算啦                      。整个方法就是local attention或者truncated attention。但是这个local attention明显有问题,我们在做attention的时候只能看到小范围的数值               ,那这个就跟CNN很像啦!local attention是可以加快我们的attention的方法                       ,但是不一定能得到很好的结果                。下面这个local attention是寻找前后的邻居                      。

2       、stride attention

那么这个stride attention就是        ,取比较远的邻居!下图我们是空2格看的               ,或者是别的方式       。

3        、global attention

以上都是以某个位置为中心看左右的事情                       ,如果我们关心整个sequence        ,那么我们可以用global attention                。我们可以加入一个特殊token到原始的sequence里面                       。在这里       ,global attention会做两件事情:

(1)每个特殊的token都加入每一个token                       ,收集全局信息       。

(2)每个特殊的token都被其他所有的token加入                ,以用来获取全局信息        。

怎么实现呢?第一种       ,我们可以把原来的sequence里面的某些向量选做special token                       。另外一种就是外加额外的token               。如果要把外加token的矩阵attention matrix画出来                      ,每一个cow行代表query                ,每一个column列代表key        。下图中橘色两个横向的地方是有值的,都要计算attention                      ,他们是特殊的token                       ,要加入到所有的其他的key                       。那每一列的前两列也是有值的,他们也会加入到第一个和第二个位置               。从下图可以看出来               ,每一个不是特殊token的query都要加入特殊token。而对于灰色的地方                       ,他们没有值        ,互相之间就没有联系了!

以上我们讲了三张不同的选择               ,那哪一个好呢?我们都选择!对于不同的heads我们选择不同的attention                       。

big bird加入了random attention                      。

4                       、data driving

刚才我们说的方法是人为决定的                       ,哪里有值        ,哪里为0.那我们能不借助人       ,而使用数据驱动的方式吗?在一个self-attention里面的矩阵里面                       ,某些位置有很大的值                ,有些位置又有很小的值       ,那我们就把很小的值变为0                      ,这个可能对我们的结果没有什么影响。那我们是否能估计矩阵哪里有大值                ,哪里有小值吗?

clustering

在reformer和routing transformer两篇文章里面,都用了一个方法——clustering                。

步骤一:我们先把query和key取出来                      ,然后根据query和key的相近程度做clustering                      。对于相近的数据就放在一起                       ,对于比较远的数据就属于不同的cluster       。下面我们有四个cluster,用不同的颜色来标出                。这里可能有个问题               ,我们在做cluster的时候可能会出现运算量大的问题!其实事实上我们的cluster还是有很多快速的方法的                       。

对于query和key形成的attention matrix来说                       ,只有当query和key的cluster是一样的时候        ,我们才计算他们的attention weight       。对于不属于同一个cluster的两个query和key               ,就把他们设为0        。这种方法可以加速我们的运算                       ,这是一种基于数据来决定的!

learnable patterns of sinkhorn sorting network

那有没有方法可以让我们再次改变上面的想法        ,让我们的矩阵是学习出来的呢?下面的方法就是由sinkhorn sorting network学习出来的                       。在sinkhorn sorting network里面       ,直接学习另外一个network来决定怎么输出这个矩阵               。

我们把输入的序列                       ,经过一个NN之后产生另外一排向量序列                ,生成的矩阵就是NN的        。我们要把这个生成的不是二进制的矩阵变成我们的attention matrix                       。这个过程是可以微分的       ,所以是可以在NN里面训练出来的               。

其实我们可以直接输出这个attention matrix                      ,不用经过非二进制矩阵转换为二进制!

但是其实还有个问题                ,就是用另外一个网络生成矩阵真的比我们直接算attention matrix快吗?仔细想想,好像两个没有什么区别吧。事实上                      ,在sinkhorn sorting network里面                       ,有好几个输入的向量会共用一个经过NN产生的向量                       。也就是时候有向量复用啦!

又有另一个问题,我们真的需要一个NN的full attention matrix吗?在一片linformer的文章里面提到               ,在一个attention matrix里会有很多冗余的列                       ,很多列都是重复的        ,这个矩阵是low rank的               ,很多列是依赖其他列的                      。那我们能不能去掉重复                       ,产生小的attention matrix        ,加快attention的速度呢?

怎么做呢?我们有N个key       ,选择K个代表的key。然后与N各query产生一个矩阵                       ,那我们怎么用这个长方形的矩阵产生self -attention layer 的输出呢?我们有N个value                ,也选择K个代表value                。然后我们把这K个value和attention matrix做weight sum加权和       ,就得到输出                      。我们我们要选择代表key                      ,而不选择代表value呢? 但是我们不能改变query呀!因为我们的输出长度可能就会变短了!如果不是输入一个序列输出一个label那就不要这样做了!

减少key的数量

怎么选择代表性的key呢?在一个文章compressed attention里面提到                ,我们输入一个很长的key序列,我们用CNN来扫过                      ,key序列的长度就变短了                       ,那这个就是代表性的key       。在另一个文章linformer里面提到,输入的key序列可以看成是dN的矩阵               ,我们可以把这个key序列乘上一个NK的矩阵                       ,然后就得到了d*K的矩阵                。那这个得到的新矩阵就是代表性key序列        ,这个方法其实是N个key序列的线性组合                       。

注意机制attention mechanism

回顾               ,其实attention的整个过程                       ,其实就是矩阵相乘        ,那我们是否能进行优化呢?

我的输入是一个矩阵I       ,I乘上一个linear transformer Wq得到另外一个矩阵Q(dN)       。然后再做以下的运算:

Q和K的维度d要一样                       ,因为要做点积        。但是V可以不为dN                       。有没有办法加速这个运算呢?

假设我们没有做softmax这个步骤                ,那A=A’       ,O=VKTQ               。

我们可以这样进行优化:是否V和K跟K和Q相乘的运算是差不多的呢?不是的        。

事实上                      ,这两种情况的相乘结果是一样的                ,但是运算量是不一样的!

KT和Q相乘的乘法次数需要NdN次,得到A(attention matrix)                       。V*A的乘法次数是d‘’NN                      ,那总的计算次数就是(d+d’)N^2.

但是我们交换了乘法顺序之后呢?乘法次数只要2dd’N!那上面的计算就会比下面的计算大很多呀               。

如果加上softmax呢?这个原来的计算过程

实际上这个过程是可以简化的!我们有φ的方法:把指数expornatial的矩阵运算变成φ的点积。

然后我们发现                       ,在分母的地方没有出现i,那就能把i提到上面!

然后看分母               ,发现q跟j也没有关系                       ,也可以提出来        ,只求k求和!

看分子               ,我们展开之后                       ,把q相同的项相乘

可以看出来        ,括号里的式子可以看出是一个向量v的权重和                       。那有几个v向量呢?由有几个q决定!

我们再来看看       ,事实上b跟只涉及q这个矩阵                       ,而其他矩阵相乘只需要计算一次!

也就是说我们的每个输入只用分别计算q                ,而其他的不用重复计算啦!但是我们要选择适当的φ才能求得跟原来的网络相似的结果!

那怎么选择φ呢?以下有很多方法

synthesizer

我们真的必须要q和k去计算attention吗?不一定       ,可以用synthesizer                      。那我们的这个矩阵怎么出来呢                      ,可以直接吧attention matrix作为网络参数的一部分                ,而不是求出来的,这样的performance也没有很大的区别。

横轴是速度                      ,纵轴是分数                       ,圈圈大小是attention数目                。

二               、non-autoregressive sequence generation非自回归序列生成

conditional sequence generation条件序列生成

(1)输入语音序列(condition),输出中文序列(sequence modeling)                      。

(2)输入一张图               ,输出这张图的内容                       ,这是一个image caption generation       。

(3)输入一段英文        ,输出中文意思               ,这是一个machine translation                。

我们在翻译的时候一般都用autoregressive model                       。如果是RNN                       ,我们就是逐步输入和逐步输出的       。

在transformer里面        ,虽然是吧输入一次性输入到encoder里面       ,但是decoder还是要逐步输出(依赖前一个输出)        。

这样就会很浪费时间!

那我们能不能让他一次性输入和输出呢?non-autoregressive model                       。我们可以让encoder随意预测一个长度                       ,encoder输入就是放在position embedding               。

问题

在文字转图片的任务里面                ,模型学习到的是一个双头火车!这就很奇妙啦        。

实际上       ,我们的输出相互之间没有什么依赖                      ,我们希望输出第二个能看见第一个位置的值                       。另外                ,我们希望输出层中的每个神经元对应一个像素,而不是会出现两个一模一样的东西!

如果我们用GAN的方法就能实现这种依赖                      ,GAN(autoregressive model之一)是能让generator输出结构的方法               。在我们描述的时候                       ,可能不知道需要显示左边还是右边的火车(no latent variable),这个模型内部可能自己预测很大可能是左边的火车               ,但是因为没有随机的机制                       ,所以到了最后的一个隐藏层        ,我们得到的还是两个火车的叠加!为什么autoregressive model没有这个问题呢?因为autoregressive model会在每个时间点做一个sample的动作               ,他会挑选最大几率的一个                       ,抛弃其他的。不管GAN还是conditional GAN        ,我们在输入的时候都要输入一个噪声(normal distribution z)到G       ,让模型事先决定生成的方向                       。所以这两个方法就会避开上面的问题                      。

我们在翻译的时候                       ,想要将英文输出为中文                ,比如说       ,输入hello                      ,一般我们的输出会有很多种答复。那怎么确定输出哪一个呢?在autoregressive model里面会学习到                ,输入hello的时候,哈和你        、罗和好的几率差不多大                      ,那这样会不会组合错误呢?会!这种问题叫做multi-modality problem                。这是本文主要解决的问题                      。

假如我们想要从一个模型里面生成一张图片                       ,用最简单的方法,deconvolution layer +L2 loss               ,可能会生成模糊图片(生成的图片是很多图片的平均)       。对应在文字上的就是                       ,我们翻译的文字是各种可能的结果的叠加                。如果我们用autoregressive model就能生成很好的图片        ,对应到文字上就是我们需要一个个输出文字                       。除此之外GAN也能生成很好的图片       。在做GAN的时候               ,我们的结构可以用deconvolution layer +L2 loss                       ,而不用autoregressive model        ,结果也很好        。但是目前GAN没有用于文字                       。

对于文字翻译来说       ,我们希望用第一种简单的方法来实现               。在输入的地方                       ,我们对于每个encoder的输入向量都预测一个数字                ,对应到decoder的输出的对应位置        。在我们预测完成之后       ,就对输入进行复制到decoder的输入                      ,那么最后我们预测的数字总和就是我们的输出的长度                       。这种其实代表了我们的decoder对翻译的事先规划               。

1                       、fertility

我们要怎么训练呢?可以用一个外部的工具                ,对于输入我们预测输出有几个字。也可以直接训练一个autoregressive model观察attention weight是怎么分布的                       。从外部工具得到我们想要的fine-tune,目标不一样                      。我们在模型收敛之后会做fine-tune                      ,也就是用reinforce的loss加在fertility classifier上面。

2               、sequence-level knowledge distillation

knowledge distillation

如果我们想要训练一个小模型                       ,想要小模型的表现跟大模型一样好                。那就把小模型当做学生,大模型 作为老师                      。小模型在训练的时候               ,把输入给大模型                       ,让大模型预测出他预测的概率分布       。然后让小模型直接学这个概率分布        ,那小模型就会学的比较好                。这个是knowledge distillation在做的事情                       。

在sequence-level knowledge distillation里面               ,教师模型是autoregressive model                       ,学生模型是non-autoregressive model       。这里跟knowledge distillation不一样        ,学生模型不学习教师模型输出的概率分布        。而是让教师模型把corpus里面的每一句话用greedy decode的方式预测       ,然后让学生模型把输出的这个结果作为正确答案训练                       。为什么用non-autoregressive model解决刚才的multi-modality问题呢?multi-modality problem相互之间没有依赖                       ,错误记录很大               。如果数据集事先给了autoregressive model做decode的话                ,那概率分布就会不一样       ,就避免了模型的错误!

(3)noisy parallel decoding(NPD)

我们在训练好了non-autoregressive model之后                      ,我们的decoder是可以sample不同的数字的(1221)                ,那么就会输出不同的句子!然后这些句子交给教师打分(autoregressive model),选择最好的那个句子作为答案        。这里我们涉及了autoregressive model                      ,有没有可能运算就变慢了?

其实如果让autoregressive model去计算已经出现的句子的概率                       ,只需要一个步骤就可以了!我们会用transformer decoder的方式,teacher focing               ,casual mask                       ,让左边的输入不能涉及右边的输入                       。这个不怎么需要耗费时间               。

在实验中        ,第一列En->De的意思是performance               ,可以看到是递增的;最后一列是速度                       ,基本上是递减的。

第一种方法是刚才说的        ,第二种iteration refinement是在生成了一句话的一部分之后作为输入到decoder里面       ,第三中insertion-based是:输入一个很差的句子到decoder里面                       ,然后在中间进行补足                ,这种方法没有限制句子应该输出多少个字       ,所以可以由机器自己决定                       。第三种方法                      ,比如说我们输入一个D                ,预测B和F,然后有三个字母之后又能预测ACEG                      。这种方法时间复杂度logN                      ,但是这种方法如果在输出一个错字的时候就不能修改了。而第二种方法能对我的输出进行修正                。所以就出现第四种方法                       ,可以让第三种方法出现错误的时候删除错字                      。

方法

1、iterative refinement

我们输入一个X,输出Y0               ,然后可以不断对Y进行修正                       ,最后得到最好的结果Y       。decoder可以加入噪声(用yt+1替换yt        ,或者把yt替换成一个随机的token               ,或者交换yt和yt+1)                       ,模型如下:

Mask-Predict

decoder输入的某些vector用mask token替代

怎么做呢?我们先预测6        ,然后生成6个mask到decoder里面       ,得出第一版本的翻译结果(bad)                。

我们把第一个输出放到输入里面                       ,判断刚才生成的字里面哪些概率比较低                ,把概率低的几个字换成mask token       ,然后再生成一次结果(better)                       。

这是每次要mask几个字的方程:刚开始mask的比较多

样例:黄色的字为几率低的                      ,t=2的时候就能得到正确答案了!

这个方法比前面的好很多!

2                       、iterative refinement

我们有生成到一半的不成型的句子                ,输入有几个输出就几个       。我们把输出的相邻两个相邻相接,两个字中间就有一个recreation        。

我们用recreation来预测要插入的字                      ,如果没有要插入的字                       ,就是end                       。如果预测了字,那就插入输入的句子里               。

训练

加入我们的数据集里面有十个字               ,然后做shuffled打乱顺序        。选择任意的数字                       ,删除那些任意位置的字        ,然后把原来的句子还原                       。

如果删掉两个就算两个loss

uniform policy的策略是进行loss的取平均               ,但是我们有个更好的方法——平衡二叉树策略               。这个方法类似于下面这个字母的例子                       ,得到中间的更容易算出两边的。所以我们会让中间的mask的权重大一点                       。

KERMIT

混合encoder和decoder

这种模型可以中英混合翻译

同时训练五个任务有什么好处呢?从下面看好像刚开始没有变好        ,还变糟糕了                      。但是训练了多个任务之后       ,performance突然变好。

KERMIT还可以做下面的zero-shot clonzeQA

3                      、insertion +delete=>levenshtein transformer

levenshtein distance algorithm

这是一个用法                       ,不过更好的处理是先删除后加入                。

imitation learning

我们有两种句子:需要被删除字的句子和需要加入字的句子                      。看见这个错误的句子                ,算法产生一个00100000       ,交给delete classifier去学习       。看见一个需要加入的句子                      ,算法就产生0200                ,交给insert classifier学习                。还有在包含占位符place holder(PLH)的句子里面,                      ,我们也能算出需要加入什么字                       ,然后交给token classifier学习                       。这样就能训练出levenshtein transformer       。

有效!

4、CTC

输出可以去掉空格,去掉重复               ,得到一个句子        。CTC经常用于语音识别                       。我们很少遇到上面出现很多结果的问题                       ,因为一段语音是有正确答案的!缺点:LAS更优;不能做refined        ,结果文字不能做decoder的输入               ,也就是输出不能修正               。

改良:inputer(CTC+mask-predict)

在输入的地方同时加入token sequence                       ,在t=0的时候        ,token sequence全是mask sequence        。

我们限制在每个时间点都把token换成字       ,block size=3                       ,那三步之内一定可以decoder一个完整的句子!

明显改善错误率                       。

这个imputer也可以放在文字翻译里面:把每个feature分裂成多个feature                ,类似于语音信号               。

CTC居然能胜过之前的所有的模型!

这个方法很强!

下面是三种语言互相翻译:

AT的方法好像不是很能翻译出       ,在一句话更多是同种语言为多。NAT会分辨出一句话三种语言的区别                       。

三                、pointer network

问题的原始描述是有一堆的点                      ,要找出最外围的点                ,使得这些点连起来,能够包围所有的点                      。

我们用NN来解决:输入一大堆数据                      ,经过NN之后                       ,得到一组数据,这些数据就是这些外围点的下标。

好像可以用seq2seq解决!如果就用这种直接训练               ,好像跑不起来                。因为我们在输出的时候选择限制了                       ,如下图        ,限制输出{1,2,3,4,end}               ,那当我扩大了数据了?就选不了别的数字啦!

我们可以做下面的调整:加入x0和y0代表end                      。采用之前的attention-based model                       ,这有个key z0        ,与每个输入的h产生attention weight

我们把z和h计算得到的结果作为distribution       ,然后做argmax                       ,输出最大的值的上标!输入有什么                ,decoder输出就可以选择什么       。

一直输出       ,知道end是作为最大的输出!

这种方法可以用来做总结summarization

声明:本站所有文章                      ,如无特殊说明或标注                ,均为本站原创发布                。任何个人或组织,在未征得本站同意时                      ,禁止复制                      、盗用       、采集                、发布本站内容到任何网站                       、书籍等各类媒体平台                       。如若本站内容侵犯了原著者的合法权益                       ,可联系我们进行处理       。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
win10系统小组件(如何永久关闭Win11系统小组件?永久关闭Win11系统小组件方法)