本文主要参考文章:http://www.bubuko.com/infodetail-902302.html
过程中遇到了很多此文中没有遇到的问题,几经波折,多处查找解决方案,终于解决了所有的问题,下面是所有的流程。
1.准备工作
我在自己的笔记本配置的caffe,配置的环境为:Windows10 64位+ cuda7.5 + Opencv2.49 + boost1.56+VS2013。
安装完第三方库之后,有的需要手动创建环境变量,方法如下:
找到计算机,右键->属性->高级系统设置->页签:高级->环境变量(右下角)->系统变量:新建;然后在弹出的对话框中,输入对应的变量名,及变量值(文件位置)。
1.1安装CUDA7.5
下载CUDA7.5: https://developer.nvidia.com/cuda-downloads,安装完成后会自动创建环境变量CUDA_PATH_V7_5。
1.2安装boost1.56
下载boost1.56:http://sourceforge.net/projects/boost/files/boost-binaries/1.56.0/,选择boost_1_56_0-msvc-12.0-64.exe,安装完成后手动创建环境变量BOOST_1_56_0。
1.3安装opencv2.4.9
下载opencv2.4.9:http://opencv.org/downloads.html,安装完成后手动创建环境变量OPENCV_2_4_9。
1.4第三方库
这一部分主要包括Glog+Gflag+Protobuf+LevelDB+HDF5+LMDB+Openblas,不容易下载。使用的是Neil Z. SHAO‘s Blog提供的编译好的。
下载地址:http://pan.baidu.com/s/1mg1iJrE
下载完,解压得到3rdparty文件夹。
1.5下载caffe源码
下载地址:https://github.com/BVLC/caffe,下载master版本得到caffe_master文件夹,将上一步下载的得到的3rdparty文件夹放到caffe_master文件夹目录。
2.增添部分缺失的文件
2.1缺少的caffe.pb.h文件
下载proto.exe和GernaratePB.bat:http://pan.baidu.com/s/1pJ7Onph;
将proto.exe放到caffe_master/3rdparty/bin文件夹,GernaratePB.bat放在caffe_master/scripts文件夹;
双击GernaratePB.bat运行,将在caffe_master/src/caffe/proto生成caffe.pb.h文件。
2.2准备mkstemp.hpp和mkstemp.cpp文件
(1)将mkstemp.hpp放在caffe_master/include/caffe/util/路径下,mkstemp.hpp中的内容为
#include <windows.h>
#include <io.h>
int mkstemp(char *templates);(2)将mkstemp.cpp放在caffe_master/src/caffe/util/路径下,mkstemp.cpp中的内容为
/* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright
(C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. */
#include "caffe/util/mkstemp.hpp"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/* Generate a temporary file name based on TMPL. TMPL must match the
rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
does not exist at the time of the call to mkstemp. TMPL is
overwritten with the result. */
int mkstemp (char *tmpl)
{
int len;
char *XXXXXX;
static unsigned long long value;
unsigned long long random_time_bits;
unsigned int count;
int fd = -1;
int save_errno = errno;
/* A lower bound on the number of temporary files to attempt to
generate. The maximum total number of temporary file names that
can exist for a given template is 62**6. It should never be
necessary to try all these combinations. Instead if a reasonable
number of names is tried (we define reasonable as 62**3) fail to
give the system administrator the chance to remove the problems. */
#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary file. To
conform to POSIX, this must be no smaller than TMP_MAX. */
#if ATTEMPTS_MIN < TMP_MAX
unsigned int attempts = TMP_MAX;
#else
unsigned int attempts = ATTEMPTS_MIN;
#endif
len = strlen (tmpl);
if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
{
errno = EINVAL;
return -1;
}
/* This is where the Xs start. */
XXXXXX = &tmpl[len - 6];
/* Get some more or less random data. */
{
SYSTEMTIME stNow;
FILETIME ftNow;
// get system time
GetSystemTime(&stNow);
stNow.wMilliseconds = 500;
if (!SystemTimeToFileTime(&stNow, &ftNow))
{
errno = -1;
return -1;
}
random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
| (unsigned long long)ftNow.dwLowDateTime);
}
value += random_time_bits ^ (unsigned long long)GetCurrentThreadId ();
for (count = 0; count < attempts; value += 7777, ++count)
{
unsigned long long v = value;
/* Fill in the random bits. */
XXXXXX[0] = letters[v % 62];
v /= 62;
XXXXXX[1] = letters[v % 62];
v /= 62;
XXXXXX[2] = letters[v % 62];
v /= 62;
XXXXXX[3] = letters[v % 62];
v /= 62;
XXXXXX[4] = letters[v % 62];
v /= 62;
XXXXXX[5] = letters[v % 62];
fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
if (fd >= 0)
{
errno = save_errno;
return fd;
}
else if (errno != EEXIST)
return -1;
}
/* We got out of the loop because we ran out of combinations to try. */
errno = EEXIST;
return -1;
}
3.建立caffe工程
准备好了caffe需要的依赖库和环境之后,下面就可以建立caffe的vs项目,进行编译了。
3.1创建新的工程
新建一个空的控制台VS2013工程,起名为caffe;
将项目改为64位的项目:右键项目->属性->配置管理器->活动解决平台方案->新建x64平台;
将caffe_master内的3rdparty、include、src和tools文件夹拷贝到工程根目录下
3.2修改项目属性
项目——属性——C/C++——常规——附加包含目录
../include
../src
../3rdparty/include
../3rdparty
../3rdparty/include/openblas
../3rdparty/include/hdf5
../3rdparty/include/lmdb
../3rdparty/include/leveldb
../3rdparty/include/gflag
../3rdparty/include/glog
../3rdparty/include/google/protobuf
项目——属性——VC++目录——包含目录
$(CUDA_PATH_V7_5)\include
$(OPENCV_2_49)\include\opencv
$(OPENCV_2_49)\include\opencv2
$(BOOST_1_56)
项目——属性——链接器——常规——附加库目录
$(CUDA_PATH_V7_5)\lib\$(PlatformName)
$(OPENCV_2_49)\x64\vc12\lib
$(BOOST_1_56)\lib64-msvc-12.0
..\3rdparty\lib
项目——属性——链接器——输入——附加依赖项
debug添加:
opencv_ml249d.lib
opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_objdetect249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_nonfree249d.lib
opencv_ocl249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_superres249d.lib
opencv_videostab249d.lib
cudart.lib
cuda.lib
nppi.lib
cufft.lib
cublas.lib
curand.lib
gflagsd.lib
libglog.lib
libopenblas.dll.a
libprotobufd.lib
libprotoc.lib
leveldbd.lib
lmdbd.lib
libhdf5_D.lib
libhdf5_hl_D.lib
Shlwapi.lib
gflags.lib
libprotobuf.lib
leveldb.lib
lmdb.lib
libhdf5.lib
libhdf5_hl.lib
release添加:
opencv_ml249.lib
opencv_calib3d249.lib
opencv_contrib249.lib
opencv_core249.lib
opencv_features2d249.lib
opencv_flann249.lib
opencv_gpu249.lib
opencv_highgui249.lib
opencv_imgproc249.lib
opencv_legacy249.lib
opencv_objdetect249.lib
opencv_ts249.lib
opencv_video249.lib
opencv_nonfree249.lib
opencv_ocl249.lib
opencv_photo249.lib
opencv_stitching249.lib
opencv_superres249.lib
opencv_videostab249.lib
cudart.lib
cuda.lib
nppi.lib
cufft.lib
cublas.lib
curand.lib
gflags.lib
libglog.lib
libopenblas.dll.a
libprotobuf.lib
libprotoc.lib
leveldb.lib
lmdb.lib
libhdf5.lib
libhdf5_hl.lib
Shlwapi.lib
3.3添加项目文件
3.3.1./src/caffe中的文件
将../src/caffe文件夹中所有的*.cpp文件添加到工程中:
3.3.2./src/caffe/layers中的文件
项目:右键->生成依赖项->生成自定义->勾选CUDA7.5->确定
将./src/caffe/layers中的所有的cpp和cu文件都添加到项目中。
3.3.3./src/caffe/util中的文件
将./src/caffe/util中所有的文件添加到项目
3.3.4./src/proto中的文件
将proto中的caffe.pb.cc添加到项目:
3.3.5./tools中的文件
本文件夹下有多个cpp文件,通过它们的名字就可以知道相应的功能。添加不同的cpp文件到项目中,然后生成项目,就可以得到不同功能的exe文件。
将caffe.cpp添加到工程,生成项目,得到caffe.exe文件,可用于训练模型
将computer_image_mean.cpp添加到工程,生成项目,得到的exe文件可用于将训练样本转换为caffe使用的leveldb/lmdb数据集。
依次类推。
3.4 修改部分文件
有一些文件在编译的过程中将会报错,先预先修改这些文件内容。
3.4.1 ./src/caffe中的文件
1.blob.cpp
出现错误:error C4996: 'std::_Copy_impl';
解决办法:属性-> c\c++->预处理器->预处理器定义里添加_SCL_SECURE_NO_WARNINGS
2.common.cpp
出现关于getid和fopen_s的错误。可通过如下步骤修改:
(1)在代码前面添加:#include <process.h>
(2)修改项目属性:项目——属性——C/C++——预处理器——预处理器定义->添加:_CRT_SECURE_NO_WARNINGS
(3)在代码中getpid的位置进行如下修改:
#ifdef _MSC_VER
pid = _getpid();
#else
pid = _getpid();
#endif
(4)注释语句::google::InstallFailureSignalHandler()。
3.4.2 ./src/caffe/layers中的文件
(1)在bnll_layer.cu文件,进行如下修改:
float kBNLL_THRESHOLD = 50 -> #define kBNLL_THRESHOLD 50.0
(2)在base_data_layer.cpp中,在“stream”的定义处初始化为0值
(3)在infogain_loss_layer.cpp中,将
Dtype prob = std::max(bottom_data[i *dim+j], Dtype(kLOG_THRESHOLD))
改为:
Dtype prob = (std::max)(bottom_data[i*dim+j], Dtype(kLOG_THRESHOLD));
3.4.3 ./src/caffe/util中的文件
1.hdf5.cpp中
将switch语句中的头两个case中的内容用{}括起来。
2.在io.cpp中
(1)在io.hpp头文件中添加:#include“mkstemp.hpp”
(2)修改ReadProtoFromBinaryFile函数:
O_RDONLY ——> O_RDONLY | O_BINARY
(3)在代码中添加:
#define open _open
#endif
(4)将close()改为_close()
3.在signal_handler.cpp中
(1)增加宏定义:#define SIGHUP 1
(2)注释掉HookupHandler函数和UnhookHandler函数的定义和引用
3.5添加动态链接库
程序缺乏三个动态链接库:libgfortran-3.dll,libglog.dll,libopenblas.dll。
(1)libgfortran-3.dll下载地址:http://www.dllzj.com/libgfortran-3.dll/;下载64位的dll;
(2)libopenblas.dll下载地址:https://sourceforge.net/projects/openblas/files/;
(3)libglog.dll:
先下载libglog0.3.3:http://download.csdn.net/detail/chenguangxing3/6661667;
打开项目工程,将生成器改为x64,编译即可得到64位的libglog.dll。
将以上3个dll文件放在caffe/x64/debug/文件目录下。
4.生成解决方案
编译所有的文件并链接,然后运行,程序正常运行。