依赖库:http://blog.csdn.net/joshua_1988/article/details/45036993
建立工程:http://blog.csdn.net/joshua_1988/article/details/45048871
在这里说一下我跟原文有一些不同的地方:
依赖库
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,好像会造成冲突。
====================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~~~