全连接层及其注意力attention的参数量和计算量分析

news/2024/7/19 10:25:28 标签: 人工智能, 神经网络, 计算量FLOPs, Transformer

🎀个人主页: https://zhangxiaoshu.blog.csdn.net
📢欢迎大家:关注🔍+点赞👍+评论📝+收藏⭐️,如有错误敬请指正!
💕未来很长,值得我们全力奔赴更美好的生活!

前言

上一篇文章中讲述了常见的卷积算子参数量和计算量的计算方法,主要包括普通卷积深度可分离卷积分组卷积,以及对自动计算模型参数量和计算量的工具库ptflops进行简单介绍。在用于计算机视觉任务的深度神经网络模型中,还有两种结构被经常使用,即liner层和使用Multi-Head Attention机制的Transformer,本篇文章对linerMulti-Head Attention以及其他常见结构的参数量和计算量进行分析,以及对自动计算模型参数量和计算量的工具库ptflops进行简单介绍。

有关卷积算子参数量和计算量的分析,可以参考之前写的这篇文章:深度神经网络算子参数量和计算量分析—卷积篇


文章目录

  • 前言
  • 1. Liner
    • (1) Params
    • (2) FLOPs
  • 2. Multi-Head Attention
    • (1) Params
    • (2) FLOPs
  • 3. 其他常见结构分析
    • (1) 激活层
    • (2) 池化层
    • (3) 归一化层
  • 4. ptflops
  • 总结


1. Liner

在这里插入图片描述
Liner层也叫神经网络全连接层(Fully Connected Layer),也称为密集层(Dense Layer),是神经网络中最常见的一种层类型之一。

如上图所示,全连接层的每个神经元都与前一层的所有神经元相连接,每个连接都有一个权重。这意味着全连接层中的每个神经元都接收来自前一层所有神经元的输入,并通过权重进行加权求和。然后,通过激活函数对这个加权和进行非线性变换,得到该神经元的输出。

全连接层的作用是将输入数据进行高维特征表示和转换。它可以学习输入数据的复杂非线性关系,并将这些特征传递给后续的层进行进一步处理。全连接层通常用于神经网络的中间层,可以有多个全连接层堆叠在一起,以构建更深层次的网络结构。

我们假设liner层的输入神经元个数 I I I输出神经元个数 O O O

(1) Params

对于liner层的参数量计算,从输出神经元的角度来看,每个输出神经元都有 I I I个输入神经元和它相连接,也就是说每一个输出神经元共有 I I I个权重,之后每一个输出神经元有一个输出,需要加一个偏置。故,对于每一个输出神经元来说,其参数量为:

P a r a m s 每一个输出神经元 = I + 1 Params_{每一个输出神经元}=I + 1 Params每一个输出神经元=I+1

共有 O O O个输出神经元,故liner层的总参数量

P a r a m s = ( I + 1 ) × O   I × O + O Params=(I + 1)\times O \\\ I \times O + O Params=(I+1)×O I×O+O

(2) FLOPs

对于liner层的计算量,我们同样从输出神经元的角度来看,每一个输出神经元都与前一层的所有神经元相连接,每个连接都有一个权重。即每个神经元都接收来自前一层所有神经元的输入,并通过权重进行加权求和后添加偏置后输出,因此,每一个输出神经元的计算量为

F L O P s 每一个输出神经元 = I + ( I − 1 ) + 1 FLOPs_{每一个输出神经元}=I + (I - 1) + 1 FLOPs每一个输出神经元=I+(I1)+1

其中, I I I是每一个输出神经元和来自前一层所有神经元的输入进行加权求和所需要的乘法次数, I − 1 I-1 I1是每一个输出神经元和来自前一层所有神经元的输入进行加权求和所需要的加法次数, + 1 +1 +1是加偏置运算的加法次数(每一个输出特征像素需要一次加偏置操作)。

共有 O O O个输出神经元,故liner层的总计算量为

F L O P s = [ I + ( I − 1 ) + 1 ] × O   ( 2 × I ) × O FLOPs=[I + (I - 1) + 1] \times O \\\ (2 \times I)\times O FLOPs=[I+(I1)+1]×O (2×I)×O

2. Multi-Head Attention

在这里插入图片描述
多头注意力机制(Multi-head Attention)是一种在自注意力机制(Self-Attention)基础上的扩展,常用于序列建模任务,如机器翻译和语言生成。如今在计算机视觉任务上也表现优异,多头注意力机制通过并行地学习多个注意力头,可以同时关注不同的语义信息,从而提高模型的表示能力和泛化能力。Multi-Head Attention流程如上图所示,有关Multi-Head Attention的相关原理较为繁琐,这里不做详细介绍。

(1) Params

多头注意力机制的参数量主要取决于注意力头的数量、输入序列的维度和每个注意力头的维度。

假设输入序列的维度 d m o d e l d_{model} dmodel注意力头的数量 h h h每个注意力头的维度 d h e a d d_{head} dhead。在多头注意力机制中,每个注意力头都有自己的查询、键和值的权重矩阵,以及最后的线性变换权重矩阵。

查询、键和值的权重矩阵:每个注意力头都有一个查询权重矩阵 W q W_q Wq)、一个键权重矩阵 W k W_k Wk)和一个值权重矩阵 W v W_v Wv)。这些权重矩阵的形状分别为 ( d m o d e l d_{model} dmodel, d h e a d d_{head} dhead),因此每个注意力头的参数量为:

P a r a m s 每个注意力头 = 3 × d m o d e l × d h e a d Params_{每个注意力头}=3 \times d_{model}\times d_{head} Params每个注意力头=3×dmodel×dhead

共有 h h h个头,故,所有的注意力头的参数量为:

P a r a m s 每个注意力头 = 3 × d m o d e l × d h e a d × h Params_{每个注意力头}=3 \times d_{model}\times d_{head} \times h Params每个注意力头=3×dmodel×dhead×h

最后的线性变换权重矩阵:在多头注意力机制中,将多个注意力头的输出进行拼接或加权求和后,需要进行最后的线性变换。这个线性变换的权重矩阵的形状为 ( h × d h e a d h \times d_{head} h×dhead, d m o d e l d_{model} dmodel),因此最后的线性变换的参数量为

P a r a m s 线性变化 = h × d m o d e l × d h e a d Params_{线性变化}=h \times d_{model}\times d_{head} Params线性变化=h×dmodel×dhead

综上所述,多头注意力机制的总参数量为:

P a r a m s 每个注意力头 = 3 × d m o d e l × d h e a d × h + h × d m o d e l × d h e a d Params_{每个注意力头}=3 \times d_{model}\times d_{head} \times h + h \times d_{model}\times d_{head} Params每个注意力头=3×dmodel×dhead×h+h×dmodel×dhead

多头注意力机制的参数量相对较大,特别是当注意力头的数量和维度较大时。为了减少参数量,可以通过减小注意力头的数量、降低输入序列的维度或使用一些参数共享的技术来进行优化。

(2) FLOPs

多头注意力机制的计算量主要取决于注意力头的数量输入序列的长度

同样假设输入序列的维度为 d m o d e l d_{model} dmodel,注意力头的数量为 h h h,每个注意力头的维度为 d h e a d d_{head} dhead

在多头注意力机制中,每个注意力头都需要进行注意力计算和加权求和操作。注意力计算的复杂度为:

O ( d m o d e l 2 × d h e a d ) O(d_{model}^2 \times d_{head} ) O(dmodel2×dhead)

其中 d m o d e l 2 d_{model}^2 dmodel2是由于需要计算每个位置与其他位置的注意力权重, d h e a d d_{head} dhead是每个位置的表示维度。

因此,对于 h h h个注意力头,注意力计算的总复杂度为:

O ( d m o d e l 2 × d h e a d × h ) O(d_{model}^2 \times d_{head} \times h) O(dmodel2×dhead×h)

在加权求和操作中,需要将注意力权重与线性变换后的表示进行加权求和。线性变换的复杂度为:

O ( d m o d e l × d h e a d × h ) O(d_{model} \times d_{head} \times h) O(dmodel×dhead×h)

其中 h h h是注意力头的数量, d m o d e l d_{model} dmodel是输入序列的长度, d h e a d d_{head} dhead是每个位置的表示维度。

综上所述,多头注意力机制的总计算量为:

O ( d m o d e l 2 × d h e a d × h ) + O ( d m o d e l × d h e a d × h ) O(d_{model}^2 \times d_{head} \times h)+O(d_{model} \times d_{head} \times h) O(dmodel2×dhead×h)+O(dmodel×dhead×h)

3. 其他常见结构分析

(1) 激活层

激活层的参数量和计算量取决于所使用的激活函数类型输入的维度

对于常见的激活函数(如ReLU、Sigmoid、Tanh等),它们通常没有可训练的参数,因此参数量为零,即

P a r a m s 激活层 = 0 Params_{激活层}=0 Params激活层=0

而计算量则取决于输入的维度激活函数的计算复杂度

以ReLU激活函数为例,它的计算复杂度与输入的维度成正比。对于每个输入元素,ReLU函数只需进行一次比较和一次乘法运算。因此,对于输入维度为 n n n的激活层,ReLU激活函数的计算量

O ( n ) O(n) O(n)

对于其他激活函数,如Sigmoid和Tanh,它们的计算复杂度也与输入的维度成正比,但相对于ReLU函数而言,它们的计算量会更大一些。激活层的参数量和计算量通常较小,相对于模型中的其他层(如卷积层或全连接层)来说,它们的参数量贡献较小。

(2) 池化层

池化层的参数量和计算量取决于池化操作的类型池化窗口的大小输入的维度

对于常见的池化操作(如最大池化和平均池化),它们通常没有可训练的参数,因此参数量为零,即

P a r a m s 池化层 = 0 Params_{池化层}=0 Params池化层=0

而计算量则取决于输入的维度池化窗口的大小池化操作的计算复杂度

以最大池化为例,它的计算复杂度与输入的维度和池化窗口的大小成正比。对于每个池化窗口,最大池化操作只需进行一次最大值的比较。因此,对于输入维度为 n n n的池化层和池化窗口大小为 k k k最大池化操作,计算量为:

O ( n × k ) O(n\times k) O(n×k)

对于平均池化,它的计算复杂度与最大池化类似,也与输入的维度和池化窗口的大小成正比。对于每个池化窗口,平均池化操作只需进行一次求和和除法运算。

因此,对于输入维度为 n 的池化层和池化窗口大小为 k 的平均池化操作,计算量为。

O ( n × k ) O(n\times k) O(n×k)

同样的,池化层的参数量和计算量通常较小,相对于模型中的其他层来说,它们的参数量贡献较小。
归一化层(Normalization Layer)的参数量和计算量取决于所使用的归一化方法和输入的维度。

(3) 归一化层

归一化层(Normalization Layer)的参数量和计算量取决于所使用的归一化方法和输入的维度。

批归一化(Batch Normalization)层归一化(Layer Normalization)是常用的归一化方法,用于加速深度神经网络的训练和提高模型的泛化能力。

批归一化是在每个批次的数据上进行归一化操作,它的主要思想是将每个特征通道的输入进行均值和方差的归一化,使得输入的分布更加稳定。

具体而言,批归一化通过以下步骤来实现:

  1. 对于每个批次的输入数据,计算该批次数据在每个特征通道上的均值和方差。
  2. 使用这些均值和方差来对该批次的数据进行归一化,即将每个特征通道的输入减去均值并除以方差。
  3. 引入可训练的缩放因子和偏移因子,用于恢复归一化后的数据的表示能力。

故,对于批归一化,每个特征通道的输入都有一个缩放因子和一个偏移因子,总的参数量为:

P a r a m s 批归一化 = 2 × 特征通道维数 Params_{批归一化}=2 \times 特征通道维数 Params批归一化=2×特征通道维数

层归一化是在每个样本的特征维度上进行归一化操作,它的主要思想是将每个样本的特征维度进行均值和方差的归一化,使得输入的分布更加稳定。

具体而言,层归一化通过以下步骤来实现:

  1. 对于每个样本的特征维度,计算该样本在所有特征维度上的均值和方差。
  2. 使用这些均值和方差来对该样本的特征维度进行归一化,即将每个特征维度的输入减去均值并除以方差。
  3. 引入可训练的缩放因子和偏移因子,用于恢复归一化后的数据的表示能力。

故,对于批归一化,每个样本的特征维度都有一个缩放因子和一个偏移因子,总的参数量为:

P a r a m s 层归一化 = 2 × 样本数 Params_{层归一化}=2 \times 样本数 Params层归一化=2×样本数

4. ptflops

ptflops 是一个自动计算模型参数量和计算量的库,可以通过pip/conda直接下载,即

pip install ptflops

速度过慢时可以使用-i参数指定源,即

pip install ptflops -i https://pypi.tuna.tsinghua.edu.cn/simple

使用举例:

import torch
from torchvision.models import resnet18
from ptflops import get_model_complexity_info
  
model = resnet50()
macs, params = get_model_complexity_info(model, (3, 224, 224), as_strings=True,print_per_layer_stat=True, verbose=True)
                                           
print("MACs=", str(macs / 1e9) + '{}'.format("G"))
print("MACs=", str(macs / 1e6) + '{}'.format("M"))

虽然它可以自己计算模型的参数量和计算量,但是对一些自定义的层或算子不支持,并且不支持带有批量的计算。

总结

以上就是深度神经网络模型中常见结构的计算量和参数量分析,以及自动计算模型参数量和计算量的工具库ptflops的简单使用。希望对你能有帮助,如有问题,欢迎指出🤗


http://www.niftyadmin.cn/n/5196429.html

相关文章

金蝶云星空和旺店通·旗舰奇门接口打通对接实战

金蝶云星空和旺店通旗舰奇门接口打通对接实战 数据源系统:金蝶云星空 金蝶K/3Cloud(金蝶云星空)是移动互联网时代的新型ERP,是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、体验”,旨在帮助企业…

UDS诊断入门

UDS定义的是诊断服务,属于应用层的内容,实现诊断通信的底层总线技术有很多,比如CAN,LIN,Ethernet,Flexray等,由于法规强制的OBD接口是CAN总线的,所以绝大多数场景中诊断都是基于CAN实…

uniapp小程序定位;解决调试可以,发布不行的问题

遇见这个问题;一般情况就两种 1、域名配置问题; 2、隐私协议问题 当然,如果你的微信小程序定位接口没开启;定位也会有问题; 第一种,小程序一般是腾讯地图;所以一般都会用https://apis.map.qq.co…

Python爬虫实战-批量爬取豆瓣电影排行信息

大家好,我是python222小锋老师。 近日锋哥又卷了一波Python实战课程-批量爬取豆瓣电影排行信息,主要是巩固下Python爬虫基础 视频版教程: Python爬虫实战-批量爬取豆瓣电影排行信息 视频教程_哔哩哔哩_bilibiliPython爬虫实战-批量爬取豆瓣…

电脑游戏录屏软件,记录游戏高光时刻

电脑游戏录制是游戏爱好者分享游戏乐趣、技巧和成就的绝佳方式,此时,一款好用的录屏软件就显得尤为重要。本文将为大家介绍三款电脑游戏录屏软件,通过对这三款软件的分步骤详细介绍,让大家更加了解它们的特点及使用方法。 电脑游戏…

C语言每日一题(34)链表的回文结构

牛客网 回文链表 题目描述 描述 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。 给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。 …

Redis:Java客户端

前言 "在当今大数据和高并发的应用场景下,对于数据缓存和高效访问的需求日益增长。而Redis作为一款高性能的内存数据库,以其快速的读写能力和丰富的数据结构成为众多应用的首选。与此同时,Java作为广泛应用于企业级开发的编程语言&…