caffe_2016版本+windows+vs2013+matlab接口配置

因为要写一个resnet架构,同时拥有HyperColumn功能以及RNN或者LSTM架构的Detection框架。正好caffe最新版拥有了RNN、LSTM的模块,同时支持最新的cudnn。基于这些要求,我就在happynear的基础上,重新配置了一个属于自己的windows版本的caffe。

1、首先是第三方库的提供。我们就使用happynear提供的就可以了。这里附上链接:https://github.com/happynear/caffe-windows。这里说一个小插曲,以及最新的happynear配置的一个小bug。

     小插曲:我本来以为最新版本的caffe一定是使用的最新的protobuf,然后我就上google的github上下载了protobuffer的最新版3.10.结果按照happynear的办法配置是有问题的。

问题就在于happynear所有的第三库编译时采用的代码生成采用的运行库是多线程DLL,但protobuff的原始配置是多线程MTD,结果就会导致两者不匹配,编译连接阶段就会出错。

 小bug:这个是happynear在配置glog时按照原始步骤配置,就会导致缺失signal.cc这个文件,这样在编译时就会报错。我会在文后附上如何配置libglog.lib。

2、在VS2013上配置自己的项目。

     首先,新建一个空项目,名字可以写为MatCaffe。为了使筛选器更加便利一点,我们可以删除系统默认的头文件、系统等筛选器(除了外部依赖项不要删之外),自己定义一些筛选器,这样更加便利看。如图所示:


   之后就可以往各个筛选器里添加相应的文件,例如,cu筛选器里就加入后缀名是cu的文件。这里要注意,我们还要建立一个mexfunction.def文件,这个主要是用来定义mexw64文件的。里面的内容如下所示:

LIBRARY    "caffe_"
EXPORTS
        mexFunction

同时要注意,在main筛选器里加入,caffe文件夹里matlab\+caffe\private\里的caffe_.cpp。这个是写入了matlab接口的文件,这个很关键。同时可以受到启发,我们以后想编译任何关于caffe的cpp文件,都可以按照这个流程来,例如,我们想编译caffe原生.exe文件,就把caffe.cpp放入到main里,同时在生成项目里改为exe,即可。

然后,就是对项目的配置。首先是release版本还是debug版本,我这里建议使用release版本即可。(因为release也可以跨平台调试,我们只要在项目的属性\配置属性\c\c++中调试信息格式里改为“用于编辑并继续的程序数据库”,同时修改优化改为禁用,下面的全程序优化改为否,在链接器\调试里生成调试信息改为是。)在主界面的右上角(标红下拉列表),点击配置管理器,增加x64的平台。





配置完毕后,进入项目属性页。配置include、bin、lib文件的归属。首先是常规标签下的,如图所示:


VC++目录:

其中,包含目录下:F:\caffe-master\src;D:\Program Files\MATLAB\R2014a\extern\include;D:\Program Files\MATLAB\R2014a\toolbox\distcomp\gpu\extern\include;F:\caffe-master\include;F:\caffe-master\include\caffe\proto;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);$(CUDA_PATH)\include;F:\caffe-master\3rdParty\include;F:\caffe-master\3rdParty\include\boost;F:\caffe-master\3rdParty\include\gflags;F:\caffe-master\3rdParty\include\glog;F:\caffe-master\3rdParty\include\google;F:\caffe-master\3rdParty\include\hdf5;F:\caffe-master\3rdParty\include\leveldb;F:\caffe-master\3rdParty\include\openBLAS;F:\caffe-master\3rdParty\include\opencv;F:\caffe-master\3rdParty\include\opencv2;$(IncludePath)

库目录:F:\caffe-master\3rdParty\bin;D:\Program Files\MATLAB\R2014a\bin\win64;D:\Program Files\MATLAB\R2014a\extern\lib\win64\microsoft;$(OutDir);$(VCInstallDir)lib\amd64;$(VCInstallDir)atlmfc\lib\amd64;$(WindowsSDK_LibraryPath_x64);$(CUDA_PATH)\lib\$(Platform);F:\caffe-master\3rdParty\lib

这里要注意,这些都是我的电脑目录下,你们要按照自己的目录来改。

C/C++中常规标签下:


这里的附加包含目录:D:\Program Files\MATLAB\R2014a\extern\include;%(AdditionalIncludeDirectories)

为了加快对c++文件的编译速度,这里可以把多处理器编译打开。

预处理器标签下:


这里预处理定义中的内容是:

USE_LEVELDB;WIN32;_CRT_SECURE_NO_WARNINGS;_VARIADIC_MAX=10;_WINDLL;NDEBUG;_CONSOLE;BUILD_MEX_INTERFACE;USE_CUDNN;%(PreprocessorDefinitions)

如果你要使用CUDNN,就加上USE_CUDNN

代码生成标签下:


在是cuda C/C++的配置。 到这里,应该是没有这个选项的。我们此时关闭属性页界面。右击项目,在下拉列表里找到生成依赖项,选择生成自定义,在如图里选择CUDA7.5


这之后,在属性页里就会出现cuda C++的选项。

在Common项里:


在Device里:

其中,代码生成项里的数字按照自己显卡型号对应的数值来填写。我的显卡是titan black X 我就写30、35 其实可以写55但是我使用55会发现报错,这里暂时需要研究。

最后,链接器里常规选项卡:


附加库目录里:D:\Program Files\MATLAB\R2014a\extern\lib\win64\microsoft;F:\caffe-master\3rdParty\lib;F:\caffe-master\3rdParty\bin;%(AdditionalLibraryDirectories)

此外在输入选项:


附加依赖库:libmx.lib;libmex.lib;libmat.lib;gpu.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;cublas.lib;cuda.lib;curand.lib;cudart.lib;gflags.lib;libglog.lib;opencv_world300.lib;libopenblas.dll.a;leveldb.lib;lmdb.lib;hdf5.lib;hdf5_hl_cpp.lib;hdf5_cpp.lib;hdf5_f90cstub.lib;hdf5_fortran.lib;hdf5_hl.lib;hdf5_hl_f90cstub.lib;hdf5_hl_fortran.lib;hdf5_tools.lib;szip.lib;zlib.lib;cudnn.lib;libprotobuf.lib;libprotoc.lib;%(AdditionalDependencies)

这是就结束上述填写。

之后需要用protobuf生成在src里的proto文件,把第三方库里的protoc.exe放到src\proto文件中去,写一个Gen.bat。具体代码我写在下面:

pushd %~dp0

echo "copying .proto and generated .cc and .h"

protoc caffe.proto --cpp_out=.\ 
copy caffe.pb.h F:\caffe-master\include\caffe\proto\caffe.pb.h

::protoc caffe.proto --matlab_out=.\
pause

popd
注意,具体路径改成你自己的。

右击生成,等待。

此时会出现几个问题:

1、在signal_handler.cpp里,代码需要修改成我写在下面的,原因是注释掉的代码都是linux里的,windows没有这些。

#include <boost/bind.hpp>
#include <glog/logging.h>

#include <signal.h>
#include <csignal>

#include "caffe/util/signal_handler.h"

namespace {
  static volatile sig_atomic_t got_sigint = false;
  static volatile sig_atomic_t got_sighup = false;
  static bool already_hooked_up = false;

  void handle_signal(int signal) {
	  switch (signal) {
		  //case SIGHUP://there is no SIGHUP in windows
		  //  got_sighup = true;
		  //  break;
	  case SIGBREAK:
		  got_sighup = true;
		  break;
	  case SIGINT:
		  got_sigint = true;
		  break;
	  }
  }

  void HookupHandler() {
    if (already_hooked_up) {
      LOG(FATAL) << "Tried to hookup signal handlers more than once.";
    }
    already_hooked_up = true;

    // Setup the handler
	if (signal(SIGBREAK, handle_signal) == SIG_ERR) {
		LOG(FATAL) << "Cannot install SIGBREAK handler.";
	}
	if (signal(SIGINT, handle_signal) == SIG_ERR) {
		LOG(FATAL) << "Cannot install SIGINT handler.";
	}
  }

  // Set the signal handlers to the default.
  void UnhookHandler() {
    if (already_hooked_up) {
		if (signal(SIGBREAK, SIG_DFL) == SIG_ERR) {
			LOG(FATAL) << "Cannot uninstall SIGHUP handler.";
		}
		if (signal(SIGINT, SIG_DFL) == SIG_ERR) {
			LOG(FATAL) << "Cannot uninstall SIGINT handler.";
		}
		already_hooked_up = false;
    }
  }

  // Return true iff a SIGINT has been received since the last time this
  // function was called.
  bool GotSIGINT() {
    bool result = got_sigint;
    got_sigint = false;
    return result;
  }

  // Return true iff a SIGHUP has been received since the last time this
  // function was called.
  bool GotSIGHUP() {
    bool result = got_sighup;
    got_sighup = false;
    return result;
  }
}  // namespace

namespace caffe {

SignalHandler::SignalHandler(SolverAction::Enum SIGINT_action,
                             SolverAction::Enum SIGHUP_action):
  SIGINT_action_(SIGINT_action),
  SIGHUP_action_(SIGHUP_action) {
  HookupHandler();
}

SignalHandler::~SignalHandler() {
  UnhookHandler();
}

SolverAction::Enum SignalHandler::CheckForSignals() const {
  if (GotSIGHUP()) {
    return SIGHUP_action_;
  }
  if (GotSIGINT()) {
    return SIGINT_action_;
  }
  return SolverAction::NONE;
}

// Return the function that the solver can use to find out if a snapshot or
// early exit is being requested.
ActionCallback SignalHandler::GetActionFunction() {
  return boost::bind(&SignalHandler::CheckForSignals, this);
}

}  // namespace caffe

2、io.hpp里增加头文件:#include <io.h>

3、在common,cpp里增加头文件#include <process.h>,同时修改第36行的pid后的代码,改为pid = _getpid(); 原因在于windows的线程头文件不支持linux的。

4、我使用的是CUDNN V5版本。但是在caffe提供的cudnn.hpp头文件里,windows不支持转换。网上有几种解决方法,我自己认为应该把这句话注释掉:


5、我之前提过,happynear的一个小bug。这里提供解决办法。

下载glog 版本的文件,解压后,用vs打开里面的sln文件,将 signalhandler.cc 文件加入到src里,编译后生成的libglog代替3rdparty即可。

6、这个问题很重要。就是在编译好后,将caffe_.mexw64放入相应的文件夹后,总是会有一定几率,报错说找不到这个文件,这个原因很简单,就是由于我们的第三方库,只是在文件的当前下编译的,没有指定到系统路径下去。所以要用dependencywalker,去找一下我们的生成文件,是不是有些dll文件漏了。关于windows一律不看,就只看我们编译过的。

祝你成功。有问题可以在我的博客下留言交流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值