FLOP的计算
💻 神经网络 FLOPs 计算指南
0. 符号与定义
为确保通用性,我们采用以下符号:
- $H$, $W$: 输入/输出特征图的高度和宽度(空间维度)。
- $L$: 序列长度(例如,句子中的词汇数,或 $1\text{D}$ 卷积的长度)。
- $C_{in}$: 输入通道数或输入特征维度。
- $C_{out}$: 输出通道数或输出特征维度(即滤波器数量)。
- $K$: 卷积核的尺寸($K \times K$)。
- $D$: 隐藏层/嵌入的维度(常用于 Transformer)。
MACs vs. FLOPs: * MAC (Multiply-Accumulate): 乘加操作 ($a \leftarrow a + w \cdot x$)。 * FLOPs (Floating Point Operations): 浮点运算次数。 * 标准惯例: $1 \text{ MAC} \approx 2 \text{ FLOPs}$ (1 次乘法 + 1 次加法)。 * 本指南统一采用 $2 \text{ FLOPs}$ 惯例。
1. 全连接层(Linear / MLP)
全连接层(或线性层)是深度学习中最基础的构建块,其本质是矩阵乘法。
代数定义: $$Y = X W^T + b$$
- 输入 $X$: $[B, C_{in}]$
- 权重 $W$: $[C_{out}, C_{in}]$
- 输出 $Y$: $[B, C_{out}]$
💡 FLOPs 计算
对于每个样本(Batch Size $B=1$):
$$\text{FLOPs} = 2 \cdot C_{in} \cdot C_{out}$$
- 注:若考虑 Batch Size $B$,则 $\text{FLOPs} = 2 \cdot B \cdot C_{in} \cdot C_{out}$
2. 卷积层 (Convolutional Layers)
卷积层是 CNN 的核心。我们假设输出特征图的高度和宽度分别为 $H_{out}$ 和 $W_{out}$。通常 $N = H_{out} \cdot W_{out}$。
2.1 标准卷积 (Conv2d)
代数定义 (简化): $$Y[h, w, c_{out}] = \sum_{c_{in}} \sum_{i=0}^{K-1} \sum_{j=0}^{K-1} X[h', w', c_{in}] \cdot W[i, j, c_{in}, c_{out}] + b$$
💡 FLOPs 计算
$$\text{FLOPs} = 2 \cdot H_{out} \cdot W_{out} \cdot C_{in} \cdot C_{out} \cdot K^2$$
- Conv1d (一维卷积): 将 $H_{out} \cdot W_{out}$ 替换为序列长度 $L_{out}$,将 $K^2$ 替换为 $K$。 $$\text{FLOPs} = 2 \cdot L_{out} \cdot C_{in} \cdot C_{out} \cdot K$$
2.2 深度卷积 (Depthwise Convolution)
也称分组卷积的一种特殊情况(分组数 $G = C_{in}$)。每个输入通道只与自己的一个 $K \times K$ 滤波器进行卷积,不跨通道求和。
💡 FLOPs 计算
$$\text{FLOPs} = 2 \cdot H_{out} \cdot W_{out} \cdot C_{in} \cdot K^2$$
2.3 点卷积 (Pointwise Convolution / 1x1 Conv)
使用 $1 \times 1$ 卷积核进行操作,主要用于跨通道的特征融合。它在数学上等同于对每个空间位置应用一个全连接层。
💡 FLOPs 计算
$$\text{FLOPs} = 2 \cdot H_{out} \cdot W_{out} \cdot C_{in} \cdot C_{out}$$
3. 循环神经网络 (RNNs)
我们按每个时间步(序列长度 $L$)计算 FLOPs。隐藏层维度记为 $D_h$(相当于 $C_{out}$)。
3.1 标准 Vanilla RNN
$$\mathbf{h}_t = \tanh(\mathbf{W}_{ih} \mathbf{x}_t + \mathbf{W}_{hh} \mathbf{h}_{t-1} + \mathbf{b})$$
💡 FLOPs 计算
考虑 $L$ 个时间步,每个时间步的 FLOPs: * 输入到隐藏 (Input $\to$ Hidden): $2 \cdot C_{in} \cdot D_h$ * 隐藏到隐藏 (Hidden $\to$ Hidden): $2 \cdot D_h^2$
$$\text{FLOPs} \approx L \cdot [2 \cdot D_h \cdot (C_{in} + D_h)]$$
3.2 LSTM (长短期记忆网络)
LSTM 有四个门(遗忘、输入、细胞状态、输出),每个门执行的操作类似于 Vanilla RNN。
💡 FLOPs 计算
$$\text{FLOPs} \approx L \cdot 4 \cdot [2 \cdot D_h \cdot (C_{in} + D_h)] = 8 \cdot L \cdot D_h \cdot (C_{in} + D_h)$$
3.3 GRU (门控循环单元)
GRU 有三个门(更新、重置、新隐藏状态)。
💡 FLOPs 计算
$$\text{FLOPs} \approx L \cdot 3 \cdot [2 \cdot D_h \cdot (C_{in} + D_h)] = 6 \cdot L \cdot D_h \cdot (C_{in} + D_h)$$
4. Transformer (自注意力机制)
自注意力机制是 Transformer 的核心,其中 $L$ 为序列长度, $D$ 为嵌入维度 ($C_{in} = C_{out} = D$)。
4.1 多头自注意力 (MHSA)
总 FLOPs (一个 Attention 块): $$\text{FLOPs}_{MHSA} = 4 L^2 D + 8 L D^2$$
步骤分解 (一步 $L$ 个 Token)
- 线性投影 (Q, K, V):
- 三个 $D \to D$ 的线性层。
- $3 \times (2 \cdot L \cdot D^2) = \mathbf{6 L D^2}$
- 注意力得分 ($Q \cdot K^T$):
- 矩阵乘法 $(L \times D) \times (D \times L)$ 得到 $(L \times L)$。
- $\mathbf{2 L^2 D}$
- 加权求和 ($A \cdot V$):
- 矩阵乘法 $(L \times L) \times (L \times D)$ 得到 $(L \times D)$。
- $\mathbf{2 L^2 D}$
- 输出投影 (Linear):
- 一个 $D \to D$ 的线性层。
- $1 \times (2 \cdot L \cdot D^2) = \mathbf{2 L D^2}$
4.2 前馈网络 (FFN / MLP)
标准 Transformer 采用扩展比 $E$(通常 $E=4$)。层 1: $D \to E \cdot D$;层 2: $E \cdot D \to D$。
💡 FLOPs 计算
$$\text{FLOPs}_{FFN} = 2 \cdot L \cdot D \cdot (E \cdot D) + 2 \cdot L \cdot (E \cdot D) \cdot D = 4 E L D^2$$ * 若 $E=4$,则 $\mathbf{16 L D^2}$
5. 其他辅助层
5.1 归一化 (Normalization)
包括 LayerNorm/BatchNorm 等。主要进行均值、方差计算、归一化、缩放和平移。
$$\text{FLOPs} \approx 4 \cdot \text{元素总数}$$ * 例如,对于 $(B, H, W, C)$ 的特征图,$\text{FLOPs} \approx 4 \cdot B \cdot H \cdot W \cdot C$
5.2 激活函数 (Activations)
ReLU、GELU、Sigmoid 等。应用于每个元素。
$$\text{FLOPs} \approx \text{元素总数} \times (\text{1 到 4})$$ * 由于指数和对数操作的硬件成本差异,通常将简单的 ReLU 计为 1 FLOP,而复杂的 Sigmoid/GELU 计为 2-4 FLOPs。
📊 总结速查表
| 层类型 | 复杂度阶数 | FLOPs 公式 (单个样本) | 主要影响因子 |
|---|---|---|---|
| 全连接 (MLP) | $O(C^2)$ | $2 C_{in} C_{out}$ | 通道/特征维度 ($C$) |
| 标准卷积 (Conv2d) | $O(N \cdot C^2 \cdot K^2)$ | $2 N C_{in} C_{out} K^2$ | $N = H_{out} W_{out}$ & 核尺寸 ($K$) |
| 深度卷积 (DW Conv) | $O(N \cdot C \cdot K^2)$ | $2 N C_{in} K^2$ | 极高效率 |
| Transformer-Attention | $O(L^2 D)$ | $4 L^2 D + 8 L D^2$ | 序列长度 ($L$) |
| LSTM (单时间步) | $O(C^2)$ | $8 D_h \cdot (C_{in} + D_h)$ | 隐藏层维度 ($D_h$) |