如何计算卷积层的计算量?从参数到公式的详细推导
在深度学习和卷积神经网络(CNN)的设计中,计算量是一个核心指标。它直接影响模型的推理速度、内存占用以及硬件部署成本。而卷积层作为CNN的核心组件,其计算量的估算尤为关键。本文将从最基础的参数出发,逐步推导卷积层的计算量公式,并通过实例帮助你彻底理解这一过程。
一、关键参数定义
在开始推导前,我们需要明确几个核心参数的含义(以二维卷积为例):
- 输入特征图尺寸:记为 w×hw \times hw×h(宽×高)。若输入是正方形,则 w=hw = hw=h(后续以 w×ww \times ww×w 简化说明)。
- 卷积核尺寸:记为 k×kk \times kk×k(宽×高),即每个卷积核的大小。
- 步长(Stride):记为 sss,表示卷积核在输入特征图上滑动的步幅(水平和垂直步长通常相同)。
- 填充(Padding):记为 ppp,表示在输入特征图四周填充的像素数(通常填充0)。
- 输入通道数:记为 CinC_{in}Cin,即输入特征图的通道数(如RGB图像 Cin=3C_{in}=3Cin=3)。
- 输出通道数:记为 CoutC_{out}Cout,即卷积操作后生成的特征图通道数(由 CoutC_{out}Cout 个不同的卷积核并行计算得到)。
二、输出特征图尺寸的计算
卷积层的输出特征图尺寸由输入尺寸、卷积核大小、步长和填充共同决定。其计算公式为:
Wout=⌊Win+2p−ks⌋+1
W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} + 2p - k}{s} \right\rfloor + 1
Wout=⌊sWin+2p−k⌋+1
Hout=⌊Hin+2p−ks⌋+1
H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2p - k}{s} \right\rfloor + 1
Hout=⌊sHin+2p−k⌋+1
其中:
- Win,HinW_{\text{in}}, H_{\text{in}}Win,Hin 是输入特征图的宽和高;
- Wout,HoutW_{\text{out}}, H_{\text{out}}Wout,Hout 是输出特征图的宽和高;
- ⌊x⌋\lfloor x \rfloor⌊x⌋ 表示对 xxx 向下取整(实际中若无法整除,超出部分会被截断)。
示例:计算输出尺寸
假设输入是 224×224224 \times 224224×224 的特征图(Win=Hin=224W_{\text{in}}=H_{\text{in}}=224Win=Hin=224),卷积核 k=3k=3k=3,步长 s=1s=1s=1,填充 p=1p=1p=1,则:
Wout=⌊224+2×1−31⌋+1=224
W_{\text{out}} = \left\lfloor \frac{224 + 2 \times 1 - 3}{1} \right\rfloor + 1 = 224
Wout=⌊1224+2×1−3⌋+1=224
此时输出特征图尺寸与输入相同(这也是“Same Padding”的效果)。
三、卷积层的计算量推导
卷积层的计算量通常用**乘加操作次数(MAC, Multiply-Add)**衡量。每个卷积操作的本质是:将一个 k×k×Cink \times k \times C_{in}k×k×Cin 的卷积核与输入特征图的对应区域逐元素相乘,再将所有乘积相加,最后加上偏置(Bias)。
1. 单个输出元素的计算量
对于输出特征图中的一个位置 (i,j)(i,j)(i,j)(iii 为行号,jjj 为列号),其值由输入特征图中一个 k×k×Cink \times k \times C_{in}k×k×Cin 的区域与一个 k×k×Cink \times k \times C_{in}k×k×Cin 的卷积核相乘累加得到。具体来说:
- 每个输入通道的 k×kk \times kk×k 区域需要 k×kk \times kk×k 次乘法;
- CinC_{in}Cin 个通道共需 k×k×Cink \times k \times C_{in}k×k×Cin 次乘法;
- 最后将 CinC_{in}Cin 个通道的结果相加,需要 Cin−1C_{in} - 1Cin−1 次加法。
但工业界和学术界通常将一次乘法和一次加法合并为一个MAC操作(即 1 MAC=1 乘法+1 加法1 \text{ MAC} = 1 \text{ 乘法} + 1 \text{ 加法}1 MAC=1 乘法+1 加法)。因此,单个输出元素的计算量为 k×k×Cink \times k \times C_{in}k×k×Cin 次MAC(加法的次数被隐含在MAC的定义中)。
2. 整个卷积层的总计算量
输出特征图的总元素数为 Wout×HoutW_{\text{out}} \times H_{\text{out}}Wout×Hout,而每个输出通道需要独立计算(由 CoutC_{out}Cout 个不同的卷积核分别处理)。因此,总计算量为:
总计算量=Cout×Wout×Hout×k×k×Cin \text{总计算量} = C_{\text{out}} \times W_{\text{out}} \times H_{\text{out}} \times k \times k \times C_{\text{in}} 总计算量=Cout×Wout×Hout×k×k×Cin
四、实例验证:以经典CNN为例
我们以VGG16中的第一个卷积层为例,参数如下:
- 输入尺寸:224×224224 \times 224224×224(Win=Hin=224W_{\text{in}}=H_{\text{in}}=224Win=Hin=224);
- 卷积核:3×33 \times 33×3(k=3k=3k=3);
- 步长:s=1s=1s=1;
- 填充:p=1p=1p=1;
- 输入通道数:Cin=3C_{\text{in}}=3Cin=3(RGB图像);
- 输出通道数:Cout=64C_{\text{out}}=64Cout=64。
步骤1:计算输出尺寸
根据公式:
Wout=Hout=⌊224+2×1−31⌋+1=224
W_{\text{out}} = H_{\text{out}} = \left\lfloor \frac{224 + 2 \times 1 - 3}{1} \right\rfloor + 1 = 224
Wout=Hout=⌊1224+2×1−3⌋+1=224
步骤2:计算总计算量
代入总计算量公式:
总计算量=64×224×224×3×3×3
\text{总计算量} = 64 \times 224 \times 224 \times 3 \times 3 \times 3
总计算量=64×224×224×3×3×3
计算得:
64×2242×27≈64×50176×27≈88,473,600 MAC
64 \times 224^2 \times 27 \approx 64 \times 50176 \times 27 \approx 88,473,600 \text{ MAC}
64×2242×27≈64×50176×27≈88,473,600 MAC
即约8850万次乘加操作。
五、扩展讨论:其他卷积类型的计算量
1. 深度可分离卷积(Depthwise Separable Conv)
深度可分离卷积分为两步:
- 逐通道卷积(Depthwise Conv):每个输入通道单独用一个 k×kk \times kk×k 卷积核处理,无跨通道信息融合。计算量为 Cin×Wout×Hout×k×kC_{\text{in}} \times W_{\text{out}} \times H_{\text{out}} \times k \times kCin×Wout×Hout×k×k。
- 逐点卷积(Pointwise Conv):用 1×11 \times 11×1 卷积融合通道信息,计算量为 Cin×Cout×Wout×Hout×1×1C_{\text{in}} \times C_{\text{out}} \times W_{\text{out}} \times H_{\text{out}} \times 1 \times 1Cin×Cout×Wout×Hout×1×1。
总计算量为两者之和,远小于标准卷积(约为标准卷积的 1/Cout+1/k21/C_{\text{out}} + 1/k^21/Cout+1/k2 倍)。
2. 偏置(Bias)的影响
每个输出通道需要 Wout×HoutW_{\text{out}} \times H_{\text{out}}Wout×Hout 次加法(加偏置),但相比卷积的乘加操作,其计算量可忽略不计(约占总计算量的 1/10001/10001/1000),因此通常不纳入主要计算量统计。
六、结论
卷积层的计算量由输入/输出尺寸、卷积核大小、通道数和步长共同决定。核心公式为:
总计算量=Cout×Wout×Hout×k×k×Cin
\text{总计算量} = C_{\text{out}} \times W_{\text{out}} \times H_{\text{out}} \times k \times k \times C_{\text{in}}
总计算量=Cout×Wout×Hout×k×k×Cin
理解这一公式有助于我们在模型设计时权衡精度与计算效率(例如,增大步长或减小卷积核可降低计算量)。实际应用中,还需结合硬件特性(如GPU的并行计算能力)和框架优化(如TensorRT的算子融合)进一步优化推理速度。
下次设计CNN时,不妨先用这个公式估算计算量,再决定是否需要调整参数!