本文主要介绍模型参数量的计算(params)和算法/模型复杂度的运算(浮点运算次数,FLOPs)。
1. 模型参数量
1.1. 卷积层参数量
卷积函数:nn.Conv2d(in_channels,out_channels,kernel_size,stride,bias)
bias=True,卷积函数的参数量:
out_channels*in_channels*kernel_size*kernel_size + out_channels
bias=False,卷积函数的参数量:
out_channels*in_channels*kernel_size*kernel_size
1.2. 数据归一化层参数量
数据归一化函数:
nn.BatchNorm2d(out_channels,momentum=0.1,affine=True,track_running_stats=True)
数据归一化函数共有两个模型参数:gamma和beta
每个通道共用1各gamma和beta
因此数据归一化参数量:
out_channels + out_channels
1.3. 激活层参数量
激活函数:nn.LeakReLU()
计算公式:
alpha是自己定的量,模型不更新参数alpha。
参数量:0
1.4. 全连接层参数量
全连接函数:nn.Linear(in_features,out_features,bias)
bias=True,参数量:
out_features*in_features + out_feature
bias=False,参数量:
out_features*in_features
2. FLOPs计算
FLOPs(floating point operations)是指浮点运算次数,通常用来评估一个计算机算法或者模型的计算复杂度。在机器学习中,FLOPs通常用来衡量神经网络的计算复杂度,因为神经网络的计算主要由矩阵乘法和卷积操作组成,而这些操作都可以转化为浮点运算次数的形式进行计算,计算每层FLOPs的原理是以输入向量和模型参数作为基准计算个数,所有点乘法和加法数量的总和。
2.1. 卷积层FLOPs
卷积函数:nn.Conv2d(in_channels,out_channels,kernel_size,stride,bias)
输入向量:N,in_channels,Hin,Win
输出向量:N,out_channels,Hout,Wout
bias=True,FLOPs:
N*(in_channels*kernel_size*kernel_size*out_channels*Hout*Wout*2)+N
bias=False,FlOPs:
N*(in_channels*kernel_size*kernel_size*out_channels*Hout*Wout*2-1)+N
卷积层计算FLOPs,可以不考虑偏置的影响。
2.2. 数据归一化FLOPs
数据归一化函数:
nn.BatchNorm2d(out_channels,momentum=0.1,affine=True,track_running_stats=True)
推理阶段,首先进行归一化:
均值和方差相对于输入向量是常数,因此对于每个通道C来说,共有一次减法和乘法,即2次运算。
FLOPS = N×H×W×2
然后计算当前数据的均值和方差:
均值运算包含了加法和乘法,每个通道C的计算量分别位N×H×W-1和1,即FLOPs = N×H×W
方差运算包含了减法、平方乘法和平均值,每个通道的计算量分别位N×H×W、N×H×W和N×H×W,即FLOPs = N×H×W×3
最后进行均值和方差的更新:
每个通道的计算量分别位N×H×W和N×H×W,即FLOPs=2×N×H×W
因此所有通道的计算量FLOPs=8×C×N×H×W
2.3. 激活层FLOPs
激活层没有模型参数,FLOPs=0。我的理解是非线性激活函数也是有乘法,由于参数为常数,因此不计入FLOPs。
2.4. 全连接层FLOPs
全连接函数:nn.Linear(in_features,out_features,bias)
bias=True,输出通道每个点的乘法和加法的次数分别为in_features和in_features-1+1,即FLOPs=2*in_features
因此所有样本和通道的FLOPs=N×out_features×2*in_features,其中N为Bs样本个数
同理bias=False,输出通道每个点的乘法和加法的次数分别为in_features和in_features-1,即FLOPs=2*in_features-1
FLOPs = N×out_features×(2*in_features-1)
一般不考虑偏置带来的影响。