Transformer超详细整理

  • 先普及一些NLP基本概念,也给自己提个醒。
  • tokenization指的是分词,分出来的每一个词语叫做token。文本向量化,转化成vector(一般不用one-hot,文本很多就完蛋了)
  • word-embedding:使用了浮点型的稠密矩阵表示token,根据词典大小,向量会使用不同的维度,可以是100,256,300等等。向量中每一个值是个超参数,初始的时候是随机生成的,之后会在训练的过程中进行学习而获得。能够比one-hot表示减少大量的空间。可以把文本转化成向量,句子也可以。一般来说会先用token使用数字表示,然后用数字转化成向量。
  • 要对各种x-transformer进行理解,首先要了解他们的祖师爷,原版transformer。transformer抛弃了CNN,RNN,成为了自立门户的新模型,广泛应用于NLP领域,在很多领域能够达到SOTA。

原版Transformer:

  • 每一个encoder和decoder的内部结构都是下面这张图片所展示的。要理解transformer,这两个重要的知识点一定不能放过。

-

  • encoder部分:

    • encoder包括前馈神经网络和self-attention部分。我们可以得到下面的流程箭头图:
    • input embedding->positional encoding->
    • for i in range(6): 因为transformer有6个encoder
      • self attention->layer normalization->FFN->layer normlization
        -
  • decoder部分:

    • decoder主要包括self-attention, encoder decoder attention, 加上FFN,可以得到下面的箭头流程图:
    • input embedding->positional encoding->
    • for i in range(6): 因为transformer有6个decoder
      • self attention->layer normalization->encoder decoder attention->layer normalization->FFN->layer normlization
  • 总体流程图可以从这幅图得到,从总体到局部,这样方便我们逐个击破:

-

Positional Encoding:

  • transformer并没有存储单词位置信息的方法,比如狗咬人和人咬狗它区分不出来,为了解决这个问题,在encoder和decoder层都加入了positional embedding。positional embedding是一个维度和embedding向量,如何得到这个独特的向量呢?虽然方法有很多,但是作者采用了周期函数对位置进行标定,函数如下图所示:
  • P E ( p o s , 2 i ) = sin ⁡ ( p o s / 1000 0 2 i / d model  ) P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s / 1000 0 2 i / d model  ) \begin{aligned} P E_{(p o s, 2 i)} &=\sin \left(p o s / 10000^{2 i / d_{\text {model }}}\right) \\ P E_{(p o s, 2 i+1)} &=\cos \left(p o s / 10000^{2 i / d_{\text {model }}}\right) \end{aligned} PE(pos,2i)PE(pos,2i+1)=sin(pos/100002i/dmodel )=cos(pos/100002i/dmodel )
  • i是指向量中每个值的index,pos表示当前输入embedding的位置。可以看出,在偶数位置,使用正弦编码,在奇数位置,使用余弦编码。最后把这个positional embedding和embedding相加(相当于特征融合),作为输入送入下一层。
  • 用周期性函数保证在一个周期之内,不同位置的权重不一样,这样方便计算。

self attention:

  • self attention是transformer的重中之重,为什么需要这个呢?比如对于一些比较明显的指代关系,人能够很快判断出来,但是机器就比较困难了。The animal didn’t cross the street because it was too tired,it指的是什么,机器就会迷糊了。但是self attention能够解决这个问题。

  • 首先,self-attention会计算出三个新的向量,在论文中,向量的维度是512维,我们把这三个向量分别称为Query、Key、Value,这三个向量是用embedding向量与一个矩阵相乘得到的结果,这些矩阵是随机初始化的,维度为(64,512)注意第二个维度需要和embedding的维度一样,其值在BP的过程中会一直进行更新,得到的这三个向量的维度是64。
    -

  • 这个是transformer中实现self attention所采用的方法:scaled dot-product attention。我们可以整理一下它的具体过程:

  • 计算self-attention的分数值,该分数值决定了当我们在某个位置encode一个词时,对输入句子的其他部分的关注程度。这个分数值的计算方法是Query与Key做点乘,以下图为例,首先我们需要针对Thinking这个词,计算出其他词对于该词的一个分数值,首先是针对于自己本身即q1·k1,然后是针对于第二个词即q1·k2。
    -

  • scale操作:要除以dk,需要除以根号d,这是为了防止接入softmax导致梯度消失。这个值一般是采用上文提到的矩阵的第一个维度(指输入句子的长度)的开方,当然也可以选择其他的值。

  • 下一步就是把Value和softmax得到的值进行相乘,并相加,得到的结果即是self-attetion在当前节点的值。

  • 总之,把queries和keys相乘再进行缩放,最后用softmax得到权重矩阵这个过程叫做scaled dot attention机制,把权重矩阵和Value矩阵相乘得到结果的整个过程叫做self attention。

Multi-Headed Attention:

  • 在计算注意力机制的时候,作者并不只初始化三个矩阵,而是初始化了8组数据,一共24组矩阵。最后得到的结果是8个Value矩阵。然后把这8个结果的矩阵contact起来,之后再乘以一个矩阵得到最后的value矩阵。多头机制是把整个大的矩阵给砍成8份,在论文里面说,因为每个头的维度都少了一些,所以,总体的计算开销和单头注意力机制(不缺维度)是一样的。但是学习到的东西更多了,来自不同的子空间,学习到更多能够提取不同信息的滤波器。

  • 这给我们留下了一个小的挑战,前馈神经网络没法输入 8 个矩阵呀,这该怎么办呢?所以我们需要一种方式,把 8 个矩阵降为 1 个,首先,我们把 8 个矩阵连在一起,这样会得到一个大的矩阵,再随机初始化一个矩阵和这个组合好的矩阵相乘,最后得到一个最终的矩阵。
    -

  • MultiHead ⁡ ( Q , K , V ) =  Concat  (  head  1 , … ,  head  h ) W O  where head  i =  Attention  ( Q W i Q , K W i K , V W i V ) \begin{aligned} \operatorname{MultiHead}(Q, K, V) &=\text { Concat }\left(\text { head }_{1}, \ldots, \text { head }_{h}\right) W^{O} \\ \text { where head }_{i} &=\text { Attention }\left(Q W_{i}^{Q}, K W_{i}^{K}, V W_{i}^{V}\right) \end{aligned} MultiHead(Q,K,V) where head i= Concat ( head 1,, head h)WO= Attention (QWiQ,KWiK,VWiV)

  • Where the projections are parameter matrices W i Q ∈ R d model  × d k , W i K ∈ R d model  × d k , W i V ∈ R d model  × d v W_{i}^{Q} \in \mathbb{R}^{d_{\text {model }} \times d_{k}}, W_{i}^{K} \in \mathbb{R}^{d_{\text {model }} \times d_{k}}, W_{i}^{V} \in \mathbb{R}^{d_{\text {model }} \times d_{v}} WiQRdmodel ×dk,WiKRdmodel ×dk,WiVRdmodel ×dv and W O ∈ R h d v × d model  W^{O} \in \mathbb{R}^{h d_{v} \times d_{\text {model }}} WORhdv×dmodel 

Layer Normalization:

  • 在transformer中,每一个子层(self-attetion,Feed Forward Neural Network)之后都会接一个残缺模块,并且有一个Layer normalization。LN是在每一个样本上计算均值和方差,而不是像BN一样在Batch上面计算均值和方差。
  • 这个就比较老生常谈了,就这样吧。

FFN:

  • 其实就是两个卷积层,或者是全连接层的叠加。注意维度,在论文中,W1是512 * 2048 W2 2048 * 512
  • FFN ⁡ ( x ) = max ⁡ ( 0 , x W 1 + b 1 ) W 2 + b 2 \operatorname{FFN}(x)=\max \left(0, x W_{1}+b_{1}\right) W_{2}+b_{2} FFN(x)=max(0,xW1+b1)W2+b2 上面的矩阵是随机初始化的。
  • 序列的长度都是一样的,相比与全连接层,FFN能够适应不同长度的序列输入。

Mask机制:

  • 在进行decoder的时候,有一些部分和encoder并不一样。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。其中,padding mask 在所有的 scaled dot-product attention 里面都需要用到,而 sequence mask 只有在 decoder 的 self-attention 里面用到。

  • Padding Mask:

    • 什么是 padding mask 呢?因为每个批次输入序列长度是不一样的也就是说,我们要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充 0。但是如果输入的序列太长,则是截取左边的内容,把多余的直接舍弃。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。
    • 具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!而我们的 padding mask 实际上是一个张量,每个值都是一个Boolean,值为 false 的地方就是我们要进行处理的地方。
  • Sequence Mask:

    • 它的出现是为了使得decoder不能够看见未来的信息,我们解码的输出只能依赖于解码之前的所有输出,而不能依赖解码时刻t之后的输出。然而,self Attention机制会让解码时刻t之后的输出泄露给网络,所以需要mask处理。
    • 那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的
    • 对于 decoder 的 self-attention,里面使用到的 scaled dot-product attention,同时需要padding mask 和 sequence mask 作为 attn_mask,具体实现就是两个mask相加作为attn_mask。
    • 在encoder的时候,Attention_mask就是padding mask
  • 当decoder层全部执行完毕后,怎么把得到的向量映射为我们需要的词呢,很简单,只需要在结尾再添加一个全连接层和softmax层,假如我们的词典是1w个词,那最终softmax会输入1w个词的概率,概率值最大的对应的词就是我们最终的结果。

  • Transformer为什么需要进行Multi-head Attention

    • 原论文中说到进行Multi-head Attention的原因是将模型分为多个头,形成多个子空间,可以让模型去关注不同方面的信息,最后再将各个方面的信息综合起来。其实直观上也可以想到,如果自己设计这样的一个模型,必然也不会只做一次attention,多次attention综合的结果至少能够起到增强模型的作用,也可以类比CNN中同时使用多个卷积核的作用,直观上讲,多头的注意力有助于网络捕捉到更丰富的特征/信息
  • Transformer相比于RNN/LSTM,有什么优势?为什么?

    • RNN系列的模型,并行计算能力很差。RNN并行计算的问题就出在这里,因为 T 时刻的计算依赖 T-1 时刻的隐层计算结果,而 T-1 时刻的计算依赖 T-2 时刻的隐层计算结果,如此下去就形成了所谓的序列依赖关系。总之RNN没法进行并行运算,而transformer可以
    • Transformer优点:transformer不但对seq2seq模型这两点缺点有了实质性的改进(多头交互式attention模块),而且还引入了self-attention模块,让源序列和目标序列首先“自关联”起来,这样的话,源序列和目标序列自身的embedding表示所蕴含的信息更加丰富,而且后续的FFN层也增强了模型的表达能力,并且Transformer并行计算的能力是远远超过seq2seq系列的模型,因此我认为这是transformer优于seq2seq模型的地方。
  • 计算量对比:

    • transformer用了6层encoder和6层decoder。self-attention要比较当前词语和其他所有词语的相似度,所以是n方。self-Attention比卷积计算量还少一些。
      - [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QCo6ad74-1624964167513)(Transformer综述整理.assets/image-20210629150815649.png)]

    • 复杂性。self-attention的复杂度是 O ( n 2 ⋅ d ) O\left(n^{2} \cdot d\right) O(n2d) 。因此, 在处理长序列时Attention模块会成为瓶颈.n是序列长度,d是embedding向量的长度(一个句子用多长的vector代替,k是卷积的kernel size,r是size of neighborhood,或者说是隐层的维度也可以)

    • 至于restricted self attention怎么计算?不是每一个词和所有词计算attention,而是只是与r个词计算attention。在并行方面,多头attention不依赖于前一时刻的计算,可以很好地并行,比RNN好。在长距离依赖上,由于self attention是和所有词计算attention,所以不管他们中间有多长的距离,都可以捕获长距离依赖关系。

shortcut的应用:

  • 在transformer中,为了防止梯度消失,也是用了shortcut,在FFN和Muti-head attention都用了残差短接,在decoder里面增加了一个Masked multi-head attention,这个模块也加了短接。

transformer的使用:

  • encoder-decoder能够在sequence-to-sequence model使用
  • 单独的encoder结构能够在分类或者序列标注的时候使用
  • 单独的decoder可以用在序列生成,比如语言模型生成上。

在综述中,作者认为对attention的改进可以分为几个方向,我看着一脸懵逼:

  1. 稀疏注意力,将稀疏偏差引入attention机制,从而降低了复杂性
  2. 线性化注意力,这一系列工作将注意力矩阵与核特征图进行分解,然后以相反的顺序计算注意力来实现线性复杂度。我一点都看不懂,很像SVD?
  3. 原型和内存压缩。这类方法减少了查询或键值记忆对的数量,以减少注意力矩阵的大小。
  4. 低秩的自注意力。这一系列工作捕获了Self-attention的低秩属性。
  5. 先验注意力。该研究领域探索用先验的注意力分布来补充或替代标准注意力。
  6. 改进的多头机制。这一系列工作探索了多个不同的多头(Multi-head)机制。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Transformer模型中,token是指输入序列中的每个词语或图像中的每个图像块。在NLP中,每个单词被视为一个token,并且通常还有一个特殊的token称为CLS,用于标注句子的语义。在CV中,图像被切割成不重叠的patch序列,每个patch也被视为一个token。\[1\]\[3\] 在Transformer模型中,tokenization是指将文本或图像划分为不同的token。这些token可以是单词、图像块或其他形式的输入单元。\[1\] 在Transformer模型中,embedding层用于将token转化为向量表示。这些向量表示被称为word-embedding,它们使用浮点型的稠密矩阵表示token。每个token的向量表示具有不同的维度,可以是100、256、300等等。这些向量的值是参数,初始时是随机生成的,并在训练过程中进行学习。通过将文本或句子转化为向量表示,可以更好地表示和处理文本数据。\[1\] 在Transformer模型中,还有两个重要的概念是cls_token和Positional Encoding。cls_token是在输入序列的首位置添加的特殊token,用于对所有的token进行信息汇聚,以用于后续的分类任务。Positional Encoding用于为输入序列中的每个token添加位置信息,以帮助模型捕捉序列中的顺序关系。\[2\] 总结起来,Transformer模型中的token是指输入序列中的每个词语或图像中的每个图像块。它们经过tokenization分割,并通过embedding层转化为向量表示。在NLP中,还有一个特殊的token称为CLS,用于标注句子的语义。在CV中,图像被切割成不重叠的patch序列,每个patch也被视为一个token。同时,还有cls_token和Positional Encoding用于信息汇聚和位置编码。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [Transformer详细整理](https://blog.csdn.net/Sakura_day/article/details/118341728)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Transformer](https://blog.csdn.net/weixin_41677138/article/details/127137986)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [transform中的token理解(单词或词语的标记)](https://blog.csdn.net/weixin_43135178/article/details/118877976)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值