模型压缩策略综述(原理概念)

7 阅读9分钟

2.1 网络剪枝 (Network Pruning)

核心思想:神经网络通常是过参数化的,存在大量冗余。剪枝旨在移除不重要的权重或神经元,以减少计算量和存储空间,同时尽量保持精度。

2.1.1 非结构化剪枝 (Unstructured Pruning)

  • 原理:以单个权重为最小单位进行剪枝。通过设定一个阈值,将绝对值小于该阈值的权重置为零,使其不参与计算。

  • 特点

    • 优点:粒度细,剪枝率高,对精度的损失相对较小。
    • 缺点:权重矩阵变得稀疏(产生大量0值),但标准硬件(如GPU)对稀疏矩阵的加速并不友好,需要特定的硬件或软件库(如专用加速器或稀疏卷积库)才能实现真正的推理加速。
  • 面试话术:它就像把一张图片中亮度较低的像素点直接调成0,虽然数据稀疏了,但在普通屏幕上显示并不会变快。

2.1.2 结构化剪枝 (Structured Pruning)

  • 原理:以更大、更规则的结构为单位进行剪枝,如剪掉整个卷积核(Channel/Filter Pruning)、通道(Channel Pruning)或层(Layer Pruning)。

  • 特点

    • 优点:剪枝后不会产生稀疏矩阵,网络结构规整,可以直接在现成的深度学习框架和硬件上获得推理速度的提升。
    • 缺点:决策比较粗暴,精度损失通常比非结构化剪枝大,往往需要更精细的微调(Fine-tuning)来恢复精度。
  • 面试话术:这好比直接删除数组中的一列数据,剩下的矩阵结构依然规整,CPU处理起来依旧很快。

2.1.3 其他类型的方法

  • 基于梯度的剪枝:不仅考虑权重的大小,还考虑梯度信息。认为即使权重小,但如果梯度大(对loss影响大),也值得保留。
  • 自动剪枝:结合NAS(神经架构搜索),让算法自动搜索每一层的最佳剪枝率。

2.2 轻量级网络设计

核心思想:不同于剪枝的“大网络变小”,轻量级设计是从0到1直接设计出高效的“小网络”。

2.2.1 基于卷积结构的轻量级模型设计

  • 原理:设计新型的卷积计算模块来替代传统的标准卷积层,从而在保证特征提取能力的同时大幅降低参数量和计算量。

  • 经典案例

    • SqueezeNet:提出了Fire Module,利用1x1卷积来“压缩”通道数。
    • MobileNet V1:核心是深度可分离卷积,将标准卷积分成Depthwise Conv(逐通道卷积)和Pointwise Conv(逐点卷积),计算量骤降。
    • ShuffleNet V1:在组卷积后引入通道重排,解决组卷积导致的“信息流通不畅”问题。

2.2.2 基于卷积操作方法的轻量化模型设计

  • 原理:在保持结构基本不变的前提下,改进卷积操作的具体计算方式。

  • 经典案例

    • 空洞卷积:在不增加参数量的情况下,扩大感受野。
    • 可变形卷积:卷积核的采样点不再固定为矩形,而是根据特征图动态学习偏移量,更适合检测形状多变的目标,但通常会增加计算负担(轻量化设计有时是权衡)。
    • 动态卷积:根据输入动态地聚合多个并行的卷积核,提升模型表达能力而不必增加网络深度或宽度。

2.2.3 基于YOLO模型结构的轻量级模型

  • 原理:针对YOLO(You Only Look Once)系列这种单阶段检测器,进行专门的结构优化,使其适应边缘设备。

  • 经典案例

    • YOLOv5-n/s:通过调整深度和宽度因子(depth_multiple, width_multiple)缩放出的超小版本。
    • YOLOv8-n:YOLOv8的nano版本,是目前轻量级检测的热门选择。
    • YOLOX-Nano:引入解耦头等先进结构,但通过特殊设计控制参数量。

2.2.4 其他类型的方法

  • 注意力机制融合:在轻量级网络中嵌入高效的注意力模块(如SE模块、CBAM、ECA),以很小的计算代价换取精度提升。

2.3 网络自适应搜索 (NAS, Neural Architecture Search)

核心思想:不再由人工设计网络,而是让算法在给定的搜索空间(如卷积核大小、通道数、是否跳连等)中,根据某种策略自动搜索出性能最好的网络结构。

2.3.1 基于强化学习的NAS方法

  • 原理:将网络生成看作一个智能体(Agent)的动作,网络在验证集上的精度作为奖励(Reward),通过策略梯度等方法训练控制器(如RNN),使其生成更高奖励的网络。
  • 代表:Google的NASNet。
  • 特点:效果好,但计算资源消耗巨大(动辄几百上千GPU天)。

2.3.2 基于进化算法的NAS方法

  • 原理:将网络结构看作一个“个体”,通过变异(修改某一层)和交叉(混合两个网络)产生后代,根据适应度(精度)进行优胜劣汰。
  • 特点:并行性好,适合大规模搜索,但同样计算量大。

2.3.3 基于梯度的NAS方法

  • 原理:通过权重共享连续松弛,将离散的架构选择问题转化为连续变量的优化问题,从而可以用梯度下降进行端到端优化。
  • 代表:DARTS。
  • 特点:大大降低了计算成本,使得NAS可以在单卡GPU上几天内完成,是现在最主流的NAS方法之一。

2.3.4 其他类型的方法

  • 贝叶斯优化:将架构搜索视为黑箱优化问题。
  • 基于代理模型的NAS:训练一个预测器来预估未训练网络的精度,避免每次都从头训练。

2.4 网络量化 (Quantization)

核心思想:降低模型参数的数值精度,将浮点数(FP32)运算转换为低比特整数运算,减少内存占用和计算延迟。

2.4.1 二进制量化 (Binary)

  • 原理:将权重和激活值约束为+1或-1(1 bit)。

  • 特点

    • 优点:极致压缩,可以用位运算代替乘加运算,速度极快。
    • 缺点:大模型精度下降严重,通常只适用于简单任务或特定结构(如XNOR-Net)。

2.4.2 三元量化 (Ternary)

  • 原理:将权重约束为{-1, 0, +1}(2 bits)。
  • 特点:相比二进制保留了更多的表达能力,是精度与速度的折中。

2.4.3 聚类量化

  • 原理:不属于均匀/线性量化。通过K-means等算法将相近的权重视为一类,用聚类中心的值代替所有权重。存储时存索引,计算时查表。
  • 代表:Deep Compression。
  • 特点:非线性量化,对分布不均匀的权重效果好,但硬件支持度不如线性量化好。

2.4.4 其他类型的方法

  • 训练时量化:在前向传播中模拟量化误差,反向传播仍用浮点梯度,使模型学会适应低精度带来的噪声。
  • PTQ与QAT:分为训练后量化和量化感知训练。

2.5 知识蒸馏 (KD, Knowledge Distillation)

核心思想:用一个大的、训练好的教师模型(Teacher)去指导一个小学生模型(Student)学习。

2.5.1 输出迁移 (Response-based)

  • 原理:让学生模型模仿教师模型的软标签
  • 细节:不仅让学生的输出逼近真实标签(硬标签),还要通过软化(Temperature参数)后的logits逼近教师的输出。软标签包含了教师对类别间相似性的理解(例如:一张猫的图片,教师可能认为它80%像猫,15%像狗)。
  • 经典:Hinton的Distilling the Knowledge in a Neural Network。

2.5.2 特征迁移 (Feature-based)

  • 原理:让学生模型模仿教师模型的中间层特征图
  • 细节:教师网络中间层的特征图包含丰富的空间信息和纹理信息。通过设计损失函数(如L2 loss),让学生中间层的特征图尽可能与教师的一致(通常需要设计适配层来对齐维度)。
  • 代表:FitNets。

2.5.3 关系迁移 (Relation-based)

  • 原理:不关注单张图的特征,而是关注不同样本之间不同层之间的关系。
  • 细节:例如,计算教师模型中不同样本特征之间的相关性矩阵,让学生模型的特征也保持这种相关性。认为“关系的结构”比“具体的特征值”更容易迁移。

2.5.4 其他类型的方法

  • 自蒸馏:学生和教师是同一个模型,或者模型自身的深层教浅层。
  • 对比学习蒸馏:引入对比损失,拉近师生对同一张图的表征,推远对不同图的表征。

2.6 低秩分解 (Low-rank Factorization)

  • 原理:将大的权重矩阵(或卷积核)分解成几个小矩阵的乘积。例如,一个 m×nm×n 的矩阵,可以近似为 m×km×k 和 k×nk×n 的矩阵相乘(k<min⁡(m,n)k<min(m,n))。

  • 在卷积中的应用:将 3×33×3 的卷积分成 1×31×3 和 3×13×1 的卷积(空间可分离),或者将标准卷积分成 1×11×1 卷积降低通道数 + 3×33×3 卷积(类似深度可分离卷积的思想,但数学原理不同)。

  • 特点

    • 优点:理论上能大幅减少参数量。
    • 缺点:分解操作本身计算复杂;分解后需要从头训练才能收敛,且分解的低秩假设(全局信息冗余)并不总是成立,在CNN中应用不如RNN/全连接层广泛。
  1. 从网络本身下手(剪枝) :我们可以像修剪树枝一样,去掉不重要的连接或通道。
  2. 从架构源头下手(轻量级设计) :或者我们干脆一开始就设计一个高效的结构,比如MobileNet里的深度可分离卷积。
  3. 从精度下手(量化、蒸馏) :如果模型已经训好了,我们可以降低它的数值精度(量化),或者用一个大模型来教一个小模型(蒸馏)。
  4. 从矩阵运算下手(低秩分解) :还可以从数学角度,把大的权重矩阵拆成几个小矩阵,降低冗余。