0%

《Channel Pruning for Accelerating Very Deep Neural Networks》

译:《用于资源高效推理的卷积神经网络剪枝》

论文地址:Channel Pruning for Accelerating Very Deep Neural Networks

有代码,且个人感觉论文写的比前面的几篇更容易读一点。

Motivation

现有的CNN加速工作主要分为三类:优化实现、量化和结构简化,本文工作就是属于最后一类

结构简化主要又涉及到因式分解、稀疏连接和通道剪枝。其中张量因式分解的方法如图中(c)所示,是将卷积层分解成几个有效的小层,但特征图宽度(通道数量)不能被降低,这就使得其对于最近的GoogleNet、ResNet等依赖的\(1\times1\)卷积难以分解;而稀疏连接方法则是断开部分神经元或通道之间的连接,如图中(b),虽然它理论上能达到很高的加速比,但稀疏卷积层的形状不规则,实现起来不友好;而通道剪枝方法如图(d)则可以直接降低特征图宽度,从而将模型收缩到很瘦,并且实现友好。

通道剪枝简单但也有许多挑战,因为删除一个层的通道可能会极大地改变下一层的输入。最近提出的在基于训练的通道剪枝工作集中在训练过程中对权重添加稀疏约束,这样可以自适应确定超参数,但这种方法在深度CNN上训练成本会很高。Inference-time方法尝试集中于分析单个权重的重要性,但其加速比非常有限。

基于上述工作,作者提出了一种新的利用通道间冗余的推理时间的通道剪枝方法。受张量因式分解的启发,作者关注特征图间的冗余而不是分析滤波器的权重。

方法简介

具体地,给定一个训练好的CNN模型,通过最小化其输出特征图上的重构误差实现对每一层剪枝。作者通过两个步骤来解决这个最小化问题:

  1. 通道选择;基于LASSO回归找到最有代表性的通道,并对冗余通道进行剪枝
  2. 特征图重构;用线性最小二乘法重构通道的输出

公式表示

如前面的Figure 2所示的是单个卷积层的通道剪枝算法,需要在维持特征图C的输出的情况下降低特征图B的通道数,一旦通道被修剪,就可以删除将这些通道作为输入的滤波器对应的通道,同时也可以移除产生这些通道的滤波器。由此,通道剪枝明显涉及两个关键点:通道选择和重构,通道选择是因为需要选择可以保留尽可能多信息的合适的通道;重构是需要使用选择的通道重构特征图。

基于这些,在通道选择阶段,需要选择最有代表性的通道,而因为完全搜索的方法只对小模型有用,作者就提出了使用基于LASSO回归的方法来找出有代表性的通道,并对冗余通道进行剪枝;而在重构阶段,则是使用线性最小二乘法重构剩余通道的输出。这样交替采用两个步骤。

正式地,为了对一个有\(c\)个通道的特征图进行剪枝,作者将\(n\times c\times k_h\times k_w\)卷积滤波器\(W\)应用到从这个特征图中采样的\(n\times c\times k_h\times k_w\)的输入\(X\),产生\(N\times n\)的输出矩阵\(Y\),这里\(N\)是采样数量,\(n\)是输出通道数,\(k_h,k_w\)是滤波器大小,为简单表示,偏置项没有包含进去。

为了在最小化重构误差情况下,将输入通道从\(c\)剪枝为\(c'(0\le c'\le c)\)可表示为: \[ \arg \min_{\beta,W} \frac{1}{2N} ||Y-\sum_{i=1}^c \beta_i X_i W_i^T||_F^2 \quad s.t.||\beta||_0 \le c' \quad (1) \] \(||.||\)是 Frobenius范数,\(X_i\)是从输入\(X\)的第\(i\)个通道切片的\(N\times k_hk_w\)矩阵(\(i=1,\cdots,c\)),\(W_i\)是从\(W\)的第\(i\)个通道切片的\(n\times k_hk_w\)滤波器权重,\(\beta\)是用于通道选择的长度为\(c\)的系数矢量,\(\beta_i\)是第\(i\)个通道的标题掩码,这里如果\(\beta_i=0\),则\(X_i\)将不再有用,可以从特征图中安全地剪掉。\(W_i\)也可以被移除,\(c'\)是剩余通道数,这是手动设置的,因为它可以根据所需要的加速比来计算。

对于整个模型加速,在给定整个模型加速比的情况下,首先给每层分配加速比,然后计算每个\(c'\)

优化

解决上述等式的\(\ell_0\)最小化问题是NP难的,因此,作者将\(\ell_0\)放宽为\(\ell_1\)正则化: \[ \arg \min_{\beta,W}\frac{1}{2N}||Y-\sum_{i=1}^c \beta_iX_iW_i^T||^2_F + \lambda ||\beta||_1 \quad s.t. ||\beta||_0 \le c',\forall i || W_i||_F=1 \] \(\lambda\)是惩罚系数,通过增加\(\lambda\)可以在\(\beta\)中有更多零项,从而获得更高的加速比,作者也添加了一个限制\(\forall i||W_i||_F=1\)来避免琐碎的解决方案。

现在分两步解决这个问题,首先固定\(W\)为通道选择求解\(\beta\),然后对\(\beta\)固定求\(W\)来重构误差。

1. \(\beta\)的子问题

固定了\(W\)求解\(\beta\),可以使用LASSO回归: \[ \hat \beta^{LASSO}(\lambda) = \arg \min_\beta \frac{1}{2N} ||Y - \sum_{i=1}^c\beta_iZ_i||_F^2+\lambda ||\beta||_1 \quad s.t.||\beta||_0 \le c' \] 这里\(Z_i=X_iW_i^T\),如果\(\beta_i=0\)就忽略第\(i\)个通道

2. \(W\)的子问题

固定了\(\beta\),就可使用最小二乘法解决: \[ \arg \min_{W'}||Y-X'(W')^T||_F^2 \] 这里的\(X'=[\beta_1X_1\quad \beta_2X_2 \quad \cdots \beta_iX_i \quad \beta_cX_c]\)\(W'=[W_1 \dots W_i \dots W_c]\),最获得结果\(W'\)后再reshape回\(W\),然后赋值\(\beta_i\leftarrow \beta_i||W_i||_F,W_i\leftarrow W_i/||W_i||_F\),满足限制\(\forall i||W_i||_F=1\)

这里轮流使用上述两个步骤,在开始时,使用训练好的模型初始化\(W\)\(\lambda=0\),即不受惩罚,\(||\beta||_0=c\),然后慢慢增加\(\lambda\),对\(\lambda\)的每次改变,都会迭代使用这两步,直到\(||\beta||_0\)稳定,在\(||\beta||_0\le c'\)后,从\(\{\beta_iW_i\}\)获得最终解\(W\),实际上作者发现这两步迭代非常耗时,因此作者选择使用第一步多次,直到\(||\beta||_0 \le c'\),然后再使用第二步一次就可以获得最终结果。

讨论

最近很多工作也会引入 \(\ell_1\)正则化或LASSO方法,但作者强调他们的方法是不同的,其它人使用的是将稀疏正则化引入训练损失,而不是显式解决LASSO。

整个模型剪枝

对于多层,作者采用逐层应用单层方法进行模型剪枝,对于每一层,从当前输入特征图中获取输入,并从未剪枝模型的输出特征图获得输出,可表示为: \[ \arg \min_{\beta,W} \frac{1}{2N} ||Y'-\sum_{i=1}^c\beta_iX_iW_i^T||_F^2 \quad s.t. ||\beta||_0\le c' \] 这里的\(Y'\)是来自原始模型的特征图,因此,累计误差可以在顺序剪枝过程中考虑到。

多分支网络剪枝

上述主要是在单分支网络,然而对多分支网络则有些不够,这部分作者主要研究的是剪枝残差结构。如下图,给定残差块,在残差分支有一些卷积层,除了第一层和最后一层的其它层则可以像之前一样剪枝。在第一层,挑战在于输入特征图宽度较大,难以剪枝,因为它与shortcut共享;在最后一层,由于shortcut上没有参数,所以shortcut的累积误差很难恢复。基于这些,作者提出一些他们的解决方案:

残差分支的最后一层

残差块的输出层由两部分组成:来自shortcut和残差分支的特征图\(Y_1\)\(Y_2\),目的是要为这个块恢复\(Y_1+Y_2\),这里的\(Y_1,Y_2\)都是剪枝前的原始特征图,\(Y_2\)可以通过式\((1)\)估计,而shortcut分支是无参数的,所以\(Y_1\)是无法直接恢复的,为了补偿这个误差,最后一层的优化目标就从\(Y_2\)变为了\(Y_1-Y_1'+Y_2\),这里的\(Y_1'\)是经过剪枝了的前一层的当前的特征图

残差分支的第一层

残差块的输入特征图不能被前去,因为其和shortcut分支共享,在这种条件下,作者在第一个卷积前使用特征图采样来保存计算,然后照样使用公式\((1)\),不同的是,对共享特征图上所选择的通道进行采样来构建用于后面卷积的新输入。

还有基于滤波器剪枝是另一种用于残差分支剪枝的方式,但由于其微调后表现不是那么好且输出是不规则卷积层,因此没有采用