ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Transformer计算量和过程统计

2022-02-11 11:05:57  阅读:266  来源: 互联网

标签:768 197 Attention 矩阵 Transformer 3072 64 计算 统计


整理一下Transformer相关论文的计算量和计算流程


一、Vision Transformer

在这里插入图片描述
Vision Transformer的结构在大佬 “太阳花的小绿豆” 的博文里面有明确的分析。这里我也是借由这篇博文来写的。
在这里插入图片描述
图片来源:太阳花的小绿豆-Vision Transformer详解


I. Patch Embedding层分析

输入输出

  1. 224 × 224 × 3 224 \times 224 \times 3 224×224×3
  2. 196 × 768 196 \times 768 196×768

运算

  1. Conv2d(卷积核大小 [ O , I , H , W ] → [ 768 , 3 , 16 , 16 ] [O, I, H, W] \rightarrow [768, 3, 16, 16] [O,I,H,W]→[768,3,16,16],步长是16)
  2. Flatten: [ 14 , 14 , 768 ] → [ 196 , 768 ] [14, 14, 768] \rightarrow [196,768] [14,14,768]→[196,768]

分析:

在原文中的计算量是主要是一个卷积层的计算量。这个卷积的主要作用就是,将输入图片下采样到 14 × 14 14\times 14 14×14,变成一个个小的patches, 再flatten之后就可以变成transformer的encoder层需要的输入了。


II. Concat & Position Embedding

Class token的插入:

Class token的维度是 1 × 768 1\times 768 1×768,并且是一个可训练的参数。在这里插入之后和Patch Embedding的输出拼接之后得到: C o n c a t ( [ 1 , 768 ] , [ 196 , 768 ] ) → [ 197 , 768 ] Concat([1, 768], [196,768]) \rightarrow [197,768] Concat([1,768],[196,768])→[197,768]

Position Embedding:

将每一个patch对应的position信息都要加入进来,所以是和Concat之后的维度是一样的,运算就是一个简单的加法,Position信息也是一个可训练的参数。

  1. 运算: A d d ( [ 197 , 768 ] , [ 197 , 768 ] ) → [ 197 , 768 ] Add([197, 768], [197,768]) \rightarrow [197,768] Add([197,768],[197,768])→[197,768]
  2. 维度: [ 197 , 768 ] [197,768] [197,768]

III. Transformer Encoder

请添加图片描述
Encoder Block里面的整体结构大致如上图所示,包含以下几个部分:

  • 第一个Residual结构里面有三个block和一个连线,分别是:
    • Layer Normalization
    • Multi-Head Attention
    • Dropout
  • 第二个Residual结构里面同样也有三个block和一个连线,分别是:
    • Layer Normalization
    • MLP Block
      • Linear
      • GELU
      • Dropout
      • Linear
      • Dropout
    • Dropout

下面分模块讲述。

A. 第一个 Layer Normalization

Layer Normalization的公式与Batch Normalization基本一致,即需要以下操作
在这里插入图片描述
但是不同的是,Batch Normalization是对一个batch内的所有feature map,取它们每个channel的均值和方差进行channel级别的标准化,而Layer Normalization是对一个feature map中某个或某几个维度进行标准化。

运算:

Layer Normalization因为标准化的维度与BN有明显的不同,所以这就导致了它无法像BN一样可以在训练过程中直接获得 r u n n i n g _ m e a n running\_mean running_mean和 r u n n i n g _ v a r running\_var running_var,从而上面公式中可以作为参数的仅仅只有 γ \gamma γ和 β \beta β。因此,具体的运算如下:

  • 求取该层的指定维度的期望: E [ x ] E[x] E[x]
  • 求取该层的指定维度的方差: V a r [ x ] Var[x] Var[x]
  • 根据已训练好的 γ \gamma γ和 β \beta β来运算标准化之后的结果

输入输出维度:

  • 输入: [ 197 , 768 ] [197,768] [197,768]
  • 输出: [ 197 , 768 ] [197,768] [197,768]

B. Multi-Head Attention

1. Self-Attention

在这里插入图片描述
(图片来源于太阳花的小绿豆

上图是非常基本的Self-Attention的运算流程。在上述运算中,可以看到最为重要的运算其实为两步:

  1. 得到 Q , K , V Q,K,V Q,K,V矩阵:即用输入值 a a a与对应的三个权重矩阵进行Matrix-Matrix Multiplication就可以得到三个矩阵。
  2. 计算Attention结果:即运算下面的公式,其中 S o f t m a x Softmax Softmax是对 Q K T / d k QK^T/\sqrt{d_k} QKT/dk​ ​这个结果矩阵的每一行进行运算的。
    A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk​ ​QKT​)V

2. Multi-Head Self-Attention

在这里插入图片描述
(图片来源于太阳花的小绿豆

Multi-head Self-Attention 顾名思义就是在Self-Attention基础上将其中的部分矩阵变成Multi-head的形式,来获得更好的效果,其基本运算与Self-Attention大致无异,主要是多了一步多head的concat以及一个矩阵矩阵乘法:

  1. 得到 Q , K , V Q,K,V Q,K,V矩阵:即用输入值 a a a与对应的三个权重矩阵进行Matrix-Matrix Multiplication就可以得到三个矩阵。(这一步与Self-Attention保持一致)
  2. 将得到的 Q , K , V Q,K,V Q,K,V矩阵按照头的数量进行均匀的按行分配:这一步按照上面的图的方式进行分开。原本原文中是需要乘以对应的 W i Q , W i K , W i V ) W_i^Q, W_i^K, W_i^V) WiQ​,WiK​,WiV​)来进行分开,但是实际操作大可不必
  3. 对分开的 Q i , K i , V i Q_i,K_i,V_i Qi​,Ki​,Vi​运算Self-Attention:这一步与上一节讲的Self-Attention运算基本一致。
  4. 将多头的Attention结果进行拼接,然后乘以 W O W^O WO:这一步就是图中的:
    M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , … , h e a d h ) W O MultiHead(Q,K,V) = Concat(head_1, \dots,head_h)W^O MultiHead(Q,K,V)=Concat(head1​,…,headh​)WO

3. ViT中的Multi-Head Self-Attention分析

原文中ViT-Base取得是12个head,那么下面就以12个head为例来分析一下维度问题。

按照前面几个图的计算流程,我推导出了下面的计算维度变化:

  1. 关键维度
    • d m o d e l = 768 d_{model} = 768 dmodel​=768
    • n u m h e a d = 12 num_{head} = 12 numhead​=12
    • d k = d m o d e l / n u m h e a d = 64 d_k = d_{model} / num_{head} = 64 dk​=dmodel​/numhead​=64
    • d k = 8 \sqrt{d_k} = 8 dk​ ​=8
  2. 输入: a → [ 197 , 768 ] a \rightarrow [197,768] a→[197,768]
  3. 计算 Q , K , V Q,K,V Q,K,V: Q = a × W q , K = a × W k , V = a × W v Q = a\times W^q, K=a\times W^k, V=a\times W^v Q=a×Wq,K=a×Wk,V=a×Wv
    • W q , Q k , W v → [ 768 , 768 ] W^q, Q^k, W^v \rightarrow [768,768] Wq,Qk,Wv→[768,768]
    • Q , K , V → [ 197 , 768 ] Q,K,V \rightarrow [197, 768] Q,K,V→[197,768]
  4. 多头均分: Q i = Q W i Q , K i = K W i K , V i = V W i V Q_i = Q W_i^Q, K_i = K W_i^K, V_i = V W_i^V Qi​=QWiQ​,Ki​=KWiK​,Vi​=VWiV​。这个操作其实是将 Q , K , V Q,K,V Q,K,V均分,在实际系统中的倒也可以不用乘以这三个均分矩阵。
    • W i Q , Q i K , W i V → [ 768 , 64 ] W_i^Q, Q_i^K, W_i^V \rightarrow [768,64] WiQ​,QiK​,WiV​→[768,64]
    • Q i , K i , V i → [ 197 , 64 ] Q_i,K_i,V_i \rightarrow [197, 64] Qi​,Ki​,Vi​→[197,64]
  5. Attention运算
    • Q i K i T = [ 197 , 64 ] × [ 64 , 197 ] → [ 197 , 197 ] Q_i K_i^T = [197,64] \times [64,197] \rightarrow [197,197] Qi​KiT​=[197,64]×[64,197]→[197,197]
    • s o f t m a x ( Q K T d k ) → [ 197 , 197 ] softmax(\frac{QK^T}{\sqrt{d_k}}) \rightarrow [197,197] softmax(dk​ ​QKT​)→[197,197]
    • h e a d i = s o f t m a x ( Q K T d k ) V = [ 197 , 197 ] × [ 197 , 64 ] → [ 197 , 64 ] head_i = softmax(\frac{QK^T}{\sqrt{d_k}}) V = [197,197] \times [197,64] \rightarrow [197,64] headi​=softmax(dk​ ​QKT​)V=[197,197]×[197,64]→[197,64]
  6. 多头MultiHead运算
    • C o n c a t ( h e a d 1 , … , h e a d n ) → [ 197 , 768 ] Concat(head_1,\dots, head_n) \rightarrow [197,768] Concat(head1​,…,headn​)→[197,768]
    • W O → [ 768 , 768 ] W^O \rightarrow [768,768] WO→[768,768]
    • M u l t i H e a d ( Q , K , V ) → [ 197 , 768 ] MultiHead(Q,K,V) \rightarrow [197,768] MultiHead(Q,K,V)→[197,768]

将计算流程梳理完之后可以总结一下这个Multi-Head Self-Attention所需要的运算量大致有哪些:

  • 2中的三个M2M
  • 4中Attention运算的M2M,Scaling操作,和按行的Softmax,加一个M2M
  • 6中在Concat结束之后的一个M2M

C. Dropout

这部分在前向传播中不需要额外运算

D. Residual的支线加

这里包含了一个 A d d ( [ 197 , 768 ] , [ 197 , 768 ] ) Add([197,768], [197,768]) Add([197,768],[197,768]) 矩阵矩阵按元素加法

E. 第二个Layer Normalization

运算与A中的运算基本一致,不需要赘述。

F. MLP Block

MLP Block的结构也如III节的第一个图所示,总共包含五层,下面依次讲解

1. 第一个Linear层

这个Linear层就是简单的全连接层,包含矩阵矩阵乘法和bias的加法。其中的维度变化是 [ 197 , 768 ] × [ 768 , 3072 ] → [ 197 , 3072 ] [197,768]\times [768, 3072] \rightarrow [197,3072] [197,768]×[768,3072]→[197,3072]

全连接层的参数矩阵大小是 [ 3072 , 768 ] [3072, 768] [3072,768]。

2. GELU(Gaussian Error Linear Units)

GELU是一个类似于ReLU的计划函数,但是本质上是在ReLU的基础上加入了Dropout的随机性。其数学表达式如下:
G E L U ( x ) = x P ( X ≤ x ) = x Φ ( x ) GELU(x) = xP(X \leq x ) = x \Phi(x) GELU(x)=xP(X≤x)=xΦ(x)
这里 Φ ( x ) \Phi(x) Φ(x) 是正态分布的概率函数。对于假设为标准正态分布的 G E L U ( x ) GELU(x) GELU(x),论文中提供了近似计算的数学公式,如下:
G E L U ( x ) = 0.5 x ( 1 + t a n h [ 2 / π ( x + 0.044715 x 3 ) ] ) GELU(x) = 0.5x (1 + tanh[\sqrt{2/\pi} (x + 0.044715x^3)]) GELU(x)=0.5x(1+tanh[2/π ​(x+0.044715x3)])
这里参考了 alwayschasing博主的博文。

在实际应用中,其实可以利用近似的公式来进行运算。

3. Dropout

在这里不做赘述

4. 第二个Linear层

这个Linear层就是简单的全连接层,包含矩阵矩阵乘法和bias的加法。其中的维度变化是 [ 197 , 3072 ] × [ 3072 , 768 ] → [ 197 , 768 ] [197,3072]\times [3072, 768] \rightarrow [197,768] [197,3072]×[3072,768]→[197,768]。这个全连接层的主要作用便是将前一个全连接层扩展的特征图维度恢复到初始维度,保证输出的时候可以直接提取结果。

全连接层的参数矩阵大小是 [ 768 , 3072 ] [768,3072 ] [768,3072]。

5. Dropout

在这里同样不做赘述。

G. Dropout

不做赘述

H. 第二个Residual Block的支线加

这里包含了一个 A d d ( [ 197 , 768 ] , [ 197 , 768 ] ) Add([197,768], [197,768]) Add([197,768],[197,768]) 矩阵矩阵按元素加法


IV. MLP Head

根据本文参考的博文的描述,在训练中这个MLP Head是由 Linear + tanh激活函数 + Linear组成,但是在实际运算中,其实可以只用一个Linear就可以。


V. Class

在经过MLP Head之后,取第0个位置的token作为分类的特征就可以得到最终的结果。

标签:768,197,Attention,矩阵,Transformer,3072,64,计算,统计
来源: https://blog.csdn.net/MicroE_Lv/article/details/122855331

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有