cuda-convnet 是Alex Krizhevsky公开的一套CNN代码,运行于Linux系统上,使用GPU做运算,在cuda-convnet中仅仅提供了Cifar数据集的demo,并且网站上并没有说明cuda-convnet代码是如何用于其它数据库的,所以博主我就尝试修改源码,以用于MNIST数据集上,做一个手写数字的识别CNNdemo
文章分三个部分:
首先,IO模块
其次,修改Layer的参数
最后是里面一些Python文件的说明,博主我也是为了这套代码才学习的Python与Cuda,所以有关python的认识还是很粗浅的,python的学习可以参考廖雪峰的网站
Alex的网站上是提供了三套cifar的数据集——python,matlab以及C,而源代码只支持python格式的。python下的数据存储是使用了“字典”的数据类型,IO是使用了Python中的CPickle模块的dump()与load()函数,其中dump()函数是帮助我们将其他数据库的文件修改成cuda-convnet可接受的,用于数据集的构建,load()函数则是代码中读取数据的函数,存在于源代码的util.py文件中。
简单的说一下python下的cifar数据集的格式吧,分为两个部分,一个是data_batch_i 一个是meta文件,使用cPickle.load()方法来读取data_batch_i得到的是一个字典,有用的关键字是——‘data‘与‘labels‘,其中data一定是按列存储。meta文件存放着有用的关键字为‘label_names’,‘data_mean’,‘num_vis’,‘num_cases_per_batch’。大家可以修改源代码util.py,加入print看一下字典格式,其实源文件里面还有很多其他的信息,但是都没有太多用处。
知道了数据的格式,那么剩下的任务就是写cuda-convnet可以接受的数据了,使用的函数就是上面说的cPickle.dump()
然后说明一下神经网络的结构,由于手写数字的识别并不是很难,所以仅仅用一层卷积层就可以了,如果想参考之前的参数,可以看一下caffe的mnist-tutorial或者是Lecun 98年的那篇文献,我差不多是自己改的,跟前人的参数定的差不多。感觉简单的模型,只要对CNN理解到位,还是可以自己修改参数的。
其中有一个很需要点出来的是神经元neuron的类型,文献里面说RELU的收敛速度要比Logistic快非常多,但是要注意使用RELU会导致的问题就是出现NaN和Inf的错误信息,这个在Alex的源代码网站下面有一群人反应,这应该是因为Relu的值域无界特点导致的,用Logistic一定可以避免这个问题,就是收敛很慢而已,但是Relu什么时候可以使用,博主也在摸索中,应该是需要一定的数学推导的。
最后介绍一下源代码中python文件的重要模块,方便大家来理解这套代码的框架
util.py 下的unpickle函数是非常重要的,可以print dict查看数据字典格式
convdata.py 下提供了三个源代码接受的数据类型CIFARDataProvider,CroppedCIFARDataProvider,DummyConvNetDataProvider,博主仅仅是关注了CIFARDataProvider,这个文件没什么代码值得看的
convnet.py 是整个python程序的入口,看代码最下面便知。这个文件主要是实现了命令行形式的启动程序
data.py 跟 convdata.py差不多,没太多值得看的
gpumodel.py 整个代码的循环模块在这里——train()函数下,有个while循环,懂的人自然懂~
layer.py option.py ordereddict.py这三个文件都没仔细看,目前看来还不需要修改
shownet.py 由于用的是SSH协议访问服务器,所以博主的绘图功能直接不能用了……
差不多介绍完了吧,感觉Alex的这套代码还是不太友好,按理说应该给出一个IO的标准,供后来人测试其他数据集的,没看过caffe,据说可读性要好一些
有什么问题欢迎指出!