《Building Efficient ConvNets using Redundant Feature Pruning》论文笔记

1. 概述

一般在做模型的时候开始最关心的是模型的性能,也就是模型的精度,我们可以增加网络的宽度与深度,来不断增加模型的表达能力。在精度达标之后,网络也变地很臃肿了,其实里面很多的参数都是非必须的,也就是冗余的。如何去掉这些冗余呢?在之前的文章中讲到了了几种方法,这篇论文中给出的方法与之前的方法思路不同,是按照聚类的思想来去除冗余的filters,从而减少网络中filters的数量,达到网络剪裁的目的。在文章中给出了filter之间相似度的度量方法,并用这个度量方法作为filter合并的依据。
论文地址:Building Efficient ConvNets using Redundant Feature Pruning
代码地址:Redundant-Feature-Pruning-Pytorch-Implementation

2. 实现

这篇文章中涉及到的剪枝方法示意图见下图:
在这里插入图片描述
在图1中 Z Z Z代表feature map, W W W代表filters。这里假设 ϕ 1 \phi_1 ϕ1是filter的聚类表达,那么 ϕ 3 , ϕ 5 \phi_3, \phi_5 ϕ3,ϕ5由于与 ϕ 1 \phi_1 ϕ1的相似性高,那么基于冗余去除原则,其在 Z l + 1 Z_{l+1} Zl+1中的feature map与 W l + 1 W^{l+1} Wl+1中对应的部分会被删除掉。
这里涉及到这些filter是之间距离度量函数的选择问题。首先,将每个filter作为一个聚类的中心,然后将其中的聚类中心,按照阈值 τ \tau τ进行合并(大于这个阈值那就合并,小于该阈值不合并),其合并的距离度量可以使用下面的方式进行描述:
在这里插入图片描述
其中, S I M C ( ϕ 1 , ϕ 2 ) = &lt; ϕ 1 , ϕ 2 &gt; ∣ ∣ ϕ 1 ∣ ∣ ∣ ∣ ϕ 2 ∣ ∣ SIM_C(\phi_1, \phi_2)=\frac{&lt;\phi_1, \phi_2&gt;}{||\phi_1|| ||\phi_2||} SIMC(ϕ1,ϕ2)=ϕ1ϕ2<ϕ1,ϕ2>是两个特征之间的cos距离度量, &lt; ϕ 1 , ϕ 2 &gt; &lt;\phi_1, \phi_2&gt; <ϕ1,ϕ2>是特征的内积。

基于冗余特征裁剪在 l t h l^{th} lth卷积层的使用可以归纳为如下步骤:
1)对filters ϕ i \phi_i ϕi进行聚类得到 n f n_f nf个聚类中心,使用阈值 τ \tau τ
2)考虑两种启发式方式:(A)在 n f n_f nf个聚类中心中随机选取一个filter,然后去剪裁剩余的filters与其对应的feature map;(B)随机剪裁掉 n ′ − n f n^{&#x27;} - n_f nnf个filters和其对应的feature map。在后面一层 ( l + 1 ) t h (l+1)^{th} (l+1)th中的对应参数也需要剪裁掉。对于这两种不同的策略,论文在后面也对其做了实验分析,详见后文。
3)得到 l t h l^{th} lth ( l + 1 ) t h (l+1)^{th} (l+1)th新的kernel矩阵。

3. 实验结论

首先,来看一下论文整体的性能吧,这里也比较了上面提到的A、B两种启发式策略,并比较了两种策略的结果
在这里插入图片描述
之后在每个层上按照之前的两个方案进行裁剪,得到下图的前两个,之后进行finetune得到下图:
在这里插入图片描述
可以看到方案A的曲线比方案B的曲线更加柔和一点。

3.2 ResNet网络

这篇论文中没有涉及到对shortcut连接两端的剪裁,而是只操作了残差块的第一个卷积。实验的讨论和刚才看的VGG网络的一样。首先是各层上冗余度与阈值的关系
在这里插入图片描述
ResNet-56中各层裁剪比例与错误率的关系
在这里插入图片描述

4. 代码实现

论文中的算法在上面给出了代码链接,代码量还是比较少的,核心的函数就一个,这里给出我对它的理解:

'''/*
函数功能:对权重按照给出的阈值进行聚类,返回聚类之后的中心数目与对应的index
weight:聚类的权重,维度为[n_features, n_samples]
threshold:阈值控制聚类的程度,越大表示结果聚类数目越多
*/
'''
def cluster_weights_agglo(weight, threshold, average=True):
    t0 = time.time()
    weight = weight.T
    weight = normalize(weight, norm='l2', axis=1)
    threshold =  1.0-threshold   # Conversion to distance measure
    clusters = hcluster.fclusterdata(weight, threshold, criterion="distance", metric='cosine', depth=1, method='centroid')
    z = hac.linkage(weight, metric='cosine', method='complete')
    labels = hac.fcluster(z, threshold, criterion="distance")

    labels_unique = np.unique(labels)
    n_clusters_ = len(labels_unique)

    #print(n_clusters_)
    elapsed_time = time.time() - t0
    # print(elapsed_time)

    a=np.array(labels)
    sort_idx = np.argsort(a)
    a_sorted = a[sort_idx]
    unq_first = np.concatenate(([True], a_sorted[1:] != a_sorted[:-1]))
    unq_items = a_sorted[unq_first]
    unq_count = np.diff(np.nonzero(unq_first)[0])
    unq_idx = np.split(sort_idx, np.cumsum(unq_count))
    first_ele = [unq_idx[idx][-1] for idx in xrange(len(unq_idx))]
    return n_clusters_, first_ele
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值