1.SSD简介
SSD全称Single Shot MultiBox Detector,是一个用于目标检测的深度学习框架。
By Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg.
SSD是一个单一的网络对象检测的统一框架。你可以使用代码来训练/评估一个用于目标检测任务的网络。(http://arxiv.org/abs/1512.02325).
作者的Github上https://github.com/weiliu89/caffe
只给出了linux下的代码,下面内容是将代码移植到windows上的实现步骤。本文参考了samylee的博文Windows-SSD配置与测试,在此表示感谢。
2. 配置环境
windows7 + vs2013 + Cuda8.0
3. 所需文件
vs2013,windows-caffe,ubuntu-ssd,libboost,cudnn,OpenCV(可选)ssd_detect.cpp,io.cpp
windows-caffe地址: 链接:http://pan.baidu.com/s/1hrGRu1A
密码:j82r
或 https://github.com/conner99/caffe
,推荐使用后者。
ubuntu-ssd地址: 链接:http://pan.baidu.com/s/1mhYuf7y
密码:3jp2
libboost地址:链接:http://pan.baidu.com/s/1pLbBMpP
密码:41tq
cudnn地址:链接:http://pan.baidu.com/s/1o8vWBhw
密码:kdj4
opencv地址:链接:http://pan.baidu.com/s/1eSkHBj0
密码:nhch
ssd_detect.cpp地址:链接:http://pan.baidu.com/s/1nvwECNv
密码:e3yn
io.cpp地址:链接:http://pan.baidu.com/s/1i4CL7QP
密码:g623
signal_handler地址:链接:http://pan.baidu.com/s/1mhYuf7y
密码:iubq
4. 配置步骤和出现的问题
本人配置的是使用GPU的版本,以下为配置步骤和出现的问题:
从上述网址下载的windows-caffe使用的Cuda版本为7.5,我使用的Cuda版本为8.0,所以将其版本改为8.0,重命名
.\caffe-master\windows\\
路径下的CommonSettings.props.example
为CommonSettings.props
,修改Cuda配置为<CudaVersion>8.0</CudaVersion>
,此外设置<CpuOnlyBuild>true</CpuOnlyBuild>
和<UseCuDNN>false</UseCuDNN>
。编译项目,报错
“未能生成object文件(视警告为错误)”
,解决方法:右击选择属性->配置属性->c/c++->常规
,将“警告视为错误”
的选项改为“否”
,若还报错,将math_functions.obj
文件放到路径caffe-master\Build\Int\libcaffe\x64\[Release|Debug]
下。复制
.\ssd_new
下所有文件(除build
,data
,example
以及models
之外)至.\windows-caffe
,替换原来文件夹中对应的文件。编译文件,报错
error C3861: “mkdir”: 找不到标识符
。解决办法:在db_lmdb.cpp
文件的
CHECK_EQ(mkdir(source.c_str(), 0744), 0) << "mkdir " << source << " failed";
语句上下添加语句,使得:
#ifdef MSC_VER
CHECK_EQ(mkdir(source.c_str(), 0744), 0) << "mkdir " << source << " failed";
#endif
- 编译文件,报错
error C2360: “occurrences_32”的初始化操作由“case”标签跳过
。解决办法:在hdf5.cpp文件中将所有出错的case
语句下的内容都括上大括号{ }
,比如,将语句
case H5T_FLOAT:
LOG_FIRST_N(INFO, 1) << "Datatype class: H5T_FLOAT";
break;
改为:
case H5T_FLOAT:
{
LOG_FIRST_N(INFO, 1) << "Datatype class: H5T_FLOAT";
break;
}
选择解决方案下的
libcaffe
项目,进入include/layers
文件夹中,将路径.\caffe-master\include\caffe\layers
下除了roi_pooling_layer.hpp
的所有hpp
文件添加到include/layers
中。进入src/layers
文件夹中,将路径.\caffe-master\src\caffe\layers
下除了roi_pooling_layers.cpp
的所有cpp
文件添加到src/layers
中。编译项目,报错
error C2065: “SIGHUP”: 未声明的标识符
。解决办法:在common.cpp
文件最上边一行添加语句
#include "process.h"
编译项目,报了都是关于
signal_handler.cpp
文件相关的错误,在本文章第三部分享文件中下载signal_handler.cpp
文件替换即可。编译项目,报错找不到boost库,在解决方案的
caffe
和classification
项目下的VC++
选项下,在包含目录
中添加~/boost_1_59_0/
,在库目录
中添加~\boost_1_59_0\stage\lib
。选择解决方案下的
libcaffe
项目,进入libcaffe/src/util
文件夹中,将路径\ssd_new\src\caffe\util
下的bbox_util.cpp
文件添加到libcaffe/src/util
中。编译项目,报错
找不到标识符"snprintf"
,解决办法:在bbox_util
文件中,在标识符snprintf
前面加上下划线_
,修改为_snprintf
。编译项目,报错:
error LNK2001: 无法解析的外部符号 "__declspec(dllimport) void __cdecl google::InstallFailureSignalHandler(void)"
采用了粗暴的解决方式,在common.cpp
文件中,将出错的函数::google::InstallFailureSignalHandler()
注释掉。
- 选择解决方案下的
classification
项目,将ssd_detect.cpp
文件添加到项目中,去除注释,修改相应的模型文件和网络结构定义文件的路径。
至此,SSD目标检测的CPU版本,已经可以在windows下运行,接下来配置 SSD的GPU加速版本。
在路径
.\caffe-master\windows\\
下进入CommonSettings.props
配置文件中,设置<CpuOnlyBuild>false</CpuOnlyBuild>
和<UseCuDNN>true</UseCuDNN>
。进入
.\caffe-master\windows\\
路径下,启动Caffe
工程,编译工程,报错:
error MSB3721: 命令“……”已退出,返回代码为1。
修改.\caffe-master\windows\\
路径下的CommonSettings.props
文件,修改对应内容为:
<CudaArchitecture>compute_30,sm_30;compute_50,sm_50</CudaArchitecture>
- 之后编译工程,报错:
无法打开cudnn.h文件
,从本博客第二部分下载cudnn,之后在项目工程的属性中的vc++包含目录
中添加~/cuda/include
路径。在库目录
中添加~/cuda/lib/x64
路径。 - 编译工程,报错:
error : declaration is incompatible with "const char *cudnnGetErrorString(cudnnStatus_t)"
,解决方法:修改cudnn.hpp
文件中
inline const char* cudnnGetErrorString(cudnnStatus_t status)
为
inline const char* CUDNNWINAPI cudnnGetErrorString(cudnnStatus_t status)
- 编译工程,报错:
"::caffe::kBNLL_THRESHOLD" is undefined in device code"
,解决方法:修改bnll_layer.cu
中
Dtype expval = exp(min(in_data[index], Dtype(kBNLL_THRESHOLD)));
为
Dtype expval = exp(min(in_data[index], Dtype(50)));
- 编译工程,报错:
error : too few arguments in function call. conv_layer.cu
。修改conv_layer.cu
文件中
this->forward_gpu_gemm(bottom_data + n * this->bottom_dim_, weight, top_data + n * this->top_dim_);
为
this->forward_gpu_gemm(bottom_data + n * this->bottom_dim_, weight, top_data + n * this->top_dim_, false);
编译项目,报错
error MSB3073
,解决办法:进入项目libcaffe
的属性设置,设置生成事件 -> 预先生成事件 -> 在生成中使用 -> 否
,设置生成事件 -> 后期生成事件 -> 在生成中使用 -> 否
。编译项目,报与boost相关的regex正则表达式库出现问题,在项目中我们不需要正则表达式,所以将相关语句注释掉即可。进入项目
libcaffe
中,进入detection_output_layer.cu
文件,将所有出现regex
和rv
的语句注释掉。进入detection_output_layer.cpp
文件,将所有出现regex
和rv
的语句注释掉。进入detection_output_layer.hpp
中,将语句#include <boost/regex.hpp>
注释掉。编译项目,报错:
找不到".\caffe\3rdparty\hungarian.h"文件
,在路径.\caffe-master\include\caffe\3rdparty\\
下添加hungarian.h
文件。编译项目,报错:找不到".\src\caffe\3rdparty\hungarian.cpp"文件
,在路径.\caffe-master\\src\caffe\3rdparty\\
下添加hungarian.cpp
文件。编译项目,报与
thrust
相关的错误,进入项目libcaffe
中,注释掉
#include "thrust/functional.h"
#include "thrust/sort.h"
……
thrust::sort_by_key(&confidences[0], &confidences[0] + num_remain, &idx[0],
thrust::greater<Dtype>());
这些语句。
- 进入解决方案下的
classification
项目的ssd_detect.cpp
文件中,去除注释,修改相应的模型文件和网络结构定义文件的路径。
至此,SSD目标检测的GPU版本,已经可以在windows下运行。
5. 感谢
感谢一直踩雷的妇老师,解决了上面提到的大部分错误。希望本篇文章可以给想要在windows环境下运行SSD的程序员们一些帮助。