之前的文章中已经使得OpenCV能利用训练好的分类器进行图像的分类了,但最为关键的一步还没做,那便是分类器的获得。毕竟我们不可能用别人训练好的分类器很好的解决自己工程上的问题。
本篇,将开始对分类器的探索!
本人选用的是开源世界现在最流行的深度学习架构,至于为何怎么选,因为看到别人都这么选。。至于别的会不会更好,以后再说吧,有更深入的研究会跟大家分享。
第一步是下载,这个没什么说的。值得说的是版本问题,本人下载的是最新版本的,但你看到的时候可能已经有新的更新,这个时候你可以选择下载最新的(可能会遇到文章中没有提到的错误),也可以下载我后面会给出的DEMO(10个下载积分,不要问我为什么这么贵。。。)
注意这里不是直接下载源码,而是拉到页面下方如图所示位置下载:
我下载的是第一个。相信看到这里你会很开心,因为编译工作别人都做完了,如果我们不需要把caffe集成到自己的工程中而仅仅只是想用它来生成分类器,那么直接用就行了!至于怎么集成到自己的工程中会在后面的文章中分享。
下完解压,路径中不要有中文(一般都不要有中文,毕竟是外国人写的,支持可能不好,那就是个大坑),我们需要的东西都在“caffe/bin”这个路径里,后面也会经常用到。
下面就直接用caffe来为“cifar-10”这个很火的图像库生成分类器吧(其实我是想生成“cifar-100”这个图形库的分类器的,只是总有问题,后面再解决吧)。下载地址如下:
生成步骤:
1.格式转换(下载的cifar-10是二进制文件,caffe无法直接处理,故有此步)
接着,在“caffe\bin”路径下创建一个bat文件,内容如下:
convert_cifar_data.exe input output leveldb
pause
双击运行bat,不出意外在“output”文件夹下会生成“cifar10_test_leveldb”和“cifar10_train_leveldb”两个文件夹。
上面我们就完成了对于“cifar-10”这个图片库的格式转换工作,将下载的二进制文件转换为leveldb格式(caffe本身只支持leveldb和lmdb两种数据格式)。
2.求数据图像的均值,获取“mean.binaryproto”均值文件
在“caffe\bin”路径下创建一个bat文件,内容如下:
compute_image_mean.exe --backend=leveldb output/cifar10_train_leveldb mean.binaryproto
pause
这里的“compute_image_mean.exe”是我们下载的caffe里面就有的,“output/cifar10_train_leveldb”为刚刚生成的文件夹路径,“mean.binaryproto”为生成文件名。
双击运行bat,在“caffe\bin”路径下会生成“mean.binaryproto”。如下图:
3.分类器训练
经过上面的努力,我们已经有了leveldb数据、均值文件,可以直接搞训练啦!
要训练,需要以“.prototxt”后缀的模型描述文件,本人现在对CNN这块东西还一知半解的,所以用了网上教程中提到的“cifar10_quick_train_test.prototxt”模型,这个模型在之前caffe的下载地址中可以找到,可点击下图的绿色按钮下载,然后搜索下examples,把整个“examples”文件夹拷到“caffe\bin”下,如图:
这里会用到“examples\cifar10”里面的“cifar10_quick_train_test.prototxt”和“cifar10_quick_solver.prototxt”两个文件,且两个文件都有地方要修改。
“cifar10_quick_train_test.prototxt”:是训练网络配置文件,用来设置训练用的网络,这个文件的名字会在“solver.prototxt”里指定,里面有四个路径,如下:
我们看到它需要访问我们之前得到的leveldb数据文件和均值文件,因此把这三个东西放到“examples\cifar10”路径下。再者因为我们之前转换出来的文件是leveldb格式的,因此要把“source: “examples/cifar10/cifar10_train_lmdb””改成“source: “examples/cifar10/cifar10_train_leveldb””,把“backend: LMDB”改成“backend: LEVELDB”,“source”和“backend”各两处,总共四处地方需要修改。改完的文件如下:
“cifar10_quick_solver.prototxt”:是方案配置文件,用于配置迭代次数等信息,训练时直接调用caffe train指定这个文件,就会开始训练把文件最后一行的”GPU”改成”CPU”,因为我们下的是CPU版本的caffe。
到此就搞定了,真不容易!下面我们再在“caffe\bin”这个路径中弄个bat文件,把分类器学习的命令放进去来双击就行,内容如下:
caffe.exe train --solver=examples\cifar10\cifar10_quick_solver.prototxt
pause
这里还有一个细节。。examples/cifar10/中有几种不同的训练模式(quick和full等),要一一对应。我们利用的是“cifar10_quick_trian_test.prototxt”网络结构,所以在solver中选择“cifar10_quick_solver.prototxt”。
假如你选择的网络是“cifar10_full_train_test.prototxt”,那么你的slver应为“cifar10_full_solver.prototxt”,上面要修改的两个文件也需要做相应的变化。
接下来,运行吧!
用CPU版本运行需要一段时间,具体多久我没计算,反正我是去看电视去了,回来就好了,可以从命令行中看到训练的精确度,训练完成之后会在“examples\cifar10”这个路径下生成如下两个文件:
前者是分类器描述文件,后者是继续学习会用到的文件。
另外,还会生成一个分类网络文件如下:
classification.exe examples\cifar10\cifar10_quick.prototxt examples\cifar10\cifar10_quick_iter_4000.caffemodel examples\cifar10\mean.binaryproto my.txt 3.jpg
pause
运行结果如下:
可以看到其输出的结果还是准确的。
同样也可以参照之前的文章,用OpenCV进行分类,不过有个大坑!有个大坑!有个大坑!那就是要把“cifar10_quick.prototxt”文件中第一个层如下:
改写成如下形式:
不然会报错!不然会报错!不然会报错!不要问我为什么知道,现在想想都恶心、发晕、心有余悸。
不过opencv识别的结果跟自带的程序不一样,这个不科学,但本人现在还不太了解情况,不知道怎么解决。
本人的电脑的显卡是GTX960,因此的话是可以用CUDA做上面的分类器生成工作的。只有下载caffe带cuda的版本,如下:
然后把之前“cifar10_quick_solver.prototxt”文件最后一行重新改为”GPU”即可。其他的操作没有区别,弄完生成分类器,会发现速度快了非常的多,英伟达万岁!生成的窗口如下:
可以见到精确度经过训练不断的提升,4000次的训练后精确度为69.9%。
另外因为可以快速训练,比较容易发现,每次训练的精确度似乎都不大一样,如下是我完全没改内容做的另一次训练。
这是caffe算法会在测试数据中随机选一部分数据进行测试造成的。
为了提高精确度,可以修改“cifar10_quick_solver.prototxt”文件中的如下两处:
前者是迭代次数为4000,后者是每4000次迭代存储一次,和存储的路径。我改成10000,结果如下:
精确度提升了一点点。
精确度看起来是提升了,但用来分类自己的图像还是会失败,这个还未详细研究,这篇就先这样吧。
参考文章: