使用vs2015编译、部署ssd-caffe(weiliu89版,CPU模式)

      前因项目所需,须训练一个快速模型以实现目标物体的实时检测。历经多次实践,发现MobileNetSSD网络符合要求,故在本人工作PC上部署weiliu89版本的ssd-caffe以期用之训练项目要求之模型。当时思之甚简,网络上相关文章多矣,此事应不成问题。然一番搜索后才发现,前人多在linux下进行,针对windows者寥寥,仅有几篇亦是使用的支持MS VS2013的conner99版本的ssd-caffe,与我的项目要求相去甚远(虽然可以将conner89版本的caffe工程从VS2013升级为VS2015,但升级后的效果很不好,编译有很多问题,CMake重新构建工程亦如此,不如干净的weiliu89版本)。虽然我的工作机器装有两个独立的OS:win10和ubuntu,完全可以在ubuntu下部署、训练模型,在windows环境下使用模型,如此亦可满足项目要求。但如此操作,须在两个OS中频繁切换,甚是繁琐,这对于有严重强迫症的我来说——如鲠在喉,无法忍受。于是,我决心解决windows下的部署问题。所幸,BVLC版本的caffe已经在win10下使用VS2015编译、部署成功(感谢BVLC-Caffe团队的卓越工作,使得该版本的caffe在windows平台下编译、部署如此简单),而weiliu89版本的caffe亦fork于此,源码基本相同,这使得此事有据可考,难度骤降。然躬行后方知,难度虽降,过程依旧曲折,历经打击无数,事方成。现在想来,不抛弃、不放弃——真真是说易行难。以下开始详述操作过程,备忘及有需者参考。

      开始编译之前,我们要先进行编译环境的准备工作(如果你已经成功编译BVLC版本的caffe,请略过),详细操作步骤如下:

1、安装CMake,这个不多说,官网有windows版本直接安装就行,下载地址:https://cmake.org/download/,我自己用的是3.11,更新的版本估计应该也没问题,下载后直接安装,一路Next即可;

2、下载boost,下载地址:https://sourceforge.net/projects/boost/files/boost-binaries/,可以找一个最新版本,我自己用的是1.61.0(boost_1_61_0-msvc-14.0-64.exe),下载成功后安装即可,对安装没什么特殊要求。在我的机器上,boost默认安装在了C:\local\boost_1_61_0下;

3、下载libraries_v140_x64_py35_1.1.0.tar.bz2,与上面的boost一样,这个是caffe需要的第三方支持库,下载地址:https://github.com/willyd/caffe-builder/releases,下载完成后解压到本地目录下,我自己借用的原先编译BVLC-Caffe遗留的库,所以没有再次下载、解压,我机器上的库路径为:C:\Users\user\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries,内容如下:

image

4、安装python35,注意一定是python35,不要安装更高的版本,caffe对这个版本支持最好,下载地址:https://www.python.org/ftp/python,随便选择一个3.5版本的python即可,我自己用的是python3.5.4(python-3.5.4-amd64.exe)。下载后安装,一路Next即可,注意安装时一定要选择“添加到系统路径”中,这样方便在控制台执行python,python3的缺省安装路径为C:\Users\user\AppData\Local\Programs\Python\Python35;

5、可选步骤,编译安装最新的opencv,这个可以略过,因为下载的libraries_v140_x64_py35_1.1.0库已经包含了opencv3.1.0,如果你想用最新的opencv,那么就需要在这里部署好,我自己用的是opencv3.4.1,部署在了C:\MVLThirdPartyLib\opencv\build路径下:

image

6、将相关执行路径添加到系统的环境变量中,这一步非常关键,关系到configure以及pycaffe的正确加载:

image

将如下路径添加到“系统变量”或“用户变量”(二选一,推荐“系统变量”)的“Path”中:

C:\Users\user\AppData\Local\Programs\Python\Python35\Scripts\
C:\Users\user\AppData\Local\Programs\Python\Python35\
C:\MVLThirdPartyLib\opencv\build\x64\vc14\bin
C:\local\boost_1_61_0\lib64-msvc-14.0
C:\Users\user\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\bin

7、编译时如果遇到找不到libboost_filesystem-vc140-mt-1_61.lib之类的文件,请到boost的安装目录下去找,找到后copy到libraries_v140_x64_py35_1.1.0库的lib文件夹下,切记!!!

如此,编译环境的准备工作完成。接下来就是获取ssd-caffe的源码(此处假设你已成功安装git):

git clone https://github.com/weiliu89/caffe.git 

如果你想省事,忽略接下来修改部分代码的工作,或者说编译时你不想看到更多的错误的话,你也可以直接从我自己的github仓库中获取修改后的工程源码,该源码fork于weiliu89,增加了对MSVC++的支持:

git clone https://github.com/Neo-T/caffe.git

拜GFW所赐,请耐心等待,如果你有早起习惯,建议早上5-7点之间clone,最晚不要超过8点,此时速度会快很多(我clone的速度曾经达到500KB/S左右,过了这个时间段就成了十几、二十几KB/S了)。clone完成后,请在ssd-caffe的根目录下建立一个“build”目录,如下所示:

image

接着打开CMake的GUI界面(cmake-gui),开始配置并生成ssd-caffe的VS2015工程的工作,首先选择刚才clone下来的ssd-caffe的工程路径(在我的机器上clone完成后,为了与BVLC版本有所区别,我把ssd-caffe的根目录名称caffe改成了ssd_caffe):

image

然后点选confgure,选择VS2015作为编译工具(如果你想用其它版本的VS,建议用高版本的,尽量别用低版本的,特别是VS2010以下的):

image

Finish”确认选择,CMake会开始配置并给出初步的配置结果:

image

令人头疼的“Error”以及后面的一大片红,果然没有什么奇迹,configure失败。点击“OK”,开始一步步消除错误:

1、设定宏观的配置选项,选择BLAS为Open版本,不开启GPU加速,python为3:

image

设置好后,继续configure;

2、设定OpenBLAS的相关路径:

image

之后,继续configure(到这一步,CMake界面虽然还是有一大片红,但不会再弹窗提示存在错误了,除非你的编译环境准备工作没有做好,下面的输出信息也会提示“Configuring done”,但到这里其实配置还没有结束,还得继续);

3、设定gflags和glog的库路径,这一步非常重要,否则生成的工程会自动下载相关源码并编译,一旦如此,你会陷入无尽深渊,死在编译这两个工程上:

image

4、设定生成pycaffe(训练模型之用),同时取消生成Dll动态库。因为生成Dll会对编译生成caffe.exe造成麻烦,虽然造成的麻烦可以解决,但操作起来比较繁琐,干脆就不生成了,反正内存和磁盘空间够大:

image

至此,configure才算真正完成:

image

此时,“Generate”按钮不再是灰色了,可以生成VS2015的工程了(对于configure过程中的“CMake Warning”之类的警告信息忽略即可)。点击“Generate”,生成VS2015工程,然后点击“Open Project”按钮,打开该工程,开始我们的编译之旅(真正头疼的时刻来到了)。

      首先,把解决方案的工程配置改为“Release x64”:

image

然后,开始编译生成caffe。鼠标右键点选左侧的“caffe”,然后点击“生成”即可。注意,这里一定是要先生成caffe,千万别直接生成整个解决方案:

image

大约几分钟后,编译完成,结果是成功两个,失败一个:

image

还不错,看看都是什么错误,点击“输出”按钮右侧的“错误列表”,错误有52个:

image

这些错误都是因为编译器的缘故造成的,需要调整代码和预编译宏,针对getpid错误,需要在common.cpp文件的头部增加如下几行代码:

#if defined(_MSC_VER)
#include <process.h>
#define getpid() _getpid()
#endif

如此就可以解决找不到getpid的问题了。关于““std::tuple”: 模板 参数“_Types”与声明不兼容”的错误,打开gtest.h文件就可以看出这个与gtest有关,是否使用google test自己的tr1 tuple实现:

image

其实源文件已经针对MSVC作出了定义,“GTEST_USE_OWN_TR1_TUPLE”宏为0,意味着不使用google test,但在编辑窗口显示该宏为灰色,没有起作用。这是因为我们在生成工程时,CMake将其定义在了工程配置文件中。打开caffe工程的属性窗口,找到“C/C++”->“预处理器”->“预处理器定义”,点开下选单,选择“编辑”:

image

删除“GTEST_USE_OWN_TR1_TUPLE”宏即可。接着,我们继续编译,依然错误很多:

image

鼠标左键双击第一条错误,定位打开发生错误的文件,将db_lmdb.cpp文件头部的代码调整如下(红色部分为新增加的代码):


#ifdef USE_LMDB
#include "caffe/util/db_lmdb.hpp"


#if defined(_MSC_VER)
#include <direct.h>
#define mkdir(X, Y) _mkdir(X)
#endif


#include <sys/stat.h>


#include <string>

 

其中红色部分为新添加的代码。继续双击错误列表的第三条错误,同样在打开的文件中将代码修改如下:

switch (class_) {
case H5T_FLOAT:
  { LOG_FIRST_N(INFO, 1) << "Datatype class: H5T_FLOAT"; }
  break;
case H5T_INTEGER:
  { LOG_FIRST_N(INFO, 1) << "Datatype class: H5T_INTEGER"; }
  break;
case H5T_TIME:
  LOG(FATAL) << "Unsupported datatype class: H5T_TIME";
case H5T_STRING:
……………………
}

其实就是在前两条case语句中增加两对“{}”而已,确保语句的完整性。改完存盘,继续编译,错误依旧:

image

现在错误发生的阵地转移到了io.cpp文件中,双击定位到具体位置,然后在文件头部增加如下代码:


#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <fcntl.h>


#if defined(_MSC_VER)
#include <io.h>
#endif

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>

 

继续双击“SIGHUP”:未声明的标识符”错误,在打开的位置修改handle_signal()函数

void handle_signal(int signal) {
    switch (signal) {
#ifdef _MSC_VER
    case SIGBREAK:  // there is no SIGHUP in windows, take SIGBREAK instead.
	got_sighup = true;
	break;
#else
    case SIGHUP:
	got_sighup = true;
	break;
#endif
    case SIGINT:
        got_sigint = true;
        break;
    }
  }

继续在该文件调整代码,下一个是HookupHandler()函数:

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

#ifdef _MSC_VER
    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.";
    }
#else
    struct sigaction sa;
    // Setup the handler
    sa.sa_handler = &handle_signal;
    // Restart the system call, if at all possible
    sa.sa_flags = SA_RESTART;
    // Block every signal during the handler
    sigfillset(&sa.sa_mask);
    // Intercept SIGHUP and SIGINT
    if (sigaction(SIGHUP, &sa, NULL) == -1) {
	LOG(FATAL) << "Cannot install SIGHUP handler.";
    }
    if (sigaction(SIGINT, &sa, NULL) == -1) {
 	LOG(FATAL) << "Cannot install SIGINT handler.";
    }
#endif
  }

最后是UnhookHandler()函数:

// Set the signal handlers to the default.
  void UnhookHandler() {
    if (already_hooked_up) {
#ifdef _MSC_VER
	if (signal(SIGBREAK, SIG_DFL) == SIG_ERR) {
		LOG(FATAL) << "Cannot uninstall SIGBREAK handler.";
	}
	if (signal(SIGINT, SIG_DFL) == SIG_ERR) {
		LOG(FATAL) << "Cannot uninstall SIGINT handler.";
	}
#else
	struct sigaction sa;
	// Setup the sighub handler
	sa.sa_handler = SIG_DFL;
	// Restart the system call, if at all possible
	sa.sa_flags = SA_RESTART;
	// Block every signal during the handler
	sigfillset(&sa.sa_mask);
	// Intercept SIGHUP and SIGINT
	if (sigaction(SIGHUP, &sa, NULL) == -1) {
		LOG(FATAL) << "Cannot uninstall SIGHUP handler.";
	}
	if (sigaction(SIGINT, &sa, NULL) == -1) {
		LOG(FATAL) << "Cannot uninstall SIGINT handler.";
	}
#endif

      already_hooked_up = false;
    }
  }

继续编译,再也没有错误了,成功:

image

接着编译pycaffe,毫无例外的是,错误如幽灵般再次卷土重来:

LINK : fatal error LNK1104: 无法打开文件“libboost_date_time-vc140-mt-1_61.lib”

这显然是找不到库文件,我们将库文件的目录添加上就可以了。打开pycaffe的属性界面,然后在“VC++目录”->“库目录”,打开下选单,选择“编辑”,将第三方库的搜索路径添加进去,在这里就是:

C:\Users\user\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib

如果你部署的libraries_v140_x64_py35_1.1.0库的路径与我不一样,请调整成你自己的路径。

继续编译,上述错误消失,又产生了新的错误:

无法解析的外部符号 "__declspec(dllimport) struct _object * __cdecl boost::python::detail::init_module(struct PyModuleDef &,void (__cdecl*)(void))"

无法解析的外部符号 "__declspec(dllimport) public: __cdecl google::base::CheckOpMessageBuilder::CheckOpMessageBuilder(char const *)"

无法解析的外部符号 "__declspec(dllimport) public: __cdecl google::base::CheckOpMessageBuilder::~CheckOpMessageBuilder(void)"

……

这种错误是因为缺少第三方支持库导致的,我们只需将其引入即可,依然在pycaffe的属性界面,点选“链接器”->“输入”->“附加依赖项”,打开下选单,选择编辑,输入系统需要引入的第三方支持库的名称:

..\lib\Release\caffe.lib
..\lib\Release\proto.lib
glog.lib
gflags.lib
libprotobuf.lib
C:\MVLThirdPartyLib\opencv\build\x64\vc14\lib\opencv_world341.lib
caffehdf5.lib
caffehdf5_hl.lib
libopenblas.dll.a

其中opencv的路径需要根据自身情况调整,其它直接复制即可。继续编译,错误还剩下几个:

无法解析的外部符号 "__declspec(dllimport) struct _object * __cdecl boost::python::detail::init_module(struct PyModuleDef &,void (__cdecl*)(void))"

无法解析的外部符号 "class caffe::Solver<float> const volatile * __cdecl boost::get_pointer<class caffe::……)"

……

无法解析的外部符号 "__declspec(dllimport) void __cdecl google::InstallFailureSignalHandler(void)"

仔细分析,就剩下三个函数无法解析了,也就是说需要找到这三个函数的第三方库。关于第一个错误“init_module”,这个是因为python2和python3的类型不兼容导致的,而CMake将python2的库引入到了工程中,导致链接错误,我们只需将python库的名称改对就可以了。打开pycaffe的“附加依赖项”窗口,找到如下一句:

C:\local\boost_1_61_0\lib64-msvc-14.0\boost_python-vc140-mt-1_61.lib

将其修改为:

boost_python3-vc140-mt-1_61.lib

我们不使用boost提供的python2库,改用libraries_v140_x64_py35_1.1.0提供的python3库即可。

      关于第二个错误“get_pointer”,需要修改pycaffe工程下的_caffe.cpp文件,在其第40和42行之间增加如下代码:

#if defined(_MSC_VER) && (_MSC_FULL_VER >= 190024210)
// Workaround for VS 2015 Update 3 which breaks boost python
// See: http://stackoverflow.com/questions/38261530/unresolved-external-symbols-since-visual-studio-2015-update-3-boost-python-link
// and https://msdn.microsoft.com/vs-knownissues/vs2015-update3
#define BP_GET_POINTER(cls) \
namespace boost { \
template <> \
const volatile caffe::cls * \
get_pointer(const volatile caffe::cls *c) { \
    return c; \
} \
}

#define BP_GET_POINTER_T(cls, dtype) BP_GET_POINTER(cls<dtype>)

BP_GET_POINTER_T(Net, float);
BP_GET_POINTER_T(Layer, float);
BP_GET_POINTER_T(Solver, float);
BP_GET_POINTER_T(SGDSolver, float);
BP_GET_POINTER_T(NesterovSolver, float);
BP_GET_POINTER_T(AdaGradSolver, float);
BP_GET_POINTER_T(RMSPropSolver, float);
BP_GET_POINTER_T(AdaDeltaSolver, float);
BP_GET_POINTER_T(AdamSolver, float);

#endif

关于第三个错误“google::InstallFailureSignalHandler(void)”,在caffe工程下找到我们原先修改过的common.cpp文件,大约在该文件的48行左右找到GlobalInit()函数,将该函数修改如下:

void GlobalInit(int* pargc, char*** pargv) {
  // Google flags.
  ::gflags::ParseCommandLineFlags(pargc, pargv, true);
  // Google logging.
  ::google::InitGoogleLogging(*(pargv)[0]);
  // Provide a backtrace on segfault.

#if !defined(_MSC_VER)
    ::google::InstallFailureSignalHandler();
#endif
}

修改完毕后,再一次编译caffe,然后再编译pycaffe,此时就可以顺利编译成功pycaffe了。不过,现在编译成功的pycaffe还不是完整版本,缺少必要的DNN网络模块,需要将我们用到的各层定义手动添加到pycaffe中,否则会报“Check failed: registry.count(t ype) == 1 (0 vs. 1) Unknown layer type: xxx(known types: xxx )”错误,继续修改_caffe.cpp文件,在这个文件的69和71行之间添加如下代码(红色部分):

namespace bp = boost::python;

#include "caffe/layers/input_layer.hpp"
#include "caffe/layers/inner_product_layer.hpp"
#include "caffe/layers/dropout_layer.hpp"
#include "caffe/layers/conv_layer.hpp"
#include "caffe/layers/relu_layer.hpp"

#include "caffe/layers/pooling_layer.hpp"
#include "caffe/layers/lrn_layer.hpp"
#include "caffe/layers/softmax_layer.hpp"
#include "caffe/layers/permute_layer.hpp"
#include "caffe/layers/flatten_layer.hpp"
#include "caffe/layers/prior_box_layer.hpp"
#include "caffe/layers/concat_layer.hpp"
#include "caffe/layers/reshape_layer.hpp"
#include "caffe/layers/detection_output_layer.hpp"

接着在87行下面,也就是“namespace caffe {”下面添加各层定义语句:

extern INSTANTIATE_CLASS(InputLayer);
extern INSTANTIATE_CLASS(InnerProductLayer);
extern INSTANTIATE_CLASS(DropoutLayer);
extern INSTANTIATE_CLASS(MemoryDataLayer);
extern INSTANTIATE_CLASS(ConvolutionLayer);
REGISTER_LAYER_CLASS(Convolution);
extern INSTANTIATE_CLASS(ReLULayer);
REGISTER_LAYER_CLASS(ReLU);
extern INSTANTIATE_CLASS(PoolingLayer);
REGISTER_LAYER_CLASS(Pooling);
extern INSTANTIATE_CLASS(LRNLayer);
REGISTER_LAYER_CLASS(LRN);
extern INSTANTIATE_CLASS(SoftmaxLayer);
REGISTER_LAYER_CLASS(Softmax);
extern INSTANTIATE_CLASS(PermuteLayer);
extern INSTANTIATE_CLASS(FlattenLayer);
extern INSTANTIATE_CLASS(PriorBoxLayer);
extern INSTANTIATE_CLASS(ConcatLayer);
extern INSTANTIATE_CLASS(ReshapeLayer);
extern INSTANTIATE_CLASS(DetectionOutputLayer);

再次编译就可以了。以后如再遇到pycaffe报未知层类型之类的错误,继续在这里添加对应的层就行了。至此两个主要核心模块编译完成。接下来就是编译相关工具软件了。

      我们先编译tools,首先是caffe.bin工程,这个工程生成caffe.exe文件。与编译之前的两个工程相似,编译出现的错误主要集中在库文件上,所以我们把库的搜索目录和需要引入的库添加到caffe.bin中即可,库的搜索目录依然是:C:\Users\user\.caffe\dependencies\libraries_v140_x64_py35_1.1.0\libraries\lib,要引入的库文件如下:

C:\Users\user\AppData\Local\Programs\Python\Python35\libs\python35.lib
..\lib\Release\caffe.lib
..\lib\Release\proto.lib
C:\MVLThirdPartyLib\opencv\build\x64\vc14\lib\opencv_world341.lib
glog.lib
gflags.lib
libprotobuf.lib
caffehdf5.lib
caffehdf5_hl.lib
libopenblas.dll.a

编译,此时会报“输出文件名匹配输入文件名“D:\caffe\build\lib\Release\caffe.lib””错误,这也是这个版本的主要问题,不适合VS编译,编译caffe.exe需要caffe.lib,但中间的输出文件还是caffe.lib,编译器就会无所适从,所以我们需要手动调整这个地方,将引入的文件改为caffe_static.lib,同时修改实际生成的caffe.lib为caffe_static.lib,如下:

1、修改引入库“..\lib\Release\caffe.lib”名称为“..\lib\Release\caffe_static.lib”;

2、在ssd-caffe的build\lib\Release文件夹下找到caffe.lib文件,将其重命名为caffe_static.lib

再次编译即可成功。最后,再到build\lib\Release文件夹下,删除掉新生成的caffe.lib,将原来的caffe_static.lib改成caffe.lib,以为后续工作之用。

      接着编译剩余tools,为了省事我们可以批量修改工程属性。鼠标左键点击最上面的“compute_image_mean”工程,然后按下键盘“Shift”键,同时鼠标左键点击最下面的“upgrade_solver_proto_text”工程,鼠标右键打开工程属性界面,添加库的搜索目录和需要引入的库文件。库的搜索路径与上同,需要引入的库文件如下:

ntdll.lib
C:\Users\user\AppData\Local\Programs\Python\Python35\libs\python35.lib
..\lib\Release\caffe.lib
..\lib\Release\proto.lib
C:\MVLThirdPartyLib\opencv\build\x64\vc14\lib\opencv_world341.lib
glog.lib
gflags.lib
libprotobuf.lib
caffehdf5.lib
caffehdf5_hl.lib
libopenblas.dll.a
lmdb.lib
leveldb.lib
snappy.lib

添加完毕,编译即可。不出意外,应该能编译成功,除非路径不对或者漏了某个步骤。

      接下来,我们编译examples,同样是批量修改工程属性,添加库的搜索路径和引入的库名称,搜索路径同上,引入库的名称如下:

boost_filesystem-vc140-mt-1_61.lib
boost_system-vc140-mt-1_61.lib
ntdll.lib
C:\Users\user\AppData\Local\Programs\Python\Python35\libs\python35.lib
..\lib\Release\caffe.lib
..\lib\Release\proto.lib
C:\MVLThirdPartyLib\opencv\build\x64\vc14\lib\opencv_world341.lib
glog.lib
gflags.lib
libprotobuf.lib
caffehdf5.lib
caffehdf5_hl.lib
libopenblas.dll.a
lmdb.lib
leveldb.lib
snappy.lib

不出意外,同样可以顺利编译成功。最后,我们可以INSTALL这些生成的文件了。鼠标右键点选工程左侧的“INSTALL”,点击“生成”,即可将所有生成的文件复制到build目录下的install文件夹,如下图所示:

image

由于训练模型需要用到pycaffe,所以我们好要测试一下pycaffe是否可用。有两种方案配置pycaffe,一种是在环境变量中添加“PYTHONPATH”,将pycaffe的路径(对于我来说就是D:\work\OpenCV\ssd_caffe\build\install\python)添加进去;还有一种方式就是直接把build\install\python下的caffe文件夹copy到python安装目录下的Lib\site-packages文件夹下。我使用的后者。前面说了,我的机器上已经部署了BVLC版本的pycaffe,那么要想正常使用ssd-caffe就必须解决两个版本并存的问题,我的解决方案就是修改pycaffe的包名称,其实就是pycaffe所在目录的目录名,我把ssd-caffe版本的pycaffe包名称改成了caffe_ssd,如下:

image

我们在复制build\install\python下的caffe文件夹时,把文件夹名称改成caffe_ssd后再复制过来就可以解决版本并存问题。上图中caffe即为BVLC版本的pycaffe。这样我们在导入时,以包名区分即可:

import caffe          #导入BVLC版本的caffe

import caffe_ssd   #导入weiliu89版本的caffe

在实际进行import之前,我们还需要做最后一步工作,将caffe_ssd\下的_caffe.dll文件重命名为_caffe.pyd,如此才可正常import,导入结果如下:

image

至此整个ssd-caffe的编译部署工作完成。

 

上述工作的最终源码请从如下地址获取:

https://github.com/Neo-T/caffe

 

附记——import pycaffe出现的常见错误解决方法:

1、ImportError: DLL load failed: 找不到指定的程序

这个错误是pycaffe在加载时无法找到编译时引入的第三方库对应的dll,两种方式解决这个问题,一种是直接copy相应的dll文件到_caffe.pyd所在的文件夹下;另外一种方式是将DLL所在的路径添加到系统环境变量中,由于我们在之前已经将其添加到环境变量中了,因此,正常情况下你不会遇到此问题。如果实在不知道要copy哪个文件,请到如下地址下载一个能够查看dll依赖的工具“Dependency Walker”:

http://www.dependencywalker.com/

选择下载“Download Version 2.2.6000 for x64 [468k]”即可。用该工具打开_caffe.pyd,出现叹号的是找不到依赖DLL的,直接复制或将其所在路径加入系统环境变量即可。

2、ImportError: DLL load failed: 找不到指定的模块

这个错误还是因为python2和python3不兼容的问题,系统加载_caffe.pyd时使用的应该是“boost_python3-vc140-mt-1_61.dll”,如果在指定的搜索路径下找不到它就会报这个错误,所以我们只需将其添加到搜索路径中就可以了。

3、TypeError: Couldn't build proto file into descriptor pool!

这个错误很吓人,输出的信息会占满整个屏幕,然后在错误信息的下方你会找到上述错误语句。这个错误是因为你的机器安装的protobuf版本不匹配导致的(如果你是pip自动安装,一般安装的都是最新的稳定版本),我们需要卸载已经安装的protobuf版本,然后指定一个比较老的版本即可:

pip uninstall protobuf

我的机器安装的就是3.6.1版本,这个版本就不能很好的适配ssd-caffe,所以我指定安装了3.3版本:

pip install protobuf==3.3.0

再次import pycaffe,世界终于清净了。

posted @ 2018-10-18 22:38  Neo-T  阅读(3057)  评论(0编辑  收藏  举报