【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程
【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程
标签:【神经网络与深度学习】 【Qt开发】 【VS开发】
这个过程是相当痛苦的,最后发现了一个真理,能通过更换开发工具版本解决的问题,就应该安装对应版本的开发工具,牺牲一点磁盘空间没啥大不了的。 首先是在visual studio 2013的环境下编译了Caffe+GPU+CUDA+cuDNN,生成了对应的libcaffe和一些工具执行文件。然后也是这自己组织安排训练生成模型,然后编写工程读取模型然后进行分类预测的实验,可以说在往Qt上移植的前,在visual studio 2013上完整的都走了一遍,这期间差不多花费了我三天多的时间,调试各种莫名其妙的问题,其中遇到最多的问题基本上在这几天撰写或者转载的博文中都有体现。所以一共生成了Release/Debug两个x64的版本。
因为在visual studio上已经进行过的验证,所有的功能都可以运行了。那么往Qt上移植的时候,我发现了问题:我基于msvc的Qt是msvc2015-32bit的,首先不是msvc2013与visual studio 2013的版本不配合,再次这尼玛当时装的时候只是下载了32-bit的版本,不支持x64,我只是简单的试着编译了一下,结果爆出了一大堆错误,还好没有钻牛角尖,硬着头皮安装了Qt for windows msvc2013-x64版本,安装完之后查看Qt的版本,发现自动也包含了msvc2013-x86,所以当初安装Qt-msvc2015的时候就应该安装x64版本的。
然后将classification的源文件拷贝粘贴到Qt工程的源文件中,然后就是最重要的在.pro文件中设置头文件和库文件的包含路径。
这个就需要一定的耐心了,一个一个的去找到相关的第三方库的lib所在位置,加以包含!应该考虑到debug版本和release版本库的区别,我希望将这个应用库全部挪到D盘根目录D:/Caffe_3rdparty文件夹中,后续的操作就可以脱离Caffe源码和编译的工程环境了,以免后续的源码编译对库的改动。
最后设置的包含路径如下:
INCLUDEPATH += D:\Caffe_3rdparty\include \
$$quote(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include) \
D:\Caffe_3rdparty\include\openblas \
LIBS += -L$$quote(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64) \
-lcublas \
-lcublas_device \
-lcuda \
-lcudadevrt \
-lcudart \
-lcudart_static \
-lcudnn \
-lcufft \
-lcufftw \
-lcurand \
-lcusolver \
-lcusparse \
-lnppc \
-lnppi \
-lnpps \
-lnvblas \
-lnvcuvid \
-lnvrtc \
-lOpenCL \
LIBS += -LD:\Caffe_3rdparty\lib \
-llibglog \
-llibopenblas \
-lleveldb \
-llmdb \
-lhdf5 \
-lhdf5_cpp \
-lhdf5_f90cstub \
-lhdf5_fortran \
-lhdf5_hl \
-lhdf5_hl_cpp \
-lhdf5_hl_f90cstub \
-lhdf5_hl_fortran \
-lhdf5_tools \
win32:CONFIG(debug, debug|release): {
LIBS += -LD:\Caffe_3rdparty\lib\Debug \
-llibprotobuf \
-lgflagsd \
-lgflags_nothreadsd \
-lopencv_core2410d \
-lopencv_imgproc2410d \
-lopencv_highgui2410d \
-lopencv_video2410d \
-lopencv_objdetect2410d \
-lopencv_ml2410d \
-lopencv_legacy2410d \
-lopencv_video2410d \
-lopencv_calib3d2410d \
-lopencv_contrib2410d \
-lopencv_ts2410d \
-lopencv_flann2410d \
-lopencv_gpu2410d \
-llibcaffe
}else:win32:CONFIG(release, debug|release): {
LIBS += -LD:\Caffe_3rdparty\lib\Release \
-llibprotobuf \
-lgflags \
-lgflags_nothreads \
-lopencv_core2410 \
-lopencv_imgproc2410 \
-lopencv_highgui2410 \
-lopencv_video2410 \
-lopencv_objdetect2410 \
-lopencv_ml2410 \
-lopencv_legacy2410 \
-lopencv_video2410 \
-lopencv_calib3d2410 \
-lopencv_contrib2410 \
-lopencv_ts2410 \
-lopencv_flann2410 \
-lopencv_gpu2410 \
-llibcaffe
}
这其中遇到了几个问题:
因为CUDA toolkit安装的时候选择了默认的方式,结果路径中包含了空格,所以刚开始一直识别不了CUDA的库何在。后面使用了$$quote(Path)来加以处理得到了解决。
不知道为何刚开始只有Debug版本程序能够跑起来,而Release的程序总是爆出一个dependent “…….hpp”没有找到,但是明明路径中有这个文件,后来在网上也没有找到解决方法,最后是将第三方库独立出来全部放到了D盘目录下后这个错误便没有了。虽然解决了,但是我不确信是不是因为路径太长,Qt没法识别的原因。
将Caffe编译结果文件/Build/x64/Debug或者Release中的动态链接库dll复制到Qt对应的编译结果路径中,就可以完整的脱离了Caffe的编译、源码环境。
将Caffe的include路径下的caffe文件夹也复制到第三方库的include路径中,从而彻底脱离Caffe源码。
后面再使用部署Caffe环境时,直接使用这个第三方库即可。
几天所做的工作
那么我这几天所做的工作已经初见成效:
基于Microsoft的visual studio 2013部署了Caffe源码与编译环境 ,成功编译生成libcaffe.lib的release和debug版本共使用;
基于visual studio 2013,在windows上使能了基于mnist和cifar-10的卷积神经网络的训练、测试;
基于visual studio 2013,在windows上部署了利用训练完毕的caffemodel进行classification的功能,通过批处理文件选择对应的网络结构,caffemodel,均值文件,输入标签和待分类的图片,也实现了从工程源码中直接嵌入路径进行执行的功能;
使用caffe官网提供的训练好的bvlc_reference_caffenet.caffemodel来进行部署分类识别功能,效果良好,debug速度要比release版本慢好多。
将caffe的部署使用环境从caffe的源码与编译环境独立出来,放入了D盘目录中,所以,后面使用训练好的模型进行分类预测时,就可以直接使用该部署使用环境。
基于Qt实现了利用caffe模型进行分类预测的功能!
使用过程
1. 首先得准备数据
比如0~9共十种手写体数字图片,分好类,转换为caffe支持的数据格式leveldb吧!
2. 设计网络
必须有对应的solver.prototxt,用来指明训练和测试的相关参数;
必须有对应的train.prototxt,用来指明网络的结构、数据等参数;
可以有对应的test.prototxt,用来对训练结果进行测试;
必须有对应的deploy.prototxt,用来指明网络结构,在部署使用的时候需要作为输入构建网络结构;
可能需要均值文件,有些时候训练中需要减去均值;
3. 训练和测试网络
这个阶段读取数据对网络结构进行训练,最后生成对应的.caffemodel和.sloverstate,caffemodel是caffe深度卷积神经网络的模型,配合对应的deploy.prototxt就可以构建分类器。而solverstate号称是训练的状态,也就是说可以在此训练的基础上继续训练你的卷积神经网络,比如调优啊之类的,或者在别人训练的模型上继续自己的训练啊等功能,不过这个功能我还没有试过。
4. 部署和使用网络进行分类
这一步需要deploy.prototxt,caffemodel,mean.binaryproto,label.txt,以及待分类的图片。待分类的图片几乎可以是opencv支持的任意图片。这里主要说一下这个label.txt,它是告诉分类器这里面可以有多少个分类,分类的名称是啥,比如手写体数字的话,就是0~9,分类的结果就是给出对应的概率,比如是0的概率为0.9,1的概率为0.05等等。
2016-9-16 15:43
张朋艺 pyZhangBIT2010@126.com