第4章:轻量级网络设计哲学:MobileNet、ShuffleNet、EfficientNet的设计启示
做模型轻量化这些年,我最大的感触就是:别把算力浪费在无效计算上。
2017年我刚接触移动端部署时,一个VGG16跑在手机上,帧率只有0.5。那时候我就想,这玩意儿根本没法用。后来MobileNet出来了,同样的任务,帧率直接飙到30+。差距在哪?说白了,就是设计哲学变了。
这一章,我带你拆解三个经典轻量网络的设计思路。它们虽然结构不同,但核心思想高度一致——用更少的计算,做更多的事。
4.1 MobileNet:深度可分离卷积的威力
MobileNet的核心贡献,就是把标准卷积拆成了两步:深度卷积和逐点卷积。
你想想看,标准卷积一个卷积核要同时处理空间信息和通道信息。这其实挺浪费的。深度可分离卷积的思路是:先单独处理每个通道的空间特征,再用1x1卷积融合通道信息。
计算量对比(直观感受)
输入特征图:H x W x C_in,卷积核:K x K,输出通道:C_out
- 标准卷积:H x W x C_in x C_out x K x K
- 深度可分离卷积:H x W x C_in x K x K + H x W x C_in x C_out
比例 ≈ 1/C_out + 1/K²。当K=3,C_out=256时,计算量直接降到原来的1/9左右。
我在项目中遇到过一个问题:深度卷积虽然省计算,但每个通道独立运算,信息交互不够。后来我加了个技巧——在深度卷积之后、逐点卷积之前,加一个BN+ReLU。这个小改动,让模型精度提升了1.2%。
我的经验:MobileNet v1的深度卷积层容易死神经元。我建议把ReLU6换成LeakyReLU,特别是低比特量化场景下,效果更稳定。
4.2 ShuffleNet:通道混洗的巧妙设计
ShuffleNet解决的是另一个问题:分组卷积的通信瓶颈。
分组卷积虽然省计算,但组与组之间老死不相往来。这就像公司里各部门各干各的,没有协作。ShuffleNet的通道混洗操作,就是强制让不同组的信息流动起来。
具体怎么做?很简单:
# 伪代码:通道混洗
def channel_shuffle(x, groups):
batch, channels, h, w = x.shape
channels_per_group = channels // groups
# reshape成 (batch, groups, channels_per_group, h, w)
x = x.view(batch, groups, channels_per_group, h, w)
# 转置:交换groups和channels_per_group维度
x = x.transpose(1, 2).contiguous()
# 展平回原始shape
x = x.view(batch, channels, h, w)
return x
我曾经在部署ShuffleNet v2时踩过一个坑:通道混洗操作在CPU上很快,但在某些GPU上反而变慢了。原因是内存访问不连续。后来我改成在逐点卷积之后做混洗,性能就上来了。
注意:ShuffleNet v2提出了四条实用准则,我建议你背下来:
- 输入输出通道数相等时,MAC最小
- 分组数过大,会增加MAC
- 碎片化操作会降低并行度
- 逐元素操作(ReLU、Add)不可忽视
这四条准则,我每次设计轻量网络都会拿出来对照一遍。
4.3 EfficientNet:复合缩放的全局视角
EfficientNet让我印象最深的一点是:它把网络设计变成了一个优化问题。
以前我们调网络,就是凭经验:深度不够就加层,宽度不够就加通道,分辨率不够就放大图片。但EfficientNet告诉你,这三个维度是耦合的,需要一起缩放。
复合缩放公式:
depth = α^φ
width = β^φ
resolution = γ^φ
其中 α·β²·γ² ≈ 2, α≥1, β≥1, γ≥1
φ是用户指定的缩放系数。α、β、γ通过NAS搜索得到。EfficientNet-B0的基线网络就是用NAS搜出来的。
我个人习惯用EfficientNet做特征提取器。在项目中,我试过用EfficientNet-B3替换ResNet-50,参数量少了40%,但精度反而高了0.5%。嗯,这就是复合缩放的力量。
核心启示:
- MobileNet教会我们:分解计算,把复杂操作拆成简单操作的组合
- ShuffleNet教会我们:信息流动,分组后别忘了让组间通信
- EfficientNet教会我们:全局优化,别只盯着一个维度调参
4.4 三者的融合启示
你可能会问:这三个网络的设计哲学,怎么用到Transformer轻量化上?
我总结了三句话:
| 轻量网络 | 核心思想 | Transformer中的对应 |
|---|---|---|
| MobileNet | 深度可分离卷积 | 分解QKV投影,用分组注意力替代全局注意力 |
| ShuffleNet | 通道混洗 | 多头注意力中的头间信息交换 |
| EfficientNet | 复合缩放 | 同时调整head数、维度、序列长度 |
我在做轻量Transformer时,就借鉴了这些思路。比如把标准注意力拆成局部窗口注意力+全局稀疏注意力,这就是MobileNet的分解思想。再比如,在FFN层引入通道混洗,让不同head的信息更充分融合。
避坑指南:我曾经在融合MobileNet和Transformer时,直接套用深度可分离卷积替换QKV投影。结果精度掉了3个点。后来发现,注意力机制中的QKV投影不适合完全分解,保留一部分标准卷积反而更好。具体来说,Q和K用深度可分离,V用标准卷积,效果最佳。
4.5 本章知识体系
下面这张图,是我梳理的轻量网络设计哲学的核心逻辑:
这张图把三个网络的核心思想,以及它们如何指导Transformer轻量化,串在了一起。你仔细看,会发现一个规律:所有轻量设计,本质上都是在做“计算重分配”——把计算资源从冗余的地方,挪到真正需要的地方。
好了,这一章的内容就到这里。记住这三个设计哲学,后面我们讲具体融合方案时,你会觉得豁然开朗。