首页 > 代码库 > 利用ReLU输出稀疏性加速卷积

利用ReLU输出稀疏性加速卷积

一篇讲利用ReLU输出的稀疏性来加速卷积计算的论文,其目的和另一篇文章《More is less》 有点类似。

实验效果似乎还不错,但似乎并没有很大的创新。

文章链接: 《Speeding up Convolutional Neural Networks By Exploiting the Sparsity of Rectifier Units》

Motivation

下图的结论是:使用ReLU作为激活函数的网络,其网络输出通常都非常稀疏。

技术分享

另一方面,目前的稀疏矩阵运算效率并不高。

Method

只要弄明白卷积的机制,就很容易明白本文干了什么。

通常使用ReLU作为激活函数会导致输出很稀疏,从而也使得后续的卷积输入变得稀疏。 如下图所示,假如输入feature map维度为 \(4\times 4\times 2\),非常稀疏只有一个非零值0.4; 再假如有4个 \(2\times 2\times 2\)的卷积核,且卷积步长为2。 则中间的图示,即是传统的im2col+GEMM的卷积计算方式。

可以看出,这种计算存在非常大的冗余。 本文的方法,不计算完整的矩阵乘法,而是只计算非0值导致的输出。并且,充分利用AVX或者SSE指令完成 \((1\times1) \times (1\times4) \)的乘法。

技术分享

Experiments

作者只对稀疏度大于0.6的层进行处理,估计是稀疏度太小时这种操作肯定没有专业的Blas库快。

技术分享

总结:

(1) 不需要额外的训练,只需要修改卷积的实现,基本上是工程优化的任务;

(2) 整体的加速效果,跟输入的稀疏性有着直接关系,但是就我观察,很多网络的ReLU输出虽然比较稀疏,但稀疏度大于0.6的并不多;

(3) 可以考虑对网络每层的输出加入类似1范数Loss的约束,人为地使输出更加稀疏,不过具体会不会造成网络性能的明显下降就需要更多的实验了。

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    利用ReLU输出稀疏性加速卷积