4. 剪枝标准:基于权重大小、基于梯度、基于L1/L2范数、基于信息熵的剪枝标准
聊到剪枝,很多人第一反应就是「把不重要的权重砍掉」。但问题来了——什么叫「不重要」?
我刚开始做模型压缩那会儿,也天真地以为直接看权重绝对值大小就完事了。结果呢?剪完模型精度掉得一塌糊涂。后来踩的坑多了,才慢慢摸清楚:不同的剪枝标准,其实对应着不同的「重要性」定义。今天咱们就把这四种主流标准掰开揉碎了讲清楚。
4.1 基于权重大小的剪枝
这是最直观、也最容易上手的方法。说白了就是:权重绝对值越小,对最终结果的影响就越小。
为什么?你想想看,一个权重值接近0,它乘上输入后对输出的贡献几乎可以忽略不计。砍掉它,网络结构变了,但输出变化不大。
具体操作分三步:
- 训练好一个稠密模型
- 统计所有权重的绝对值分布,确定剪枝率(比如剪掉50%的权重)
- 将绝对值最小的那部分权重置为0,然后微调恢复精度
我在项目中遇到过一个问题:剪枝后的模型虽然参数量少了,但推理速度没怎么提升。为什么?因为权重置零后,稀疏矩阵的存储和计算需要特殊硬件或库支持(比如NVIDIA的cuSPARSE)。如果你用的推理框架不支持稀疏加速,那剪枝就只是「数字游戏」。
4.2 基于梯度的剪枝
权重大小真的能完全代表重要性吗?不一定。我举个例子:
假设有个权重是0.01,看起来很小对吧?但如果它的梯度很大,说明模型对这个权重很「敏感」,稍微动一下损失函数就剧烈变化。这种权重你敢砍?
基于梯度的剪枝,就是看权重对损失函数的影响程度。常用的指标是:
重要性 = |权重 × 梯度|
这个公式其实来自OBD(Optimal Brain Damage)算法。直觉上理解:权重本身大、梯度也大,说明这个参数既重要又敏感,必须保留。
我个人的习惯是:在训练的最后几个epoch收集梯度信息,然后取平均。为什么?因为单次梯度的噪声太大,容易误判。
| 剪枝标准 | 优点 | 缺点 |
|---|---|---|
| 权重大小 | 计算简单,容易实现 | 忽略梯度信息,可能误剪重要参数 |
| 梯度 | 考虑了对损失的影响 | 需要额外存储梯度,计算开销大 |
4.3 基于L1/L2范数的剪枝
这个标准主要用在结构化剪枝上。比如你要剪掉一个卷积核(filter),或者剪掉一个通道(channel),这时候看单个权重就不够用了——你得看一组权重的整体重要性。
L1范数就是绝对值之和,L2范数是平方和的平方根。对于一组权重 w₁, w₂, ..., wₙ:
L1 = |w₁| + |w₂| + ... + |wₙ|
L2 = sqrt(w₁² + w₂² + ... + wₙ²)
我一般更推荐用L1范数。为什么?因为L2范数对大权重更敏感,而L1范数对每个权重「一视同仁」。在实际项目中,L1范数剪枝的稳定性更好。
举个例子:假设你要剪掉一个3×3的卷积核,计算这9个权重的L1范数。如果这个值很小,说明这个卷积核整体上对特征提取贡献不大,可以整组砍掉。
4.4 基于信息熵的剪枝
这个标准稍微抽象一点,但非常有意思。它的核心思想是:一个神经元(或卷积核)输出的信息量越大,越值得保留。
信息熵怎么算?对于某个神经元的输出激活值,我们可以统计它的分布,然后计算熵:
H = -Σ p(x) · log(p(x))
其中p(x)是激活值落在某个区间的概率。熵越大,说明这个神经元的输出越「丰富」,携带的信息越多。
我刚开始用这个标准时,觉得它太理论了。直到有一次做语音识别模型的剪枝——传统的权重大小剪枝效果很差,因为语音特征本身就很稀疏。换成信息熵剪枝后,精度只掉了0.3%,但模型大小压缩了4倍。
4.5 四种标准的对比与选择
说了这么多,到底该用哪个?我个人的建议是:
- 非结构化剪枝(单个权重):优先用基于权重大小,简单高效。如果精度掉得厉害,再换成基于梯度。
- 结构化剪枝(卷积核/通道):用L1范数,配合BN层的gamma值一起判断。
- 特殊场景(如语音、稀疏特征):试试信息熵,往往有惊喜。
嗯,这里要注意:没有万能的标准。我见过有人把四种标准加权组合起来用,效果反而不好——因为不同标准之间的尺度差异太大,加权系数很难调。
最后分享一个我踩过的坑:剪枝标准选好了,但剪枝率设得太激进。有一次我想把模型压缩到原来的10%,结果精度直接崩了。后来老老实实从20%剪枝率开始,每次增加5%,每步都微调恢复精度。虽然慢,但稳。