CNN模型参数量和计算量详解

2023-05-20  本文已影响0人  西北小生_

一、参数量

参数量一般指可学习参数的数量,在CNN中主要有卷积层(Conv),批归一化层(BN),和全连接层(FC)含有可学习参数。

1. 卷积层参数量:
(1)普通卷积层的参数量:

\text{Param}(Conv)=\left \{ \begin{aligned} &C_o \times C_i \times K_w \times K_h + C_o, &\text{bias=True}, \\ &C_o \times C_i \times K_w \times K_h, &\text{bias=False} \end{aligned} \right.
其中C_o是输出通道数,C_i是输入通道数,K_w是卷积核的宽,K_h是卷积核的高。

(2)分组卷积的参数量:

\text{Param}(GConv)=\left \{ \begin{aligned} &C_o \times \frac{C_i}{g} \times K_w \times K_h + C_o, &\text{bias=True}, \\ &C_o \times \frac{C_i}{g} \times K_w \times K_h, &\text{bias=False} \end{aligned} \right.
其中g为分组数。分组卷积把输入分为g组,分别在组内进行卷积计算,参数量减少了g倍。

(3)深度分离卷积的参数量:

\text{Param}(DWConv)=\left \{ \begin{aligned} &C_i \times K_w \times K_h + C_i, &\text{bias=True}, \\ &C_i \times K_w \times K_h, &\text{bias=False} \end{aligned} \right.
深度分离卷积可视为分组卷积在g=C_i时的特殊情况。

【注意】如果Conv后面有BN层,则Conv计算不需要偏置,即 bias=False。
【解释】因为BN是线性计算,BN层已经有偏置,且两个偏置都是可学习参数,加在一起等效于一个偏置的作用:
Conv有偏差+BN:\gamma (Wx+b)+\beta=(\gamma W)x+(\gamma b+\beta)
Conv无偏差+BN:\gamma Wx+\beta=(\gamma W)x+\beta
【防杠】上面的推导只是一个简单的示意,实际计算有更多细节,不在本文讨论范围。

2. 批归一化层参数量:

\text{Param}(BN)=2C
BN层只有放缩因子\gamma和偏置\beta这两组可学习参数,这里的C是通道数。

3. 全连接层参数量:

\text{Param}(FC)=N_o \times N_i +N_o
其中N_o是输出神经元数量,N_i是输入神经元数量,第二项N_o是偏置b的。

二、计算量

当前相关论文中多使用浮点运算量(FLOPs)作为计算量的指标,FLOPs原本指乘法和加法的计算次数总和,即单次乘法和单次加法各算一次浮点运算。如:(a*b+c)浮点运算量是2,(a*b+c*d)的浮点运算量是3。

但在当前绝大多数深度学习论文中,FLOPs这一指标实际上计算的是“乘-加”数(MACs),即乘且加的数量。如:(a*b+c)的乘-加数是1,(a*b+c*d)的乘-加数是2。

本文将错就错,本文中的FLOPs计算的内容实际上就是MACs。

CNN中几乎所有层(除ReLU外)都存在FLOPs(有些论文中认为池化和BN没有FLOPs,因为它们不是标准的乘-加运算),下面给出几种常用模块的计算量公式。

另外,本文给出的计算量是模型推断阶段输入单张图片的计算量,如果要计算批量输入是的计算量,只需要在单张输入图像计算量的基础上\timesBatchSize即可。

1. 卷积层的FLOPs:
(1)普通卷积的FLOPs:

\text{FLOPs}(Conv)=C_o \times C_i \times K_w \times K_h \times W_o \times H_o
其中W_oH_o是该卷积层输出特征图的宽和高。方便起见,本文直接忽略偏差b的FLOPs,细究的话b的FLOPs为C_o \times W_o \times H_o,因为b被广播成尺寸为输出特征图大小后在每个输出激活值(浮点数)上进行了一次加法运算,相当于特殊的乘法和累加。忽略这一项对全局影响不大。

(2)分组卷积的FLOPs:

\text{FLOPs}(GConv)=C_o \times \frac{C_i}{g} \times K_w \times K_h \times W_o \times H_o

(3)深度分离卷积的FLOPs:

\text{FLOPs}(DWConv)=C_i \times K_w \times K_h \times W_o \times H_o
深度分离卷积可以视作分组卷积在g=C_iC_o=C_i时的特殊情况。

2. BN的FLOPs:

BN层的FLOPs一般只考虑推断阶段,训练阶段还涉及到归一化计算的运算量。当然,由于BN本身就是线性计算,可以和前面的卷积层合并(重参数化),忽略BN层的FLOPs是有一定合理性的。我们给出一个参考计算:
\text{FLOPs}(BN)=C\times W \times H \times 2
由于BN是对特征图上的所有激活值进行一次放缩和一次移位,两次操作都可以视为特殊的“乘-加”,所以要在特征图激活值总数上乘2。

3. 池化层的FLOPs:

\text{FLOPs}(Pool)=K_w \times K_h \times C_o \times W_o \times H_o
其中K_hK_w分别为池化窗口的高和宽。池化层输出特征图中的每个值都是由K_w \times K_h次浮点操作得到的。

4. ReLU层的FLOPs:

\text{FLOPs}(ReLU)=0
ReLU是对每个激活值的比较运算,不涉及浮点运算和乘加运算,故其没有浮点运算量。

5. 全连接层的FLOPs:

\text{FLOPs}(FC)=N_o \times N_i + N_o

以上便是几种CNN模型中常见模块的参数量和计算量公式,其它没有提及到的我将持续补充。

当然,手工计算这些数据的十分麻烦的,在下一篇文章里,我们将总结几种常用的计算模型参数量和计算量的库。并且将给出使用PyTorch从零实现计算这些数据的代码。

上一篇下一篇

猜你喜欢

热点阅读