参数剪枝相关研究 F 2017 - glqglq/ml_dl_wiki GitHub Wiki

PRUNING FILTERS FOR EFFICIENT CONVNETS

  • Motivation:
    • 领域存在问题:
      • dl计算密集、存储密集、功耗高、内存占用大、不实时、不隐私,难以部署在嵌入式设备上
    • 现有方法存在问题:
      • 现有剪枝:
        • 韩松剪枝:
          • 由于不规则的稀疏性,使得全连接修剪效果较好,卷积层修剪效果差。
          • 剪全连接使得参数量变小,但是推理速度没有提升。
          • 需要稀疏卷积库,维护稀疏库也会产生额外开销。
          • 剪枝、retrain两步骤。
        • 卷积核评估剪枝:
      • 现有精细结构设计:虽然参数量小了,但是层数越来越深,卷积层越来越多,速度没提升。
      • 现有低秩分解:不改变卷积核数量
      • 现有底层优化:
      • 现有量化:
    • Method:
      • 剪枝评价指标:对于某一层的若干filter,用l1 norm来求得卷积核的重要程度,因为值小的卷积核生成的特征图值也小,然后sort,然后取top。
        • 不使用『filter所有filter低于某一阈值就减掉』的方法,因为该方法需要调阈值。
        • 不使用l2 norm的方法,因为该方法和l1效果差不多。
      • 某层修剪率评价指标:
        • 每一卷积层进行单独剪枝,查看在validation set上准确度的变化,发现『保留权重比例-sort后的保留权重的l1』图中曲线下面积越大的越敏感(不能修剪太多)。
        • 对于VGG-16, 一些卷积层的filter数量是一样的,所以对于差不多 Sensitivity 的卷积层,使用相同的比例进行剪枝,而对于 Sensitivity 比较大的,选择最小的比例进行剪枝或者不进行剪枝
      • 多层剪枝策略:
        • 整体修剪不逐层修剪:
          • 避免耗时
          • 从整体考虑,避免局部性
          • 对于复杂的网络,一个整体的方法很有必要,比如对于ResNet,对恒等映射特征图或者每个残差模块的第二个层剪枝会导致额外层的修剪
        • 独立剪枝:计算sum的时候不考虑上一层被剪掉的feature map。
        • 贪心剪枝:计算sum的时候考虑到上一层被被剪掉的feature map。不是全局最优,但是整体性好,剪枝后的网络精度高。
        • 残差网络的处理:
          • 第一层随意裁剪,因为它只会影响Xi+1的输入,但是不会影响最后的输出。
          • residual block里面的裁剪需要注意,因为裁剪需要和shortcut layer保持一致,才能累加。
          • 因为identical feature maps比added residual maps更重要,所以后者的裁剪结果应该由前者决定。
          • 即residual block中第二层修剪的Filter index与shortcut layer中的1×1卷积核所选择的Filter index相同,注意:这里的resnet的不是恒等映射,其中有1×1卷积。
      • retrain:敏感层retrain难以恢复,用第二种方法较好。
        • 修剪所有后重训练
        • 修剪一层后重训练

Channel Pruning for Accelerating Very Deep Neural Networks

  • Motivation:
    • 现有方法存在问题:
      • 现有矩阵分解:特征图个数不能减少,对于1*1卷积核不能压缩,加入别的计算量。
      • 现有W剪枝:卷积层剪的形状不规律,得用专用加速库。
      • 现有F剪枝:每层通道剪枝后会影响下一层输入,剪枝过程计算量大,没有进行大规模数据集、模型实验。
  • Method:目的是要把某些卷积核剪掉,使得剪掉后的卷积核W和从feature maps中采样出的子feature maps的卷积结果矩阵能尽可能和原始的卷积得到的矩阵Y接近,这里用矩阵乘法来表示卷积,把特征图给拆出来了,前面加上了稀疏β,方便进一步修剪。
    • loss设计:增加lambda,β会更稀疏,β=0时对应的卷积核被删除。使用L1范数代替原来β的L0范数,因为L0难以优化,而且有数学证明L1范数可以替换L0范数。另外||Wi||F=1是用来约束W的唯一解。

    • 两步优化:开始lambda为0,逐渐增加lambda,运行下面两步直到β稳定且小于规定压缩值。为了节约时间起见,可以执行多次第一步执行一次第二步,两种是差不多的。

      • 先固定W优化β:这步可以看做为lasso regression。
      • 再固定β优化W:具体转换看论文。
    • 针对多branch网络:

      • 在这个residual block中,除了第一层和最后一层外的其他层都可以采用前面介绍的通道剪枝方式进行剪枝。
      • 针对第一层,因为其输入feature map的通道数是输出的4倍,因此在剪枝之前先对输入feature map做sample。
      • 针对最后一层的通道剪枝,由原来对Y2来做近似优化,改成对Y1-Y1‘+Y2来做近似优化(Y1和Y2表示剪枝之前的输出),Y1’表示前面层剪枝后得到的结果(也就是该residual block的输入,只不过和Y1不同的是该输入是前面层剪枝后得到的结果),否则shortcut部分带来的误差会对结果影响较大。 

ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression

  • Motivation:
    • 现有方法存在问题:
      • 剪枝:一些基于二阶导数的方法有昂贵的计算成本;韩松方法需要底层软硬件加速、忽略了缓存和内存访问问题(由random connectivity导致的缓存局部性差、跳跃内存访问)、网络结构被破坏导致很难后续再用别的方法(如量化);现有的结构化剪枝not directly related to the final loss。
      • 低秩近似、量化:可以和剪枝互补。
  • Method:
    • ThiNet剪枝框架:
      • 滤波器选择,利用layer i+1 的input channels来选择剪枝layer i哪些部分。如果我们可以用第i+1层的输入channel的一个子集作为第i+1层的输入且经过对应的filter后近似得到第i+1层的输出,那么这个子集以外的channel就可以去掉了,因为第i+1层的一个输入channel对应第i层的一个filter(卷积核),因此去掉第i+1层的channel同时也就可以去掉第i层的filter。
      • 剪枝
      • 微调:为节省时间,对一层剪枝后仅训练一两个epochs,当整个网络都剪枝后,再训练足够多轮。
      • 循环至第一步对下一层网络剪枝。
    • 通道重要性选择:
      • 如果i层某filter被去掉,则对应的i+1层的特征图输入和输入filter被去掉,因为i+1层的输出filter数不变,则i+2层不会受影响。
      • 假设:如果去掉i层的某些filter却对i+2层的输入影响很小,则整体模型表现也不会有影响。
      • loss推导:这里|T|远小于|S|。
        image image
      • 贪心策略:
        image

Designing Energy-Efficient Convolutional Neural Networks using Energy-Aware Pruning

  • Motivation:
    • 功耗不光和flops等有关,还和memory access(如从DRAM中获取数据)等有关,memory access和CNN形状(filter size、特征图size、filter数、通道数)有关。数据重用导致相同的数据值用于多个MAC操作。这意味着一些数据比其他数据对能量的影响更大,因为它们被更频繁地访问。CONV层比FC层有更显著的数据重用现象。由于现在的DRAM都有多级缓存,所以需要最小化在多级缓存下的总能耗是关键。
    • 往常的剪枝算法都是单独剪枝,没有考虑对输出的联合影响。
  • Method:
    • 对于每层:
      • 基于能量确定网络层的修剪顺序:能量越高的层,越能够实现更高的压缩比。具体的计算框架基于作者的另外一篇论文:E_data+E_comp,E_data是从内存中取出数据的消耗,E_comp是计算消耗。
      • 使用简单的基于量值的修剪方法来快速去除高于目标压缩比的权重,用这种方法来快速的进行初始剪枝,如果剪枝比例大会导致权重相关性被打乱。
      • 将对减小输出误差具有最大影响的相关权重恢复到其原始非零值以达到目标压缩比,作者将最小化输出特征图的误差(不是最小化filter误差)问题建模为L0最小化问题。q是希望在filters中保留的非0权重数。si是每个filters具有相应的非零权重的索引。使用贪心算法求解:
        image
        • 在每次迭代中,通过减少那些没在si中的权重个数使得L1范数损失变小,选择影响L1变化最大的权重,对其添加非零权重的索引si。
        • 为了加速恢复过程,在每次迭代中恢复给定过滤器中的多个权重。因此,选择具有最高的g个使得最大L1范数改进的g个权重,计算时减少了每个权重残差改进的频率,否则这需要很长时间。
      • 局部fintune: 利用闭式最小二乘解对局部权重进行局部微调,以进一步减少输出特征映射误差。 image
    • 对于全局:使用反向传播来微调。

Learning Efficient Convolutional Networks through Network Slimming

  • Motivation:
    • 现有方法存在问题:
      • 低秩分解:全连接层表现好,不用于卷积层,不能进行模型整体加速。
      • 量化:hash等方法不能节约运行时的内存或推理时间,因为模型权重会在推理时进行restore。二值化网络acc太低。
      • 非结构化剪枝:需要特制软硬件加速,内存减少很有限,因为filter权重不占空间特征图占空间。
      • 结构化剪枝:
        • 剪枝粒度太大(如修剪层)只对很深的网络有效。
        • 网络中接近0的值太少了,一般用稀疏正则(group LASSO)来使权重稀疏化,该方法需要计算附加正则项对于所有卷积核权重的梯度,复杂度高。
      • AutoML:搜索空间大,训练复杂。
  • Method:
    • 使用缩放因子Γ:
      image
      • 次梯度下降法作为不平滑(不可导)的L1惩罚项的优化方法。
      • 平滑的L1正则项取代L1惩罚项,尽量避免在不平滑的点使用次梯度。
    • 使用bn层缩放因子Γ:
      • 如果我们不使用BN层,而在卷积层之后加入一个缩放层:缩放因子的值对于评估一个通道的重要性没有任何意义,因为卷积层和缩放层就是一种线性变换而已。
      • 如果我们在BN层之前插入一个缩放层,缩放层的影响将完全被BN层所掩盖;
      • 如果在BN层之后插入一个缩放层,那么对于每个通道将会有两个连续的缩放因子。
    • multi-pass方案:多次瘦身。