1. 概述
一般在做模型的时候开始最关心的是模型的性能,也就是模型的精度,我们可以增加网络的宽度与深度,来不断增加模型的表达能力。在精度达标之后,网络也变地很臃肿了,其实里面很多的参数都是非必须的,也就是冗余的。如何去掉这些冗余呢?在之前的文章中讲到了了几种方法,这篇论文中给出的方法与之前的方法思路不同,是按照聚类的思想来去除冗余的filters,从而减少网络中filters的数量,达到网络剪裁的目的。在文章中给出了filter之间相似度的度量方法,并用这个度量方法作为filter合并的依据。
论文地址:Building Efficient ConvNets using Redundant Feature Pruning
代码地址:Redundant-Feature-Pruning-Pytorch-Implementation
2. 实现
这篇文章中涉及到的剪枝方法示意图见下图:
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/21e585a7e21fc7dc.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21fYnVkZHk=,size_16,color_FFFFFF,t_70)
在图1中ZZZ代表feature map,WWW代表filters。这里假设ϕ1\phi_1ϕ1是filter的聚类表达,那么ϕ3,ϕ5\phi_3, \phi_5ϕ3,ϕ5由于与ϕ1\phi_1ϕ1的相似性高,那么基于冗余去除原则,其在Zl+1Z_{l+1}Zl+1中的feature map与Wl+1W^{l+1}Wl+1中对应的部分会被删除掉。
这里涉及到这些filter是之间距离度量函数的选择问题。首先,将每个filter作为一个聚类的中心,然后将其中的聚类中心,按照阈值τ\tauτ进行合并(大于这个阈值那就合并,小于该阈值不合并),其合并的距离度量可以使用下面的方式进行描述:
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/d34245582687a4e6.webp)
其中&#xff0c;SIMC(ϕ1,ϕ2)&#61;<ϕ1,ϕ2>∣∣ϕ1∣∣∣∣ϕ2∣∣SIM_C(\phi_1, \phi_2)&#61;\frac{<\phi_1, \phi_2>}{||\phi_1|| ||\phi_2||}SIMC(ϕ1,ϕ2)&#61;∣∣ϕ1∣∣∣∣ϕ2∣∣<ϕ1,ϕ2>是两个特征之间的cos距离度量&#xff0c;<ϕ1,ϕ2><\phi_1, \phi_2><ϕ1,ϕ2>是特征的内积。
基于冗余特征裁剪在lthl^{th}lth卷积层的使用可以归纳为如下步骤&#xff1a;
1&#xff09;对filters ϕi\phi_iϕi进行聚类得到nfn_fnf个聚类中心&#xff0c;使用阈值τ\tauτ&#xff1b;
2&#xff09;考虑两种启发式方式&#xff1a;&#xff08;A&#xff09;在nfn_fnf个聚类中心中随机选取一个filter&#xff0c;然后去剪裁剩余的filters与其对应的feature map&#xff1b;&#xff08;B&#xff09;随机剪裁掉n′−nfn^{&#x27;} - n_fn′−nf个filters和其对应的feature map。在后面一层(l&#43;1)th(l&#43;1)^{th}(l&#43;1)th中的对应参数也需要剪裁掉。对于这两种不同的策略&#xff0c;论文在后面也对其做了实验分析&#xff0c;详见后文。
3&#xff09;得到lthl^{th}lth与(l&#43;1)th(l&#43;1)^{th}(l&#43;1)th新的kernel矩阵。
3. 实验结论
首先&#xff0c;来看一下论文整体的性能吧&#xff0c;这里也比较了上面提到的A、B两种启发式策略&#xff0c;并比较了两种策略的结果
![在这里插入图片描述](https://img.php1.cn/3cd4a/1e618/c5a/d5d40da532c3a782.png?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21fYnVkZHk&#61;,size_16,color_FFFFFF,t_70)
之后在每个层上按照之前的两个方案进行裁剪&#xff0c;得到下图的前两个&#xff0c;之后进行finetune得到下图&#xff1a;
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/7d7ef3f69d479716.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21fYnVkZHk&#61;,size_16,color_FFFFFF,t_70)
可以看到方案A的曲线比方案B的曲线更加柔和一点。
3.2 ResNet网络
这篇论文中没有涉及到对shortcut连接两端的剪裁&#xff0c;而是只操作了残差块的第一个卷积。实验的讨论和刚才看的VGG网络的一样。首先是各层上冗余度与阈值的关系
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/b428d8f746fb8d47.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21fYnVkZHk&#61;,size_16,color_FFFFFF,t_70)
ResNet-56中各层裁剪比例与错误率的关系
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/eec57030b649a106.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21fYnVkZHk&#61;,size_16,color_FFFFFF,t_70)
4. 代码实现
论文中的算法在上面给出了代码链接&#xff0c;代码量还是比较少的&#xff0c;核心的函数就一个&#xff0c;这里给出我对它的理解&#xff1a;
&#39;&#39;&#39;/*
函数功能&#xff1a;对权重按照给出的阈值进行聚类&#xff0c;返回聚类之后的中心数目与对应的index
weight&#xff1a;聚类的权重&#xff0c;维度为[n_features, n_samples]
threshold&#xff1a;阈值控制聚类的程度&#xff0c;越大表示结果聚类数目越多
*/
&#39;&#39;&#39;
def cluster_weights_agglo(weight, threshold, average&#61;True):t0 &#61; time.time()weight &#61; weight.Tweight &#61; normalize(weight, norm&#61;&#39;l2&#39;, axis&#61;1)threshold &#61; 1.0-threshold clusters &#61; hcluster.fclusterdata(weight, threshold, criterion&#61;"distance", metric&#61;&#39;cosine&#39;, depth&#61;1, method&#61;&#39;centroid&#39;)z &#61; hac.linkage(weight, metric&#61;&#39;cosine&#39;, method&#61;&#39;complete&#39;)labels &#61; hac.fcluster(z, threshold, criterion&#61;"distance")labels_unique &#61; np.unique(labels)n_clusters_ &#61; len(labels_unique)elapsed_time &#61; time.time() - t0a&#61;np.array(labels)sort_idx &#61; np.argsort(a)a_sorted &#61; a[sort_idx]unq_first &#61; np.concatenate(([True], a_sorted[1:] !&#61; a_sorted[:-1]))unq_items &#61; a_sorted[unq_first]unq_count &#61; np.diff(np.nonzero(unq_first)[0])unq_idx &#61; np.split(sort_idx, np.cumsum(unq_count))first_ele &#61; [unq_idx[idx][-1] for idx in xrange(len(unq_idx))]return n_clusters_, first_ele