我所写的CNN框架 VS caffe
一个月前,自己模仿caffe实现了一个卷积神经网络的框架。
相同点
1无缝支持CPU和GPU模式,GPU模式使用cuda实现。
不同点
1我的CNN不依赖与任何第三方的函数库,caffe用到了第三方的数学函数库(cublas和mkl)来做矩阵操作。
其实区别就在于,caffe采用了矢量化编程的方法,如ufldl教程所说http://deeplearning.stanford.edu/wiki/index.php/%E7%9F%A2%E9%87%8F%E5%8C%96%E7%BC%96%E7%A8%8B。
---------------------------------------------------------------------------------------------------------------
矢量化编程是提高算法速度的一种有效方法。为了提升特定数值运算操作(如矩阵相乘、矩阵相加、矩阵-向量乘法等)的速度,数值计算和并行计算的研究人员已经努力了几十年。矢量化编程的思想就是尽量使用这些被高度优化的数值运算操作来实现我们的学习算法。
---------------------------------------------------------------------------------------------------------------
这也解释了caffe比我的快的原因。
对于cpu模式,我只是简单的用for循环了实现一些矩阵操作。
对于gpu模式,虽然用到了cuda的线程模型,有一定的并行度。但是并没有人家的数学函数库那么快。
要想超过caffe的速度,这里也是切入点之一。
方法1:找到比cublas更快的数学库。
方法2:精通GPU编程,研究cublas等源码,提高数据的利用率。其实用cublas等函数库也是有一个致命缺点的,函数只能给你返回最终结果,中间结果不会保存。但是很可能存在这么一种情况,这些中间结果可能下次操作会用到,如果能用到,速度必然更加,否则得重新计算,浪费时间。所以,如果对cublas源码精通,或者能设计出比她更高性能的数值运算操作,我们就可以保存一些中间结果,提高数据的利用率,达到性能上的提高。
当然,这里还有指出,并不是所有操作都能转换为矢量化编程。gpu模式下,caffe里面有一些操作也是自己写核函数实现的,不能用现有的函数实现,比如pool层的正向传播和反向传播。
2 类设计和内存设计
我的CNN类设计比caffe清晰,每一层的特征值,权重值,都有一个类,而caffe都用blob。
从代码的清晰度来看,我的比caffe好。
但是从性能上来讲,就不行了。
caffe的blob内存设计是数据密集型的,我的CNN特征值,权重值等数据在不同的对象中,因此从内存上来看也是分开的。
这恰好是caffe的巧妙指出,只有数据在连续的内存空间,才可以方便的用到第三方的函数库的矩阵操作来实现矢量化编程。
而我,只能用多个循环来操作。
3 迭代方法
虽然用的都是随机梯度下降法来求最优解,
但是我的是每次一张图片,
而caffe每次一批图片。
除了上面提到的一些提高性能的方法,
还想到一点。就是实现内存池,优化内存的使用。肯定有些操作,会申请临时空间,然后用完了就丢弃。
这时就可以用内存池来优化了。
唉,现实是残酷的。可惜我现在还是没有能力写出比caffe更快的,因为对GPU编程和矢量化编程不够精通。这个我所写CNN暂且就被丢弃了。先用caffe玩,毕竟研究人家代码有很多可取之处。
本文作者: linger
本文链接:http://blog.csdn.net/lingerlanlan/article/details/38121443
我所写的CNN框架 VS caffe,布布扣,bubuko.com
原文:http://blog.csdn.net/lingerlanlan/article/details/38121443