第一步自然是要有数据了,没有数据怎么学习呢?
我们之前谈到数据一般是保存在caffe目录下data这个目录的
再进入mnist目录看一下:
这里只有1个file,即是get_mnist.sh脚本,我们就是运行它来下载mnist数据的,
来看一下此脚本里面写的什么
打开此脚本:vim get_mnist.sh
这里面的内容了解一下即可,主要是让大家看看稀奇,可见它用了一个for循环,下载了4个文件,并解压了它们。
这里可能和其他一些地方分别把四个文件的名字和网址都列出来不一样,可能是caffe版本的问题,但是所执行的任务是一样的,for循环大家总看得懂吧
废话有点多了,回到caffe根目录,输入下面的代码,
./data/mnist/get_mnist.sh
然后就显示以下内容
下载完毕,原来的文件夹里多了四个文件
下载的数据为二进制文件,需要转换为LEVELDB或LMDB,
Mnist这个例程保存在我之前Caffe随记(一)中谈及的caffe目录下example这个目录,转到此目录可见如下,可以看到有个叫做mnist的文件夹,我们就要用到里面的东西
打开mnist目录
我们会用到create_mnist.sh这个脚本(然后我们还偶遇了上篇博文中提到的lenet_solver.prototxt这个脚本)
打开脚本看看里面的内容: vim create_mnist.sh
这里还是讲一下这个脚本中写的内容把,
首先,定义了几个路径变量:EXAMPLE、DATA、BUILD,因为这里路径变量定义的原因,所以我们等会儿调用这个脚本时要回到caffe这个根目录哦!
下面的这几个变量等会儿执行时就用这几个路径替换
然后,定义了 BACKEND这个变量为”lmdb”,所以下面程序中的BACKEND就用lmdb替换
接着,rm –rf $EXAMPLE/mnist_train_${BACKEND}这两句是在删除原来这个路径下的文件,
也就是如果你之前转换过一次,他会先删除原来转换得到的文件,然后再重新转换一次;
最后,$BUILD/convert_mnist_data.bin这句话就是在调用BUILD这个路径下的一个可执行文件:
convert_mnist_data.bin, 看名字就知道是在转换格式啦
紧跟 $DATA/train-images-idx3-ubyte\
$DATA/train-labels-idx1-ubyte\
这两个参数就是我们刚刚第1步下载后的文件,你看DATA对应的路径是不是第1步中的?这是训练集数据train,一个数据一个标签
紧跟 $EXAMPLE/mnist_train_${BACKEND} --backend=${BACKEND}EXAMPLE/mnist_train_
这个参数是把转换后的文件保存到哪里
对于test数据也是同样的操作
这就是这个脚本的详细描述
那么我们回到caffe根目录输入以下代码:
./examples/mnist/create_mnist.sh
再去刚刚那个EXAMPLE目录也就是examples/mnist目录去看看:
这里的两个文件夹中存放的就是我刚刚转换了的数据
我们用的网络是LeNer-5模型,这个模型当初Yan LeCun用的是sigmoid激活函数,但是至AlexNet之后的网络基本都用ReLU激活函数了,所以这个模型在caffe中用的也是ReLU
有兴趣的可以vim打开这个看一下这个文件,这里我就不贴图占篇幅了,caffe随记(二)中Net那一部分(点击打开)我就是举得这个例子。
文件的目录:
,caffe/example/mnist/lenet_train_test.prototxt 上一张图片其实就能看到这个文件的位置
Data准备好了,Net也定义了,下面就该轮到训练了
在caffe根目录下运行 ./example/mnist/train_lenet.sh
其实先不急运行,咱们来看看这个脚本的内容再说:
如图,这个脚本的内容很少,重要的就最后一行:
./build/tools/caffe train 这一句其实是在运行一个可执行文件,最后我们会详解一下,这里不急,因为这里面用的也是相对路径,那个点代表的是根目录caffe,所以我们也要在caffe根目录下执行这个文件。
后面的--solver=examples/mnist/lenet_solver.prototxt 是 参数
这个文件我也不打开看了,因为我的caffe随记(三)中讲sovler(点击可打开)时举的例子就是这个,这个就是我用来训练时需要的核心文件。脚本的内容就是这样,下面执行把。
执行结果会打印出来很多东西:
①GPU信息
我用的0号GPU: Tesla K40c (实验室的服务器,自己当然是买不起的- -)
②solver文件的参数信息:
③lenet_train_test.prototxt网络的信息和各层的建立过程
你可能会发现打印了两次网络,但其实一个是TRAIN一个是TEST,如下所示
和
细节我就不贴图了,太长了
然后就等着Iteration一直显示到10000,因为sovler.prototxt中规定了最大迭代次数10000,可以点此转到我那篇博文;
根据GPU或者CPU性能不同等待的时间不一样,千万不要以为你电脑卡住了,只要它的Iteration一直在增长就说明是在运行
然后会在5000和10000次的时候各输出2个数据一共是2x2=4个文件,
lenet_iter_5000.caffemodel、lenet_iter_5000.solverstate
lenet_iter_10000.caffemodel、lenet_iter_10000.solverstate
这四个文件
同样是因为solver中定义了每5000次迭代存储一次数据,可以点此转到我那篇博文。
获得训练出的模型之后,我们就可以用它来测试一把了。
运行 ./examples/mnist/test_lenet.sh
也许出于某些原因你的./examples/mnist目录下没有test_lenet.sh这个脚本文件,无妨,你其实可以自己写一个,调用linux指令touch 新建一个test_lenet.sh文件,然后再vim编辑它即可,来看看它的内容是什么:
#!/usr/bin/env sh
./build/tools/caffe.bin test--model=examples/mnist/lenet_train_test.prototxt –gpu 0--weights=examples/mnist/lenet_iter_10000.caffemodel -iterations 100
第一行 #!/usr/bin/env sh是说用sh方式执行这个脚本,
第二行 ./build/tools/caffetest 还是在调用可执行文件./build/tools/caffe.bin,然后test是它的参数,表明我现在是在测验了,
之前我们在train的时候已经碰到了./build/tools/caffe 这个命令,只不过那个时候参数是train,你可以往上翻到第4步去看看。
后面的--model=examples/mnist/lenet_train_test.prototxt仍然是参数,就是指定Net模型
后面的–gpu 0是我自己添上的一个参数,表明我是指定使用0号GPU来执行,
为什么我要自己加个这个呢?因为如果不加GPU的话,caffe.bin这个文件默认调用CPU来运行,这里不急,我后面会单独详解这个caffe.bin这个可执行文件
后面的--weights=examples/mnist/lenet_iter_10000.caffemodel仍然是参数,这个必须要带上,因为这就是你第4步训练出来的模型(也就是得到的权值文件),
后面的-iterations100仍然是参数,表明迭代次数
然后去根目录下运行此脚本即可,如果你是自己新建的这个脚本,如果不修改权限的话,也许需要在前面加上sh 这个命令才能运行。
当然其实经过上面的脚本文件讲解后,你完全可以直接在根目录下输入脚本里面的那个命令内容,如下:
./build/tools/caffe.bin test \
> -model examples/mnist/lenet_train_test.prototxt \
> -weightsexamples/mnist/lenet_iter_10000.caffemodel \
> -iterations 100
你看,这里我通过 直接在caffe根目录下输入命令来执行test操作,这里我就没有输入gpu 0,它打印的信息显示Use CPU
如果我选择调用我自己刚刚那个脚本文件来运行,因为那个文件里面我谢了GPU参数,所以就用GPU来运行咯,如下:
你看用的就是我的gpu 0, Tesla K40c
最终结果如下
平均准确率达到0.9904
至此,本篇讲解mnist的例子就到此结束了,完成这个实验,你就已经在caffe中玩了一次 Hello World!了
关于 .build/tools/caffe.bin这个可执行文件,我在下一篇博客来详细介绍一下,点击这里