主要是针对于模型一次前向传播的Flops(浮点运算数)和Params(参数量)计算。
1.Flops(浮点运算数)
理解为模型的计算量,用来衡量算法/模型的复杂度。调用fvcore库的FlopCountAnalysis函数,函数的具体用法如下:
flops = FlopCountAnalysis(model, iuput)
一般传递的参数就两个,模型和输入。
卷积和全连接FLOPS 计算公式
FLOPS = ∑ i ( 2 × H out ( i ) × W out ( i ) × K 2 × C in ( i ) × C out ( i ) ) + ∑ j ( 2 × C in ( j ) × C out ( j ) ) \text{FLOPS} = \sum_{i}\left(2 \times \mathrm{H}_{\text{out}}^{(i)} \times \mathrm{W}_{\text{out}}^{(i)} \times \mathrm{K}^{2} \times \mathrm{C}_{\text{in}}^{(i)} \times \mathrm{C}_{\text{out}}^{(i)}\right) + \sum_{j}\left(2 \times \mathrm{C}_{\text{in}}^{(j)} \times \mathrm{C}_{\text{out}}^{(j)}\right) FLOPS=i∑(2×Hout(i)×Wout(i)×K2×Cin(i)×Cout(i))+j∑(2×Cin(j)×Cout(j))
解释:
1. 第一个求和:卷积层
∑ i ( 2 × H out ( i ) × W out ( i ) × K 2 × C in ( i ) × C out ( i ) ) \sum_{i}\left(2 \times \mathrm{H}_{\text{out}}^{(i)} \times \mathrm{W}_{\text{out}}^{(i)} \times \mathrm{K}^{2} \times \mathrm{C}_{\text{in}}^{(i)} \times \mathrm{C}_{\text{out}}^{(i)}\right) i∑(2×Hout(i)×Wout(i)×K2×Cin(i)×Cout(i))
- H out ( i ) \mathrm{H}_{\text{out}}^{(i)} Hout(i) :第 i i i 层输出特征图的高度。
- W out ( i ) \mathrm{W}_{\text{out}}^{(i)} Wout(i):第 i i i 层输出特征图的宽度。
- K K K:卷积核的大小(假设为正方形卷积核,即 K × K {{K} \times \text{K}} K×K)。
- C in ( i ) \mathrm{C}_{\text{in}}^{(i)} Cin(i):第 i i i 层的输入通道数。
- C out ( i ) \mathrm{C}_{\text{out}}^{(i)} Cout(i):第 i i i 层的输出通道数。
- 乘以 2 是因为卷积中的乘法和累加操作。
2. 第二个求和:全连接层
∑ j ( 2 × C in ( j ) × C out ( j ) ) \sum_{j}\left(2 \times \mathrm{C}_{\text{in}}^{(j)} \times \mathrm{C}_{\text{out}}^{(j)}\right) j∑(2×Cin(j)×Cout(j))
- C in ( j ) \mathrm{C}_{\text{in}}^{(j)} Cin(j):第 j j j 层的输入神经元数量。
- C out ( j ) \mathrm{C}_{\text{out}}^{(j)} Cout(j):第 j j j 层的输出神经元数量。
- 乘以 2 是因为全连接层中的乘法和累加操作。
总结:
- 第一个求和计算所有卷积层的 FLOPS。
- 第二个求和计算所有全连接层的 FLOPS。
- 总 FLOPS 是这两个数量的总和。
这个公式有助于估算神经网络的计算复杂度,特别是在典型的卷积神经网络模型中。在我的模型中我还使用了注意力部分。
3. 注意力机制FLOPS 计算公式
1. 计算 Q、K、V
对于每个输入的特征矩阵
X
X
X,计算查询、键和值矩阵的 FLOPS:
F
L
O
P
S
Q
K
V
=
3
×
2
×
N
×
C
×
H
\mathrm{FLOPS}_{Q K V} = 3 \times 2 \times N \times C \times H
FLOPSQKV=3×2×N×C×H
- 这里的 3 3 3 表示我们需要计算查询、键和值三个矩阵。
- 2 2 2 是因为每个乘法和加法都需要计算。
- N N N 是输入序列的长度(或 patch 数量)。
- C C C 是输入特征的维度(通道数)。
- H H H 是注意力头的数量。
2. 计算注意力分数
计算注意力分数矩阵的 FLOPS:
F L O P S a t t n s c o r e s = 2 × N × N × H \mathrm{FLOPS}_{{attn_scores}} = 2 \times N \times N \times H FLOPSattnscores=2×N×N×H
- 这里的 N × N N \times N N×N 是因为需要计算每个查询与所有键的点积。
- 2 2 2 是因为每个乘法和加法都需要计算。
3. 计算加权值
计算加权后的值的 FLOPS:
F
L
O
P
S
w
e
i
g
h
t
e
d
V
=
2
×
N
×
C
×
H
\mathrm{FLOPS}_{{weighted_V}} = 2 \times N \times C \times H
FLOPSweightedV=2×N×C×H
- 这里的 2 2 2 是因为每个乘法和加法都需要计算。
4. 综合计算
将上述部分综合,整个多头自注意力的 FLOPS 可以表示为:
F
L
O
P
S
a
t
t
e
n
t
i
o
n
=
F
L
O
P
S
Q
K
V
+
F
L
O
P
S
a
t
t
n
s
c
o
r
e
s
+
F
L
O
P
S
w
e
i
g
h
t
e
d
V
\mathrm{FLOPS}_{{attention}} = \mathrm{FLOPS}_{Q K V} +\mathrm{FLOPS}_{{attn_scores}} + \mathrm{FLOPS}_{{weighted_V}}
FLOPSattention=FLOPSQKV+FLOPSattnscores+FLOPSweightedV
5. 最终 FLOPS 公式
整合后,多头自注意力的 FLOPS 可以用以下公式表示:
F
L
O
P
S
attention
=
3
×
2
×
N
×
C
×
H
+
2
×
N
×
N
×
H
+
2
×
N
×
C
×
H
\mathrm{FLOPS}_{\text{attention}} = 3 \times 2 \times N \times C \times H + 2 \times N \times N \times H + 2 \times N \times C \times H
FLOPSattention=3×2×N×C×H+2×N×N×H+2×N×C×H
6. 简化
我们可以将上述公式进一步简化为:
F
L
O
P
S
attention
=
6
×
N
×
C
×
H
+
2
×
N
×
N
×
H
\mathrm{FLOPS}_{\text{attention}} = 6 \times N \times C \times H + 2 \times N \times N \times H
FLOPSattention=6×N×C×H+2×N×N×H
这就是多头自注意力机制的 FLOPS 计算公式。
Params(参数量)
Params(参数量)主要用来形容模型的大小程度,刻画模型的空间复杂度。模型参数量可以直接通过代码来计算。
n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)
1. 卷积层参数量计算公式
P a r a m s c o n v = ( K × K × C in + 1 ) × C out \mathrm{Params}_{conv}= (K \times K \times \mathrm{C}_{\text{in}} + 1)\times \mathrm{C}_{\text{out}} Paramsconv=(K×K×Cin+1)×Cout
公式解释:
- K K K:卷积核的大小(假设为正方形卷积核,即 K × K {{K} \times \text{K}} K×K)。
- C in \mathrm{C}_{\text{in}} Cin:输入通道数(输入特征的深度)。
- C out \mathrm{C}_{\text{out}} Cout:输出通道数(卷积层的输出特征的深度)。
- +1 是为了考虑每个输出通道的偏置(bias)参数。
2.全连接层参数量计算公式
P a r a m s f c = ( C i n × C o u t ) + C o u t \mathrm{Params}_{fc} = (\mathrm{C}_{in} \times \mathrm{C}_{out}) + \mathrm{C}_{out} Paramsfc=(Cin×Cout)+Cout
公式解释:
- C in \mathrm{C}_{\text{in}} Cin:输入特征数(输入神经元的数量)。
- C out \mathrm{C}_{\text{out}} Cout:输出特征数(输出神经元的数量)。
- C o u t \mathrm{C}_{out} Cout 是为了考虑每个输出神经元的偏置(bias)参数。
3.注意力机制参数量计算公式
1. Q、K、V 权重
对于每个输入特征矩阵
X
X
X,计算查询、键和值矩阵的权重:
P
a
r
a
m
s
Q
K
V
=
(
C
i
n
×
C
h
e
a
d
)
×
3
\mathrm{Params}_{QKV} = (\mathrm{C}_{in} \times \mathrm{C}_{head}) \times 3
ParamsQKV=(Cin×Chead)×3
- C in \mathrm{C}_{\text{in}} Cin:输入特征维度。
- C head \mathrm{C}_{\text{head}} Chead:每个头的特征维度(通常是 C i n / n u m _ h e a d s \mathrm{C}_{in} / num\_heads Cin/num_heads)。
2. 输出线性层(MLP)权重
如果有一个输出线性层,用于将多个头的输出合并:
P
a
r
a
m
s
o
u
t
=
C
h
e
a
d
×
n
u
m
_
h
e
a
d
s
×
C
o
u
t
\mathrm{Params}_{out} = \mathrm{C}_{head} \times num\_heads \times \mathrm{C}_{out}
Paramsout=Chead×num_heads×Cout
- C out \mathrm{C}_{\text{out}} Cout:最终输出特征维度。
综合计算
整个多头自注意力的参数量可以表示为:
P
a
r
a
m
s
a
t
t
e
n
t
i
o
n
=
P
a
r
a
m
s
Q
K
V
+
P
a
r
a
m
s
o
u
t
\mathrm{Params}_{attention} = \mathrm{Params}_{QKV} + \mathrm{Params}_{out}
Paramsattention=ParamsQKV+Paramsout
以上只是最简单便捷的Flops(浮点运算数)和Params(参数量)计算,实际问题还要具体分析。