核心思想
通道裁剪的效果
细节补充
"看图说话"
目标函数解读
论文题目: Channel Pruning for Accelerating Very Deep Neural Networks
文献地址:https://arxiv.org/pdf/1707.06168.pdf
源码地址:https://github.com/yihui-he/channel-pruning
最近,在进行YOLOv3,v4的模型压缩,浅层压缩中的裁剪和知识蒸馏是压缩现有模型常用的方法(关于模型加速的概述猛戳这里),通过概述可以了解到浅层压缩的裁剪(剪枝)主要包括权重剪枝,通道剪枝,核剪枝和神经元剪枝几个分支。通道裁剪(channel pruning)相对于权重裁剪是一种粗粒度的裁剪方式,其直接删除feature map的一些通道。这些通道是怎么选取的,删除通道的数量又是如何控制的?这些将由本篇来揭晓,该论文是ICCV2017的文章。
核心思想
对训练好的模型进行通道剪枝,也就是基于基础模型训练之后。针对删除通道的选择以及删除通道数量的控制,作者主要通过以下两步操作进行:
step 1:channel selection,通道的选择是通过LASSO regression来做的,也就是在损失函数中添加L1范数对权重进行约束,以目标函数优化的角度考虑,L1范数可以使得权重中大部分值为0,使得通道内权重具有稀疏性,从而可以将系数的channel剪掉。
step 2:feature map reconstruction,删除通道的数量是不太容易优化的,可以通过建立某种目标更直接的达到通道剪枝力度的控制,就是希望剪枝后输出的feature map和剪枝前输出的feature map差异越小越好,很容易想的到,这一目标可以建立基于linear least squares(最小二乘or最小平方)实现。
加速效果
For VGG-16, we achieve 4× acceleration, with only 1.0% increase of top-5 error. Combined with tensor factorization, we reach 5× acceleration but merely suffer 0.3% increase of error, which outperforms previous state-of-thearts. We further speed up ResNet-50 and Xception-50 by 2× with only 1.4%, 1.0% accuracy loss respectively.
从加速效果来看,通道裁剪在VGG、ResNet-50、Xception-50等现有backbone上具有明显的加速效果,且不会带来严重的精度损失。
通道裁剪的效果
下图是以VGG16为backbone,对channel selection的方式的实验对比结果。其中first k 表示抽取前k个channel作为剪枝后的channel。(...有点任性)max response表示选取卷积核权重绝对值最大的一些channel作为剪枝后的channel。可以看出,随着层数的加深,剪枝的难度是逐渐上升的。这表明在浅层中存在更多的冗余channel,这在一定程度上也表明对模型做channel pruning时,浅层和深层剪枝的力度应该是不同的。
下表是对整个VGG-16网络做通道剪枝的结果,可以看出在2×加速的时候甚至没有影响到准确率。
下表是将加速算法用在object detection算法上的表现,这里是以Faster RCNN为例。
细节补充
"看图说话"
首先,作者列举了其他两种常见的简化网络结构的操作:sparse connection(图b)和tensor factorization(图c),如下图所示。
(a)传统的3层卷积操作;
(b)sparse connection,这是通过去掉一些参数很小的连接得到的,理论上是有明显的加速效果的,但是在实现过程中并不容易,主要因为稀疏连接层的形状不规则。
(c)tensor factorization,比如SVD分解,但是这种操作其实并不会减少channel数量,因此很难带来明显加速。
(d)本文的通道剪枝(channel pruning),剪掉一些冗余的channel,相当于给网络结构瘦身,不会影响网络结构的整体性,没有牵一发而动全身的影响。
下图是对卷积层进行通道剪枝的示意图。先看右图虚线框内的内容。其中,字母B表示输入的feature map,c表示B的通道数量,可以看出B是经过通道裁剪后的feature map。W表示卷积核,kh和kw表示卷积核的尺寸,因此,每个卷积核的维度为c*kh*kw。由于feature map的部分通道裁剪,因此,相对应的卷积核的通道也没有存在的价值,也要被裁剪掉。 C表示输出的feature map,n为输出feature map的通道数量,也是W卷积核的个数,从C的形态可以看出,C的维度只和卷积核的个数有关,并且输出是完整的,也就是说,通道裁剪的过程并不会对下一层卷积造成影响,只是影响卷积内部的运算,说白了也就是参数量和计算量。
因此,剪枝需要解决的问题就是剪掉谁,如何保证剪掉后对精度没有影响。(怎么突然想到了公司裁员...)
目标函数解读
这种问题解决都离不开优化,也就需要建立目标函数,神经网络中通常通过损失函数来刻画,即给予机器学习的指引。
出于优化的角度,对于feature map通道需要剪掉谁,保留谁的问题,可以通过优化一个二值决策变量(0,1,其中,0表示裁剪,1表示保留)解决,即如下式中的βi。其中,c表示通道数量,i为通道数量的索引,Xi和Wi分别对应输入feature map和卷积核的每个通道。因此,很容易理解,βi为0时,相当于该通道无作用,即裁减掉;βi为1时,表示保留。
对于保证裁剪掉后对精度没有影响的问题,可以通过最小二乘的方式解决。即下式中的F范数。c'表示剪枝后feature map的通道数量,通过对β的零范数限制裁剪力度下限,零范数表示β中非零值的数量。
由于零范数的存在,上式是无法直接优化求解的,需要将L0范数转化为L1范数。并将约束项以惩罚项的形式添加到目标函数中,惩罚项λ可以控制β中非零值的数量,λ越大,惩罚越严重,β中非零值越少,模型加速力度比较大;同理,λ越小,惩罚相对较弱,β中的非零值就会多一些。另外||Wi||F=1是用来约束W的唯一解。
因此,需要优化的变量包含两个,一个是β,另一个是W。对于这样的优化问题,通常会采用两步走的方式,即固定W,优化β;再固定β,优化W。
- 固定W,优化β可以通过LASSO regression
- 固定β,求解W,可以通过最小二乘:
优化中的一个细节是前面公式中的λ是在迭代过程中不断增大的,直到||β||0稳定以后就不增大了。
前面介绍的都是对于网络没有分支情况下的通道剪枝,但是现在的ResNet、GoogleNet网络都有多分枝,对于这种网络,文中以ResNet为例也做了分析。首先,在这个residual block中,除了第一层和最后一层外的其他层都可以采用前面介绍的通道剪枝方式进行剪枝。针对第一层,因为原来其输入feature map的通道数是输出的4倍,因此在剪枝之前先对输入feature map做sample。针对最后一层的通道剪枝,由原来对Y2来优化,改成对Y1-Y1'+Y2来优化(Y1和Y2表示剪枝之前的输出),Y1'表示前面层剪枝后得到的结果(也就是该residual block的输入,只不过和Y1不同的是该输入是前面层剪枝后得到的结果),否者shortcut部分带来的误差会对结果影响较大。