B-神经网络模型复杂度分析
- 链接了解更多。需要指出的是,现有很多硬件都将乘加运算作为一个单独的指令。
卷积层 FLOPs 计算
卷积操作本质上是个线性运算,假设卷积核大小相等且为 \(K\)。这里给出的公式写法是为了方便理解,大多数时候为了方便记忆,会写成比如 \(MACCs = H \times W \times K^2 \times C_i \times C_o\)。
- \(FLOPs=(2\times C_i\times K^2-1)\times H\times W\times C_o\)(不考虑bias)
- \(FLOPs=(2\times C_i\times K^2)\times H\times W\times C_o\)(考虑bias)
- \(MACCs=(C_i\times K^2)\times H\times W\times C_o\)(考虑bias)
\(C_i\) 为输入特征图通道数,\(K\) 为过卷积核尺寸,\(H,W,C_o\) 为输出特征图的高,宽和通道数。
二维卷积过程如下图所示:二维卷积是一个相当简单的操作:从卷积核开始,这是一个小的权值矩阵。这个卷积核在 2 维输入数据上「滑动」,对当前输入的部分元素进行矩阵乘法,然后将结果汇为单个输出像素。
公式解释,参考这里,如下:
理解
FLOPs的计算公式分两步。括号内是第一步,计算出output feature map的一个pixel,然后再乘以 \(H\times W\times C_o\),从而拓展到整个 output feature map。括号内的部分又可以分为两步:\((2\times C_i\times K^2-1)=(C_i\times K^2) + (C_i\times K^2-1)\)。第一项是乘法运算次数,第二项是加法运算次数,因为 \(n\) 个数相加,要加 \(n-1\)次,所以不考虑bias的情况下,会有一个 -1,如果考虑bias,刚好中和掉,括号内变为\((2\times C_i\times K^2)\)。所以卷积层的 \(FLOPs=(2\times C_{i}\times K^2-1)\times H\times W\times C_o\) (\(C_i\) 为输入特征图通道数,\(K\) 为过滤器尺寸,\(H, W, C_o\)为输出特征图的高,宽和通道数)。
全连接层的 FLOPs 计算
全连接层的 \(FLOPs = (2I ? 1)O\),\(I\) 是输入层的维度,\(O\) 是输出层的维度。
二,模型参数量分析
模型参数数量(params):指模型含有多少参数,直接决定模型的大小,也影响推断时对内存的占用量,单位通常为
M,GPU端通常参数用float32表示,所以模型大小是参数数量的4倍。这里考虑的卷积核长宽是相同的一般情况,都为K。模型参数量的分析是为了了解内存占用情况,内存带宽其实比
FLOPs更重要。目前的计算机结构下,单次内存访问比单次运算慢得多的多。对每一层网络,端侧设备需要:- 从主内存中读取输入向量 /
feature map; - 从主内存中读取权重并计算点积;
- 将输出向量或
feature map写回主内存。
MAes:memory accesse,内存访问次数。卷积层参数量
卷积层权重参数量 = $ C_i\times K^2\times C_o + C_o$。
\(C_i\) 为输入特征图通道数,\(K\) 为过滤器(卷积核)尺寸,\(C_o\) 为输出的特征图的
channel数(也是filter的数量),算式第二项是偏置项的参数量 。(一般不写偏置项,偏置项对总参数量的数量级的影响可以忽略不记,这里为了准确起见,把偏置项的参数量也考虑进来。)假设输入层矩阵维度是 96×96×3,第一层卷积层使用尺寸为 5×5、深度为 16 的过滤器(卷积核尺寸为 5×5、卷积核数量为 16),那么这层卷积层的参数个数为 5×5×3×16+16=1216个。
BN 层参数量
BN层参数量 = \(2\times C_i\)。其中 \(C_i\) 为输入的
channel数(BN层有两个需要学习的参数,平移因子和缩放因子)全连接层参数量
全连接层参数量 = \(T_i\times T_o + T_O\)。
\(T_i\) 为输入向量的长度, \(T_o\) 为输出向量的长度,公式的第二项为偏置项参数量。(目前全连接层已经逐渐被
Global Average Pooling层取代了。) 注意,全连接层的权重参数量(内存占用)远远大于卷积层。三,模型内存访问代价计算
MAC(memory access cost) 内存访问代价也叫内存使用量,指的是输入单个样本(一张图像),模型/卷积层完成一次前向传播所发生的内存交换总量,即模型的空间复杂度,单位是Byte。CNN网络中每个网络层MAC的计算分为读输入feature map大小(DDR读)、权重大小(DDR读)和写输出feature map大小(DDR写)三部分。卷积层 MAC 计算
以卷积层为例计算
MAC,可假设某个卷积层输入feature map大小是 (Cin, Hin, Win),输出feature map大小是 (Hout, Wout, Cout),卷积核是 (Cout, Cin, K, K),理论 MAC(理论 MAC 一般小于 实际 MAC)计算公式如下:# 端侧推理IN8量化后模型,单位一般为 1 byte input = Hin x Win x Cin # 输入 feature map 大小 output = Hout x Wout x Cout # 输出 feature map 大小 weights = K x K x Cin x Cout + bias # bias 是卷积层偏置 ddr_read = input + weights ddr_write = output MAC = ddr_read + ddr_writefeature map大小一般表示为 (N, C, H, W),MAC指标一般用在端侧模型推理中,端侧模型推理模式一般都是单帧图像进行推理,即N = 1(batch_size = 1),不同于模型训练时的batch_size大小一般大于 1。四,一些概念
双精度、单精度和半精度
CPU/GPU的浮点计算能力得区分不同精度的浮点数,分为双精度FP64、单精度FP32和半精度FP16。因为采用不同位数的浮点数的表达精度不一样,所以造成的计算误差也不一样,对于需要处理的数字范围大而且需要精确计算的科学计算来说,就要求采用双精度浮点数,而对于常见的多媒体和图形处理计算,32位的单精度浮点计算已经足够了,对于要求精度更低的机器学习等一些应用来说,半精度16位浮点数就可以甚至8位浮点数就已经够用了。
对于浮点计算来说,CPU可以同时支持不同精度的浮点运算,但在GPU里针对单精度和双精度就需要各自独立的计算单元。浮点计算能力
FLOPS:每秒浮点运算次数,每秒所执行的浮点运算次数,浮点运算包括了所有涉及小数的运算,比整数运算更费时间。下面几个是表示浮点运算能力的单位。我们一般常用TFLOPS(Tops)作为衡量NPU/GPU性能/算力的指标,比如海思3519AV100芯片的算力为1.7Tops神经网络运算性能。MFLOPS(megaFLOPS):等于每秒一佰万(=10^6)次的浮点运算。GFLOPS(gigaFLOPS):等于每秒拾亿(=10^9)次的浮点运算。TFLOPS(teraFLOPS):等于每秒万亿(=10^12)次的浮点运算。PFLOPS(petaFLOPS):等于每秒千万亿(=10^15)次的浮点运算。EFLOPS(exaFLOPS):等于每秒百亿亿(=10^18)次的浮点运算。
硬件利用率(Utilization)
在这种情况下,利用率(Utilization)是可以有效地用于实际工作负载的芯片的原始计算能力的百分比。深度学习和神经网络使用相对数量较少的计算原语(computational primitives),而这些数量很少的计算原语却占用了大部分计算时间。矩阵乘法(MM)和转置是基本操作。MM 由乘法累加(MAC)操作组成。OPs/s(每秒完成操作的数量)指标通过每秒可以完成多少个 MAC(每次乘法和累加各被认为是 1 个 operation,因此 MAC 实际上是 2 个 OP)得到。所以我们可以将利用率定义为实际使用的运算能力和原始运算能力的比值:
\[mac\ utilization = \frac {used\ Ops/s}{raw\ OPs/s} = \frac {FLOPs/time(s)}{Raw\_FLOPs}(Raw\_FLOPs = 1.7T\ at\ 3519) \]五,参考资料
- PRUNING CONVOLUTIONAL NEURAL NETWORKS FOR RESOURCE EFFICIENT INFERENCE
- 神经网络参数量的计算:以UNet为例
- How fast is my model?
- MobileNetV1 & MobileNetV2 简介
- 双精度,单精度和半精度
- AI硬件的Computational Capacity详解
- Roofline Model与深度学习模型的性能分析