总结下卷积加速的三种实现方法:
方案一:
卷积等效于使用傅里叶变换将输入与核都转换到复频域,做一个点乘运算,再用逆变换变回到实域,这的确比离散的卷积更快。
方案二:
当卷积核是可以分离的可以拆成一列乘一行的情况(可以用SVD验证一个卷积核是否可拆),将列与输入进行卷积后再把结果与行进行卷积,这种情况做卷积是最快的但是它只是针对特定的卷积核。这里提供大家一个链接里面专门讲解了和对比了这种方法还是在GPU的情况下点击打开链接,我也用pycuda体验过效果是不错就是不很实用,对卷积核限制太死了。
如果卷积核是不可分离的,但是又想快速 的实现它可以采用卷积核分解和SVD联系起来,使用SVD中更多的序列保留下来,使得主成分成分保留下来,将这些可以分离的卷积累加起来。这种方法是否有效将取决于SVD分解的大小,重要的奇异值的数量及其他的考虑,例如高速缓存的连贯性和存储单元的局部性。
方案三:
由于矩阵卷积的运算可转换成矩阵乘法进行,具体的原理可以看看这一个帖子点击打开链接,MATLAB的程序点击打开链接,Python的程序点击打开链接,其实这样做只是改变了运算的方式,没有降低运算量。通过这么一转化非常适应使用GPU编程,值得一提的就是直接用离散卷积公式进行GPU加速效果是不大的,我对比过卷积核小的时候还可以,卷积核一大就不行了,不如上述第一种方法好(在CPU下),具体的做法可以看我以前的帖子点击打开链接,我建议想尝试的朋友放弃这种方法。
用矩阵相乘的方法去进行GPU加速是肯定可以的,虽然我没有尝试过但是caffe下卷积乘法是这么做的,如果以后有空还是自己会做下。
这个帖子就是总结下前面的学习经验,有看法的朋友欢迎评论。