1. 从“全连接”到“卷积”:为什么我们需要这么多花样?
如果你刚开始接触深度学习,尤其是计算机视觉,可能会被各种“卷积”搞得晕头转向。普通卷积、分组卷积、深度卷积、逐点卷积、深度可分离卷积……这些名词听起来既相似又不同,它们到底在解决什么问题?为什么一个简单的“卷积”操作,会演化出这么多变体?
要理解这一切,我们得回到问题的起点。在图像处理中,卷积的本质是用一个小的滤波器(卷积核)在输入数据上滑动,进行局部特征的提取。最初的普通卷积(Standard Convolution)就像一个“全才”,它同时负责两件事:跨通道的特征融合和空间特征的提取。想象一下,你有一张三通道的彩色图片(RGB),一个普通的3x3卷积核,它不仅要在3x3的区域内计算像素关系(空间特征),还要把红、绿、蓝三个通道的信息混合起来,生成一个新的特征。
这听起来很强大,但“全才”往往意味着“高成本”。这个成本就是计算量和参数量。随着网络越来越深,特征图通道数越来越多,普通卷积的计算开销会变得极其庞大,严重制约了模型在移动设备或嵌入式设备上的部署。于是,研究人员开始思考:我们能否把这个“全才”的工作拆分开,让不同的“专家”各司其职,从而在保证效果的前提下,大幅提升效率?
这就是分组卷积、深度可分离卷积等变体诞生的核心动机。它们不是要颠覆卷积,而是对卷积工作进行了一次精密的“职责划分”和“流程再造”。理解它们,不仅仅是记住公式和形状,更是理解现代高效神经网络设计的核心思想。接下来,我们就逐一拆解这些“卷积专家”们是如何工作的,并用最直观的输入、卷积核、输出形状来具象化这个过程。
2. 基准模型:深入拆解普通卷积的运作机制
在讨论各种变体之前,我们必须先彻底理解基准——普通卷积。它是所有衍生技术的基础,搞懂了它,其他变体就很容易触类旁通。
2.1 核心工作流程与张量形状变换
假设我们有一个输入特征图(Input Feature Map),其形状为[H_in, W_in, C_in]。这里H_in是高度,W_in是宽度,C_in是输入通道数。例如,一张RGB图片输入网络时,C_in = 3。
我们使用一个卷积层,它包含C_out个卷积核(Kernels 或 Filters)。每个卷积核的形状是[K, K, C_in]。其中K是卷积核的空间尺寸(如3, 5, 7),C_in必须与输入特征图的通道数相等,这是进行逐元素乘加运算的前提。
计算过程:每个卷积核独立工作。它将这个[K, K, C_in]的核在整个输入特征图上滑动(涉及步长Stride、填充Padding等参数)。在每一个滑动窗口位置,核与输入窗口的对应元素相乘后求和,得到一个标量值。这个标量,就是输出特征图在该位置、该通道的一个像素点。
- 一个卷积核,遍历所有空间位置后,生成一张单通道的特征图,形状为
[H_out, W_out, 1]。 C_out个卷积核,各自生成一张单通道特征图,最终将所有结果在通道维度上堆叠(Stack)起来,就得到了最终的输出特征图,其形状为[H_out, W_out, C_out]。
形状关系总结:
- 输入(Input):
[H_in, W_in, C_in] - 卷积核(Kernel):
[K, K, C_in, C_out](通常我们按[C_out, C_in, K, K]的顺序理解,但本质是四维张量) - 输出(Output):
[H_out, W_out, C_out]
其中,H_out和W_out由输入尺寸、卷积核尺寸K、步长S和填充P共同决定,公式为:H_out = floor((H_in - K + 2P) / S) + 1。
2.2 计算量与参数量分析:效率瓶颈所在
普通卷积的强大源于其“全连接”特性:每个输出通道的每个像素,都综合了所有输入通道在局部空间上的信息。但这正是其计算代价高昂的原因。
参数量(Parameters): 参数量就是所有卷积核的权重总数。一个卷积核有K * K * C_in个参数,一共有C_out个这样的核。参数量 = K * K * C_in * C_out
计算量(FLOPs,浮点运算次数): 通常以一次乘加运算(Multiply-Add)为一次FLOP。对于每一个输出像素(共H_out * W_out * C_out个),都需要进行K * K * C_in次乘加运算。计算量 ≈ H_out * W_out * C_out * K * K * C_in(忽略偏置项)
注意:这里隐藏了一个关键点。当
C_in和C_out都很大时(例如256、512),计算量会以乘积形式爆炸式增长。K*K项(空间聚合)和C_in*C_out项(通道融合)耦合在一起,是效率的主要瓶颈。后续所有的卷积变体,几乎都是围绕如何解耦或优化这两项而展开的。
3. 分工协作的初步尝试:分组卷积的设计哲学
当普通卷积的通道融合部分(C_in * C_out)成为瓶颈时,分组卷积(Grouped Convolution)提供了一种直观的优化思路:化整为零,分而治之。
3.1 如何将通道“分组”处理
分组卷积的核心思想是将输入通道C_in和输出通道C_out均分成G个独立的组。假设C_in和C_out都能被G整除。
- 输入特征图被分成
G组,每组有C_in / G个通道。 - 输出通道也被分成
G组,每组需要生成C_out / G个通道的特征图。 - 关键限制:第
g组的卷积核,只允许与第g组的输入通道进行卷积操作,并生成第g组的输出通道。组与组之间的计算是完全独立的,信息不交叉。
形状关系:
- 输入(Input):
[H_in, W_in, C_in](在逻辑上被分为G组,每组C_in/G通道) - 卷积核(Kernel): 可以理解为有
G个独立的“子卷积层”。每个子卷积层的核形状为[K, K, C_in/G, C_out/G]。整体参数量是这G部分的累加。 - 输出(Output):
[H_out, W_out, C_out](由G组结果在通道维拼接而成)
3.2 效率提升与特性分析
参数量和计算量:
- 参数量 =
G * (K * K * (C_in/G) * (C_out/G)) = (K * K * C_in * C_out) / G - 计算量 ≈
H_out * W_out * C_out * K * K * (C_in/G)
可以看到,无论是参数量还是计算量,都下降为普通卷积的1/G。当G=C_in=C_out时,就是著名的深度卷积,我们稍后会详细讲。
特性与注意事项:
- 稀疏连接:分组卷积引入了通道维度的稀疏性。输出特征的每个通道,只与一部分输入通道相关。这可以看作是一种正则化,有时能防止过拟合,学习到更鲁棒的特征。
- 硬件友好:独立的组计算可以非常方便地在多个GPU或计算核心上进行并行,提升实际运行速度。
- 信息隔离的副作用:这也是最大的缺点。由于组间信息不流通,特征融合的能力被削弱了。如果分组数
G设置得过大(比如等于通道数),模型的表现可能会下降。ResNeXt等网络通过采用适度的分组数(如32),在精度和效率间取得了良好平衡。 - 分组数选择:
G通常取2的幂次(如2, 4, 8, 16, 32),并且需要保证C_in和C_out能被G整除。G=1就是普通卷积,G=C_in就是深度卷积。
4. 极致的空间滤波:深度卷积的独立通道处理
分组卷积当分组数G等于输入通道数C_in,并且通常也令输出通道数C_out等于C_in时,就得到了一个特例——深度卷积(Depthwise Convolution, DW Conv)。这是深度可分离卷积的第一阶段。
4.1 一个通道配一个滤波器
深度卷积的理念非常极端:每个输入通道完全独立,拥有自己专属的、只针对该通道的卷积核。这个卷积核只在该通道对应的二维平面上做空间滤波,不与其他任何通道的数据混合。
工作流程:
- 输入特征图有
C_in个通道。 - 我们准备
C_in个卷积核,每个核的形状是[K, K, 1]。 - 第
c个卷积核,只在输入特征图的第c个通道上滑动计算,生成一张单通道的特征图。 - 最终,将
C_in张单通道输出图在通道维度拼接起来,得到输出特征图。
形状关系:
- 输入(Input):
[H_in, W_in, C_in] - 卷积核(Kernel):
[K, K, 1, C_in](通常表示为[C_in, 1, K, K]) - 输出(Output):
[H_out, W_in, C_in]注意:输出通道数等于输入通道数。
4.2 深度卷积的效能与局限
效率极高:
- 参数量 =
C_in * K * K * 1 = K * K * C_in - 计算量 ≈
H_out * W_out * C_in * K * K * 1与普通卷积的K*K*C_in*C_out相比,深度卷积少了C_out这个乘数因子。当C_out较大时(如256),节省的计算量是数十上百倍的。
核心局限: 深度卷积只做空间滤波,完全不做通道融合。输出的每个通道都只来源于输入的对应通道,通道之间是“老死不相往来”的。这意味着它虽然能高效地提取每个通道内的空间特征(比如边缘、纹理),但无法组合这些特征来形成更高级的语义概念(比如“眼睛是由特定纹理和边缘组成的”)。因此,深度卷积几乎从不单独使用,它需要一个搭档来弥补通道融合的缺陷,这个搭档就是逐点卷积。
5. 高效的通道融合器:逐点卷积的跨通道信息整合
逐点卷积(Pointwise Convolution, PW Conv)是深度可分离卷积的第二阶段,也是解决深度卷积局限性的关键。它的名字很形象:卷积核的尺寸是 1x1。
5.1 1x1卷积的跨通道线性组合
一个形状为[1, 1, C_in, C_out]的卷积核,它的工作方式如下:
- 它在输入特征图的每一个空间位置(即每一个“点”)上独立操作。
- 在这个点上,它看到一个
C_in维的向量(所有通道在该位置的像素值)。 - 1x1卷积核对这个
C_in维向量进行线性加权求和(再加上偏置),输出一个标量值。因为有C_out个这样的核,所以在这个点上就产生了C_out个标量。 - 遍历所有
H_out * W_out个空间位置,就得到了最终的输出特征图。
形状关系:
- 输入(Input):
[H_in, W_in, C_in](注意:对于PW Conv,通常H_out = H_in, W_out = W_in,因为1x1卷积且步长为1时,空间尺寸不变) - 卷积核(Kernel):
[1, 1, C_in, C_out] - 输出(Output):
[H_in, W_in, C_out]
5.2 为什么1x1卷积如此重要?
- 纯粹的通道融合:它不涉及任何空间相邻像素的聚合(因为核大小是1x1),它的全部职责就是学习如何将
C_in个通道的信息以最优的方式组合成C_out个新的通道。这正好弥补了深度卷积的不足。 - 升降维度的利器:通过设置
C_out大于或小于C_in,它可以灵活地增加或减少特征图的通道数,是控制网络容量和复杂度的关键开关。 - 计算代价相对较低:它的计算量是
H * W * C_in * C_out。虽然仍有C_in * C_out项,但没有了K * K这个乘数因子。相比于普通卷积的K*K*C_in*C_out,计算量减少了K*K倍(例如对于3x3卷积,就是9倍)。
实操心得:在设计和调试网络时,1x1卷积层是调整特征图通道数的首选。它不仅计算高效,而且由于其线性变换的本质,在反向传播中也非常稳定。在瓶颈结构(Bottleneck)中,常用1x1卷积先降维,再用3x3卷积处理,最后再用1x1卷积升维,能极大减少中间层的计算量。
6. 黄金组合:深度可分离卷积的完整工作流与优势对比
现在,我们把深度卷积(DW Conv)和逐点卷积(PW Conv)串联起来,就构成了完整的深度可分离卷积(Depthwise Separable Convolution)。它的设计哲学是:将空间特征提取和通道特征融合这两个高度耦合的任务,解耦成两个独立的、更高效的步骤。
6.1 两步走的工作流程
第一步:深度卷积(Depthwise Conv)
- 输入:形状为
[H, W, C_in]的特征图。 - 操作:使用
C_in个[K, K, 1]的卷积核,分别对每个输入通道进行独立的空间滤波。 - 中间输出:形状为
[H_out_dw, W_out_dw, C_in]的特征图。注意通道数未变,但空间尺寸可能因步长而变化。
第二步:逐点卷积(Pointwise Conv)
- 输入:上一步的输出,形状为
[H_out_dw, W_out_dw, C_in]。 - 操作:使用
C_out个[1, 1, C_in]的卷积核,对中间输出的每个空间位置进行通道融合。 - 最终输出:形状为
[H_out_dw, W_out_dw, C_out]的特征图。
6.2 效率对比:以经典3x3卷积为例
让我们用具体数字来感受一下深度可分离卷积的效率优势。假设输入为[H, W, 256], 输出为[H, W, 256], 使用3x3卷积,且步长=1,填充=1(保持尺寸不变)。
普通3x3卷积:
- 计算量 ≈
H * W * 256 * 3 * 3 * 256 = H * W * 589,824 - 参数量 =
3 * 3 * 256 * 256 = 589,824
- 计算量 ≈
深度可分离卷积(3x3 DW + 1x1 PW):
- 深度卷积阶段:
- 计算量 ≈
H * W * 256 * 3 * 3 * 1 = H * W * 2,304 - 参数量 =
3 * 3 * 256 = 2,304
- 计算量 ≈
- 逐点卷积阶段:
- 计算量 ≈
H * W * 256 * 1 * 1 * 256 = H * W * 65,536 - 参数量 =
1 * 1 * 256 * 256 = 65,536
- 计算量 ≈
- 总计:
- 计算量 ≈
H * W * (2,304 + 65,536) = H * W * 67,840 - 参数量 =
2,304 + 65,536 = 67,840
- 计算量 ≈
- 深度卷积阶段:
对比结果:
- 计算量比例:
67,840 / 589,824 ≈ 1/8.7 - 参数量比例:
67,840 / 589,824 ≈ 1/8.7
深度可分离卷积将计算量和参数量都降低到了普通卷积的约1/9!这正是MobileNet、Xception等轻量级网络的核心秘诀。
6.3 实际应用中的权衡与变体
尽管效率优势巨大,但深度可分离卷积并非完美无缺。
精度损失:由于将空间滤波和通道融合完全解耦,其表示能力理论上弱于同时进行这两项操作的普通卷积。在实践中,对于大型数据集(如ImageNet)和足够深的网络,通过增加网络宽度(通道数)或深度,通常可以弥补这部分精度损失,最终实现精度相当但模型更小更快。
变体与改进:
- 线性瓶颈与倒残差结构(MobileNetV2):MobileNetV2发现,在深度卷积之前使用PW卷积先升维(扩大通道数),在深度卷积之后再用PW卷积降维,并在其中使用线性激活(无非线性),能更好地保留特征信息,显著提升精度。
- 通道混洗(ShuffleNet):在分组卷积或深度可分离卷积中,组间或通道间信息不流通是弱点。ShuffleNet通过在分组卷积后引入“通道混洗”操作,让不同组的信息能够重新排列、混合,以极小的计算代价提升了特征融合能力。
- 注意力机制结合:在深度卷积或PW卷积中引入通道注意力(如SE模块)或空间注意力,让网络能自适应地强调重要特征,进一步提升性能。
踩坑经验:在将现有模型中的普通卷积替换为深度可分离卷积以进行模型压缩时,不能简单地一对一替换。通常需要重新调整整个网络的宽度乘子(Width Multiplier)和分辨率乘子(Resolution Multiplier),并可能需要微调甚至从头训练。直接替换往往会导致精度大幅下降。一个稳妥的做法是,先在关键瓶颈层进行替换,评估效果后再逐步推广。
7. 综合对比与选型指南:如何为你的项目选择卷积类型?
了解了各种卷积的机理后,在实际项目中如何做出选择?下面这个表格从多个维度进行了对比,可以作为快速参考。
| 特性 | 普通卷积 (Standard Conv) | 分组卷积 (Grouped Conv) | 深度可分离卷积 (Depthwise Separable Conv) |
|---|---|---|---|
| 核心职责 | 同时进行空间滤波与通道融合 | 分组内进行空间滤波与通道融合 | 深度卷积:空间滤波;逐点卷积:通道融合 |
| 输入形状 | [H, W, C_in] | [H, W, C_in](分G组) | [H, W, C_in] |
| 卷积核形状 | [K, K, C_in, C_out] | [K, K, C_in/G, C_out/G](每组) | DW:[K, K, 1, C_in]; PW:[1, 1, C_in, C_out] |
| 输出形状 | [H_out, W_out, C_out] | [H_out, W_out, C_out] | [H_out, W_out, C_out] |
| 计算量 (近似) | HWC_outK^2C_in | HWC_outK^2(C_in/G) | HW(C_inK^2 + C_inC_out) |
| 参数量 | K^2 * C_in * C_out | (K^2 * C_in * C_out) / G | K^2 * C_in + C_in * C_out |
| 主要优势 | 强大的特征融合与表示能力 | 计算量/参数量减少为1/G, 有一定正则化效果 | 极高的计算效率,参数量大幅减少,适合移动端 |
| 主要劣势 | 计算成本与参数量高 | 组间信息不流通,G过大会损害性能 | 表示能力稍弱,需更宽/深的网络补偿精度 |
| 典型应用场景 | 对精度要求极高的服务器端模型、网络底层特征提取 | ResNeXt, ShuffleNet (与通道混洗结合), 平衡效率与精度 | 移动端/嵌入式模型首选:MobileNet系列, Xception |
选型决策思路:
首要考虑:部署平台与性能约束
- 服务器/云端(算力充足):优先使用普通卷积,以获得最佳模型精度。在需要压缩模型时,可考虑结合分组卷积。
- 移动端/嵌入式设备(算力、内存、功耗敏感):深度可分离卷积是绝对的主流和首选。从MobileNetV1到V3,以及许多其他轻量级网络,都以其为基础构建。
次要考虑:精度与效率的平衡点
- 如果觉得深度可分离卷积在任务上精度损失明显,但普通卷积计算量又太大,可以尝试分组卷积。通过调整分组数
G(如8, 16, 32),可以在效率和特征融合能力之间找到一个折中点。ShuffleNet通过引入通道混洗,进一步缓解了分组卷积的信息流通问题,是非常优秀的轻量级架构。
- 如果觉得深度可分离卷积在任务上精度损失明显,但普通卷积计算量又太大,可以尝试分组卷积。通过调整分组数
网络结构设计中的混合使用
- 一个网络并非只能使用一种卷积。常见的策略是:
- 网络浅层:输入通道少,计算量不大,可使用少量普通卷积快速提取基础特征。
- 网络中层与深层:通道数激增,大量使用深度可分离卷积或分组卷积来构建瓶颈块(Bottleneck Blocks),控制计算量爆炸。
- 注意力与门控机制:经常使用1x1的逐点卷积来实现通道或空间注意力权重的生成。
- 一个网络并非只能使用一种卷积。常见的策略是:
理解这些卷积变体,最终是为了让你在设计和优化神经网络时,手中拥有更多、更精确的工具。它们不是互斥的,而是可以像乐高积木一样,根据你对模型性能、速度、大小的具体需求,灵活组合,搭建出最适合当前任务的架构。