您的位置:首页 > Web前端

深度学习工具箱CAFFE在64位win7+VS2013环境下编译及运行

2015-04-21 15:37 405 查看

首先按照 joshua_1988 的两篇博客进行依赖库的配置和工程的创建

依赖库:/content/7159639.html

建立工程:/content/7159640.html

在这里说一下我跟原文有一些不同的地方:

依赖库

1. 根据我的经验,一定要用vs2013,虽然joshua_1988说2012应该也行,但是我尝试的时候发现caffe有一些用到c++11标准的地方,而vs2012对11标准支持较弱,会对一些11标准新加的东西报一些错,所以我后来还是装上了vs2013。而且要先装vs2013再装cuda,否则我发现在build configuration里没有启用cuda7.0的选项。

2. OpenBLas,joshua_1988用的0.2.14 for windows的openblas,官网上也有支持win平台的包。但是下载下来以后lib文件夹里并没有.lib文件,上文joshua_1988直接用的.dll.a文件,但是我用它却不成功。最后只好下了老一些的版本0.2.8的openblas发现里边有lib文件。

3. lmdb除了下载joshua_1988提到的三个文件,我记得我还额外下了一个inttypes.h。里边是一些#define。但是在编译的时候又会对这些define报错,我最后直接保留了这个头文件但是把内容注释掉了。

4. protobuf的库,直接build所有工程经常会失败几个,其实只要分别build这三个 libproto,libprotoc,protoc工程,生成需要的lib文件就可以了。

5. 在3rdparty/lib里并没有snappy64.lib文件。joshua_1988图中的libhdf5.lib和libhdf5_hl.lib在我这儿是 hdf5.lib和hdf5_hl.lib。记得debug的lib要自己改名加上d。在3rdparty/include中我还加入了openblas的include里的头文件。还加上了hdf5中hl里的头文件hdf5_hl.h以及同一个文件夹下的配套的h文件。

建立工程

1. 把linker中的input中的libopenblas.dll.a改为.lib

2. 手动把hdf5_hl.h加到工程里。在c/c++的general里的addtional include directories里加入了3rdparty\include\openblas。

3. 最好不要加caffe目录下的test和gtest源文件,否则会报很多错,而且gtest里还有个main,跟caffe.cpp里的main冲突。

下面是我在完成joshua_1988博客内容以后遇到的问题及解决方法,基本按我自己搞得顺序。

1. 在H5public.h中报错,找不到H5pubconf.h。这玩意儿隐藏在hdf5文件夹的cmake\build里,就在build目录下,是编译自动生成的,拷贝到3rdparty\include\hdf5中。我也是在这个时候手动把hdf5_hl.h添加到工程里的。

2. 编译时报错:std::max和std::min都报错,网上查因为windows.h的原因。在windows.h里微软自己实现了max和min,好像会造成冲突。

解决std::min和max的问题:1. 给std::max std::min变成(std::max) (std::min)注意:我这样做无效。
2. 用std::max<double>,参数是long double的,不知道用std::max<double>会不会损失精度。
3.
caffe.pb.h: float min() const;报错syntax error: ')'。解决办法:把FillerParameter中的min,max都改名,我改成了caffe_return_min/max。因为这个函数的作用就是返回类里的变量_min和_max。记得把引用的地方也改了,可以根据debug报错的位置来逐一改掉。
下边的语句会报 syntax error : 'constant'。
static const DimCheckMode STRICT
= V1LayerParameter_DimCheckMode_STRICT;
static const DimCheckMode PERMISSIVE
= V1LayerParameter_DimCheckMode_PERMISSIVE
[align=left]试了好几种改法,最后。。。。在STRICT和PERMISSIVE前加个_,也就是改个名字。= =不知道为啥,有懂得请留言。。[/align]
[align=left]4. 有一个地方(好像是caffe.pb.h还是cc来着)会报fileno这个函数是posix标准已抛弃,请用_fileno代替。结果我改成了_fileno他还是报错。最后追踪到unistd.h。。。有一句#define fileno _fileno。。坑爹啊!注释掉这句。[/align]
[align=left]5. 然后我在这里删掉了test和gtest的源代码,错误报的太多了。。。删掉了清爽很多。。[/align]
[align=left]6. 把boost,gflags,glog的bin路径都加到path里。其实准备依赖库的时候就可以加上了。各种bin都加到path就行了。[/align]
[align=left]7. 编译通过!!!不过运行会报丢失一堆dll,我遇到的基本可以在这篇文章中找到解决方法,尤其注意libgcc_s_sjlj-1.dll,我下了好多个才找到一个能用的。都放到system32就行。[/align]
[align=left]8. 已经可以运行!然后就是很多需要改代码的地方了,比如传参的路径\和/还有很多变量我发现运行的时候都没赋上值,这些都得自己一步一步追踪程序改代码。我也正在改,后续会更新。[/align]

====================2015年4月24日更新===================

1. 开始逐句调试,结果一开始就发现FLAGS_solver这个变量 没赋上值。想了一会儿,果断在main里直接赋给这个变量以solver文件的路径。

2. 还有一点,记得给argc和argv赋值,参数可以参考caffe/example下任一例子的sh文件中的传参。比如train_lenet.sh中这么写的

./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt

那么参数就是 ‘train’和'--solver=examples/mnist/lenet_solver.prototxt',在windows下也直接给这俩参数就行。记得solver路径改成自己的。

3. caffe.cpp的main函数跳到caffe.cpp的train函数,然后到solver.cpp的Solve方法中,然后进行net.cpp的初始化。结果在data_layer的初始化就跪了。(补充一点!一定记得先准备好数据,我进行到这儿的时候才想起来mnist的数据我都没下,搞毛呢!你可以准备lmdb和leveldb的数据,最好也准备好图片格式的原始数据。原因后边说

等我从实验室服务器上下载了mnist的leveldb和lmdb的数据以后,再运行程序,还是报错。注意原始prototxt里用的是leveldb的数据,然后我就报了一个

Debug Error!R6010-abort() has been called


的错。当时我就蒙圈了,没见过这样的啊,上网查,也没有什么解释的清楚地,就有人说好像是内存泄漏啊指针之类的问题。这尼玛我上哪找去。

3.1 然后我果断在prototxt里换成了lmdb数据,反正哥都有。然后运行,又报错,这回是程序自己assert了错。我一跟踪,mdb_strerror报出来的,那就是lmdb中函数运行中出问题了。又跟踪,发现mdb_env_open这个函数总是返回错误,再跟就是lmdb的lib文件了。然后我又上网查,看看有没有别人有解决办法,很少,貌似有说的但是没什么有价值的,还看到一个外国人写的说leveldb在windows下根本搞不起,lmdb还可以但是也要改源码。然后又看到说lmdb版本不同生成的数据不通用。我靠,然后我就跑去编译caffe/tools下的convert_imageset工具了,工程配置跟caffe的工程一样,搞出来以后还是在mdb_env_open报错。我崩溃了!!!

4. 折腾了好久,实在搞不好。一怒之下我把data_layer换成了imagedata_layer。直接用图片做输入!!然后我先用matlab把mnist的数据都恢复成了图片,并保存了一个txt记录文件名和label给iamgedata_layer用,一共7w张图片。

5. 关于imagedata_layer,我在这里犯了两个错误。一是我把transform_param的scale参数删了。我没仔细看imagedata层的参数(在caffe.proto)里,反正脑子一抽就给删了以为没有这个参数。第二是图片是单通道的,记得设一个参数是is_color: false,我一开始没设。这两个错误第一个致命的,导致我在后来折腾半天并且对整个caffe工程都开始质疑了。第二个算是强迫症。

6. 换了层以后开始跑,好高兴呀,data层终于初始化过了,其他层也没有问题。然后就开始跑,我就干别的了。过一会儿回来看 跑完了。卧槽。loss=87.3365,而且从第二个100轮开始就停留在loss=87.3365了。准确率10%。我三观差点就颠覆了。这有问题啊,然后我就开始跟踪代码,找啊,毫无结果,大半天都干这个了。最后都快绝望了,后来的事实证明!!!千万不要删掉scale参数。。。scale是用来把0-255的数据变成0-1的。。。删了这个归一化就是找抽。

7. ok,运行成功!有图有真相。



倒数第六行,准确率accuracy = 0.991~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: