灵犀小批量智能手表工厂里,有 8 条零件传送带(输入通道),8 名质检组长(输出通道)。以前每个组长都要挨条检查 8 条传送带,再汇总一页报告——8×8=64 种配对,费时费力。厂长想了个主意:把传送带和组长分成两组,第一组只管前 4 条带子,第二组只管后 4 条。配对瞬间从 64 降到 32,产量没少,人却轻松了一半。这个“分组协作”的思路,就是深度学习里大名鼎鼎的分组卷积(Group Convolution)。 分组卷积是轻量级神经网络(MobileNet 等)的标配技术。它不改变卷积的基本玩法,只是把“所有通道两两组合”的粗放式配对,改为“组内组合、组间隔离”的精细化分工,从而把计算量和参数量降到原来的 1/g(g 为分组数)。这篇文章会让你理解:标准卷积如何计算开销、分组卷积的数学原理与效率账、分组数怎么选、它和深度可分离卷积的关系,以及它在 MobileNet 等真实网络中的落地效果。
掌握分组卷积,你就掌握了模型压缩与轻量化设计中“省算力”的核心钥匙。无论是端侧部署、模型提速还是移动端 AI 产品落地,这项技术都是绕不开的必修课。
可视化演示
展示分组卷积的通道分组计算过程、计算量与参数量压缩效果,以及Channel Shuffle组间信息混合机制。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+captions.group+'
标准卷积基线
回到灵犀车间。8 条传送带、8 名质检组长,每当一个零件流过,每个组长都要亲手比对全部 8 条线的规格,再填一张报告单。这样一来,一个零件就要产生 8×8=64 次“组长-传送带”配对。在卷积神经网络里,这个配对数量就是算法的核心开销来源。
这种“所有人查所有线”的模式,就是标准的卷积运算。具体来说,假设输出特征图的空间尺寸是 H×W,卷积核边长是 K,输入通道数为 C_in,输出通道数为 C_out,那么标准卷积要做多少次乘加运算?答案就是下面这个公式——它像一个总账本,记录着卷积层的全部工作量。
所以标准卷积的激进之处在于“通道全混合”:任何一条传送带的信息都要被每个质检组长检查一遍,配对成本随通道数平方增长。正如车间里 64 次配对让组长们叫苦不迭,网络加深时,这种通道两两组合的开销会迅速变成灾难。
- 输出像素数输出特征图有 H×W 个空间位置,每个位置都要独立完成一次“小窗口操作”。
- 通道配对每个输出像素要融合 C_in 条输入通道的信息,并生成 C_out 个通道结果,形成通道全连接式的配对。
- 卷积核面积每个通道对要在一个 K×K 的窗口内做加权求和,窗口越大,乘加次数越多。
分组卷积原理
厂长的新方案是:把 8 条传送带分成 g=2 组,每组 4 条;8 名质检组长也分成 2 组,每组 4 人。第一组只看前 4 条带子,第二组只看后 4 条。于是每个零件只需要 2×(4×4)=32 次配对,工作量减半,报告照样完整——只是两组之间不再互相检查对方的零件。这就是分组卷积的核心思想:组内做标准卷积,组间互不干扰,最后把结果拼起来。
在数学上,分组卷积把输入通道平均切成 g 份,每份 C_in/g 个通道;对应的卷积核也切成 g 份,每份负责输出 C_out/g 个通道。每一组内部执行一次标准卷积,再把 g 组输出沿通道维度拼接,就得到了完整的 C_out 个输出通道。整个过程可以写成:
你可以把 "1/g" 理解成车间的省力系数:分 2 组省一半力气,分 4 组省掉四分之三。正是这个简洁的约分,让分组卷积成为轻量网络的第一块基石。
- 组内通道裁剪每组的输入通道变为 C_in/g,输出通道变为 C_out/g,配对基数随之缩小。
- 组内独立卷积每组内部仍用完整的 K×K 卷积核做标准卷积,输出特征图尺寸不变。
- 乘上分组数共有 g 个小组并行工作,所以总计算量是单组的 g 倍。
- 约分化简g 与分母的 g² 约分,最终得到整体计算量为标准卷积的 1/g。
效率分析
省钱省力是厂长的核心目标。除了计算量下降,工资单(参数量)同样被压缩。标准卷积的卷积核参数量是 C_in×C_out×K²——每个输入输出通道对都配一个 K×K 的核。分组后,每组只需 (C_in/g)×(C_out/g)×K² 个参数,g 组合计:
此外,分组后的每组数据量更小,更容易塞进高速缓存与寄存器,从而带来内存带宽的优化;g 个组之间没有依赖关系,天然适合多核并行或 GPU 上的并行加速。不过要泼一盆冷水:理论计算量降低,不等于实际运行一定变快。实际耗时还受硬件访存方式、框架实现、卷积核尺寸等多重因素影响。省下的算力是“账面利润”,能否兑现还要看工程优化是否跟得上。
- 单组参数一组内的卷积核连接 C_in/g 个输入通道和 C_out/g 个输出通道,参数为三者相乘。
- 各组汇总g 组之间不共享卷积核,总参数需要乘以 g。
- 约分结果分子分母约去 g,得到标准卷积的 1/g。
分组数选择
分组数 g 就像车间的小组数量,调多调少各有利弊。如果 g=1,等于没分组,退回标准卷积,计算量大但信息交流充分;如果 g=C_in(即分组数等于输入通道数),每个输入通道单独成组,此时输出通道也必须按同样的组数划分——这就是深度卷积(Depthwise Convolution)的雏形:每条传送带配一个专员,各查各的,完全没有跨线比对。
当 g 取中间值时,模型容量会被压缩,精度通常随之下降,因为组与组之间的信息被“隔离”了。比如第一组质检员永远看不到第二组的零件,万一第二组有个规格偏差,第一组是完全无感的。这就解释了为什么分组卷积常被拿来当正则化使用:它减少了自由参数,等效于给网络“降噪”,但若分组过多,模型学不到足够的通道组合模式,精度会显著受损。
实际工程中,g 的取值要兼顾精度与效率:常见的经验值是 g=2、4、8,或者让每组通道数保持 16 以上的“信息富足度”。同时要考虑硬件特性——某些 GPU 对 4 的倍数组数优化更好,固定分组数也便于工程队统一模板。总的来说,g 是精度与效率之间的调节旋钮,没有绝对最优,只有针对场景的折中。
演进与变体
分组卷积的思想很快演进出更极致的形式。当 g=C_in 且输出通道数等于输入通道数时,分组卷积变成深度卷积:每个输入通道独占一个卷积核,通道间零交流。但深度卷积的空间滤波能力有限,所以研究者又加上了逐点卷积——用 1×1 卷积核对所有通道做一次轻量混合。这就像车间改革的新模式:每位专员只负责一条传送带的初步核对(深度卷积),随后一名总装师把核对结果汇总成完整报告(逐点卷积)。
把深度卷积和逐点卷积串起来,就得到了深度可分离卷积(Depthwise Separable Convolution),计算量可以写成:
沿这条思路还衍生出了分组残差模块:在残差分支里引入分组卷积,用更小的参数量换取更宽的通道表达,典型代表如 ResNeXt。它不追求“更多层”,而是用“更多组”来提升网络的表达能力——组与组之间的不同卷积核,天然产生了多样化的特征提取器。
- 深度卷积项每个输入通道单独配一个 K×K 卷积核,输出通道数等于输入通道数,计算量为 H×W×C_in×K²。
- 逐点卷积项1×1 卷积负责融合所有通道的信息,计算量与 K 无关,只有 H×W×C_in×C_out。
- 两项相加深度卷积只做空间上的特征提取,逐点卷积只做通道间的组合,二者分工明确、互不重叠。
轻量网络应用
回到灵犀工厂的终极目标:在一条体积小、耗电低的生产线上,造出和大型车间同等质量的手表。MobileNet 交出的答案是:把整个网络里的标准卷积统统换成深度可分离卷积,并辅以瓶颈残差块设计——先用 1×1 卷积压缩通道,再做深度卷积,最后用 1×1 卷积还原通道,像一根细腰的哑铃。这个设计让网络的参数与计算量双双暴跌。
我们来算一笔账:深度可分离卷积与标准卷积的计算量之比为:
当 C_out 很大(例如 512)而 K=3 时,第一项趋近于 0,比值约等于 1/9。也就是说,MobileNet 主体计算量只有标准卷积的约九分之一。
这就是 MobileNet 系列“快而准”的秘密:用 1/9 的算力换来接近标准卷积的精度,再通过宽度乘子(channel multiplier)微调通道数,在目标算力预算内寻找最佳精度。轻量网络应用的工程经验表明:先把分组做对,再用残差补齐信息流通,最后用数据增强和蒸馏技术捡回精度——这也是今天大多数端侧视觉模型的标准打法。
- 分子拆分把 F_sep 的两项分别除以 F_std,拆成两个独立的比值。
- 约分第一项深度卷积项与分母约分后剩 1/C_out,C_out 越大这一项越小。
- 约分第二项逐点卷积项约分后剩 1/K²,卷积核越大约省得越多。
AI 应用场景
移动端实时人脸检测
阶段:模型部署与推理优化阶段
解决的问题:手机 CPU 算力有限,标准卷积在视频流上每秒只能跑几帧,发热掉电严重。AI 工程师用 MobileNet 系列轻量主干做特征提取,把深度可分离卷积全面替换标准卷积,计算量骤降 8-9 倍,人脸检测从“卡顿”变为“60 帧流畅”。
具体案例:某手机美颜 App 的实时人脸关键点检测模块,原模型 4.2MB、单帧 37ms。工程师将骨干网络换成 MobileNetV3,配合分组卷积的宽度调整,模型缩至 1.8MB,单帧降到 12ms,关键点精度仅下降 0.3%,顺利通过产线验收。
云端大规模图像分类提精度
阶段:模型设计与训练阶段
解决的问题:在算力预算固定的前提下,单纯加深或加宽网络会触及收益天花板。分组残差模块用“加组不加层”的方式扩大模型容量,让同一 FLOPs 下网络能学到更多样化的特征组合。
具体案例:某云厂商图像分类服务需要把 Top-1 准确率从 78.2% 提到 79% 以上,但推理时延不能超过 20ms。工程师参考 ResNeXt 的设计,将 ResNet-50 的 3×3 卷积改为 32 组的分组卷积,参数量不变的情况下准确率提升 0.8%,时延仅增加 1.2ms,稳定达标。
自动驾驶嵌入式设备分割模型
阶段:模型压缩与落地部署阶段
解决的问题:车载芯片的显存与功耗预算紧张,语义分割模型动辄几百 MB。利用分组卷积压缩通道间的冗余组合,可分阶段裁剪计算量,保留空间细节信息的表达能力。
具体案例:某自动驾驶团队的实时车道线分割模型原本有 12GFLOPs,在 Jetson 平台跑不满 30 FPS。通过将编码器最后的 4 层标准卷积改为分组卷积(g=2),FLOPs 降至 7.2G,帧率升到 42 FPS,mIoU 下降不到 1 个百分点,满足安全冗余要求。
Python 演示
import numpy as np def conv2d_single(inp, weight, bias, stride=1, pad=0): """极简 4 重循环标准卷积,仅供教学演示。""" N, Cin, H, W = inp.shape Cout, _, K, K = weight.shape Hout = (H + 2 * pad - K) // stride + 1 Wout = (W + 2 * pad - K) // stride + 1 out = np.zeros((N, Cout, Hout, Wout)) inp_pad = np.pad(inp, ((0, 0), (0, 0), (pad, pad), (pad, pad))) for n in range(N): for co in range(Cout): for hi in range(Hout): for wi in range(Wout): patch = inp_pad[n, :, hi * stride:hi * stride + K, wi * stride:wi * stride + K] out[n, co, hi, wi] = (patch * weight[co]).sum() + bias[co] return out def group_conv2d(inp, weight, bias, groups, stride=1, pad=0): """把输入通道切成 groups 份,分别做标准卷积再拼接。""" N, Cin, H, W = inp.shape Cout, _, K, K = weight.shape assert Cin % groups == 0 and Cout % groups == 0 Cin_g = Cin // groups Cout_g = Cout // groups parts = [] for gi in range(groups): in_g = inp[:, gi * Cin_g:(gi + 1) * Cin_g] wt_g = weight[gi * Cout_g:(gi + 1) * Cout_g] bs_g = bias[gi * Cout_g:(gi + 1) * Cout_g] parts.append(conv2d_single(in_g, wt_g, bs_g, stride, pad)) return np.concatenate(parts, axis=1) if __name__ == "__main__": np.random.seed(0) x = np.random.randn(1, 4, 8, 8) w = np.random.randn(8, 4, 3, 3) b = np.random.randn(8) y_std = conv2d_single(x, w, b) print("标准卷积输出:", y_std.shape) y_grp = group_conv2d(x, w, b, groups=2) print("分组卷积输出(g=2):", y_grp.shape) print("分组卷积与标准卷积结果一致:", np.allclose(y_std, y_grp, atol=1e-8))
assert Cin % groups == 0 and Cout % groups == 0分组的前提是通道数能被组数整除,否则无法均分。Cin_g = Cin // groups每组分配到的输入通道数,公式中的 C_in/g。in_g = inp[:, gi * Cin_g:(gi + 1) * Cin_g]按通道维度切片,取出第 gi 组的输入通道。wt_g = weight[gi * Cout_g:(gi + 1) * Cout_g]同步切分卷积核,每组只保留自己那部分输出通道的核。parts.append(...)每组独立做标准卷积,结果暂时存放在列表里。np.concatenate(parts, axis=1)沿通道轴(axis=1)拼接各组的输出,还原完整的 C_out 通道。np.allclose(y_std, y_grp)对比分组前后结果,逐元素误差小于 1e-8,证明数学等价。
常见误区
误区我一直以为分组卷积就是单纯把输入的图片数据切成几块,分别送到不同的 GPU 或 CPU 上并行计算,切得越碎跑得越快。
正解分组卷积切分的是“通道维度”,不是空间数据。它的真正作用是减少“输入通道×输出通道”的配对数量,把全连接式的通道组合变成组内组合。并行只是它带来的附带红利,而非本质。就好比车间分组的目的是减少质检配对,而不是把零件物理切开;切开零件反而会破坏完整性。
为何常见:因为“分组”这个词太容易让人联想到多机多卡的数据并行,初学者往往会忽略卷积在通道维度上的数学结构。
误区既然计算量是 1/g,那我直接把 g 设成 32 甚至 64,模型不就越轻越快?精度差点也能接受。
正解g 过大会导致每个组内的通道太少,组与组之间完全没有信息交流,模型很难学习到“跨通道组合”这种高级特征。实践中 g 超过一定值后精度会快速滑坡,省下的算力远不足以弥补准确率的损失。分组数的选择是效率与精度之间的权衡,不是单边压倒。
为何常见:人们天然把“省算力”当作唯一目标,却忽略了模型性能是多目标博弈的结果;g 只是旋钮,不是开关。
误区FLOPs 从 100M 降到 25M,那推理时间不就应该是原来的四分之一?为什么实测只快了 1.5 倍?
正解FLOPs 衡量的是乘加运算次数,但真实耗时还取决于访存带宽、数据布局、卷积实现的底层算法(如 im2col、Winograd、FFT)以及硬件利用率。分组卷积的组数如果不匹配硬件向量化宽度,反而会引入额外开销。计算量是“账面利润”,实际速度要看“落袋为安”的工程实现。
为何常见:在深度学习入门阶段,FLOPs 是唯一显眼的复杂度指标,大家习惯把它等同于时间;但计算机系统的实际性能从来不是单一算术指标能决定的。
误区深度可分离卷积不就是分组卷积吗?都是把通道分开运算,名字不同而已。
正解它们是从属关系而非等价关系。深度卷积是分组卷积在 g=C_in 时的特例;而深度可分离卷积 = 深度卷积 + 逐点卷积,即在彻底分组之后,又用 1×1 卷积补上了一次“通道混合”来修复组间信息隔离的问题。普通分组卷积没有这个补救步骤,所以信息隔离更严重。
为何常见:两套名词都围绕“通道分组”展开,概念交叉多;如果没有画过网络结构图,很容易把它们的层级关系搞混。
面试题
Q1. 分组卷积最核心的改进是什么?
- A.把输入图片切成小块分别处理
- B.把通道分组各自卷积再拼接← 正确答案
- C.把卷积核替换成多个小卷积核
- D.把模型复制到多张卡上训练
答案:B。分组卷积的本质是沿通道维度切分——输入通道和对应卷积核一起分成 g 组,每组内部做标准卷积,最后拼接输出。A 错在切的是通道不是空间数据;C 错在核的尺寸不变,只是数量被分组;D 说的是数据并行,与分组卷积无关。
Q2. 标准卷积的计算量(FLOPs)公式是?
- A.H × W × C_in × C_out × K
- B.H × W × C_in × C_out × K²← 正确答案
- C.H × W × (C_in + C_out) × K²
- D.H × W × C_in × K²
答案:B。每个输出像素要对 C_in×C_out 个通道组合做 K×K 窗口内的乘加,再乘以 H×W 个空间位置。A 少乘了一个 K;C 把乘号写成了加号;D 忽略了输出通道 C_out 的配对。
Q3. 输入输出通道均为 64,分组数 g=4 时,参数量是标准卷积的多少?
- A.四分之一← 正确答案
- B.二分之一
- C.十六分之一
- D.六十四分之一
答案:A。分组卷积的参数量公式为 P_std/g,直接代入 g=4 得四分之一。C 的十六分之一是把每组参数量当成了总参数量;D 是把分组数误当通道数;B 没有按公式计算。
Q4. 当分组数 g 等于输入通道数时,分组卷积退化为?
- A.标准卷积
- B.逐点卷积
- C.深度卷积← 正确答案
- D.转置卷积
答案:C。g=C_in 时每个输入通道单独一组,卷积核只在单个通道上滑动,这正是深度卷积的定义。A 发生在 g=1 时;B 是 1×1 卷积;D 是上采样操作,与分组无关。
Q5. 分组数过大,最主要的副作用是什么?
- A.模型体积变大无法部署
- B.组间信息隔离导致精度下降← 正确答案
- C.训练时梯度必然爆炸
- D.卷积核尺寸必须同步增大
答案:B。分组越多,每组通道越少,组与组之间完全不交换信息,跨通道特征组合难以学习,精度随之下降。A 说反了,分组越大参数越少;C 梯度爆炸与分组无直接关系;D 卷积核尺寸不受分组影响。
Q6. 为什么 FLOPs 降为 1/4,实测推理速度不一定变为 1/4?
- A.FLOPs 只统计加法不统计乘法
- B.实际耗时还受访存、硬件与实现的影响← 正确答案
- C.分组后模型参数反而变多
- D.卷积核计算无法并行化
答案:B。FLOPs 只是乘加次数,真实推理耗时还受内存带宽、数据布局、框架底层算法和硬件利用率制约。A 说反了,FLOPs 通常同时统计乘与加;C 参数只会变少;D 分组卷积恰恰更容易并行。
Q7. 深度可分离卷积由哪两部分组成?
- A.深度卷积(Depthwise Conv)← 正确答案
- B.逐点卷积(Pointwise Conv)← 正确答案
- C.转置卷积(Transposed Conv)
- D.空洞卷积(Dilated Conv)
答案:AB。深度可分离卷积 = 深度卷积(每个通道独立空间滤波)+ 逐点卷积(1×1 卷积混合通道)。C 用于上采样,D 用于扩大感受野,二者都不是深度可分离卷积的组成部分。
Q8. C_in=256,C_out=256,K=3,输出特征图 28×28,g=32 时分组卷积的 FLOPs 约为?
- A.1810 万次乘加← 正确答案
- B.1448 万次乘加
- C.905 万次乘加
- D.452 万次乘加
答案:A。代入公式 F = H×W×C_in×C_out×K²/g = 28×28×256×256×9÷32 = 18,055,168 ≈ 1810 万。B 是误把 H×W 当 28×28 再少算一半的结果;C 是按 1/g 多除了一次;D 是把 K² 误当 3。
Q9. 关于 MobileNet 中的轻量化设计,下列说法正确的是?
- A.用深度可分离卷积替代标准卷积← 正确答案
- B.深度卷积负责空间特征提取← 正确答案
- C.逐点卷积负责扩大感受野
- D.卷积核全部换成了 7×7 大核
答案:AB。MobileNet 用深度卷积做空间滤波、逐点卷积做通道混合,两者组合替代标准卷积。C 错在逐点卷积是混合通道而非扩大感受野;D 错在 MobileNet 默认使用 3×3 卷积核。
Q10. 某网络将标准卷积改为分组卷积后精度下降,下列哪种补救措施最符合分组卷积的设计思想?
- A.增大分组数 g 以继续压缩参数
- B.在分组卷积后增加逐点卷积恢复通道混合← 正确答案
- C.把卷积核从 3×3 改为 7×7
- D.删掉所有激活函数减少噪声
答案:B。分组卷积精度下降的主因是组间信息隔离,而逐点卷积恰是修复通道混合的轻量手段(这正是深度可分离卷积的思路)。A 会加重隔离;C 改大核只增计算量不补信息流通;D 删激活函数会损害非线性表达能力。