前因项目所需,须训练一个快速模型以实现目标物体的实时检测。历经多次实践,发现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:localboost_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:Usersuser.caffedependencieslibraries_v140_x64_py35_1.1.0libraries,内容如下:
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:UsersuserAppDataLocalProgramsPythonPython35;
5、可选步骤,编译安装最新的opencv,这个可以略过,因为下载的libraries_v140_x64_py35_1.1.0库已经包含了opencv3.1.0,如果你想用最新的opencv,那么就需要在这里部署好,我自己用的是opencv3.4.1,部署在了C:MVLThirdPartyLibopencvbuild路径下:
6、将相关执行路径添加到系统的环境变量中,这一步非常关键,关系到configure以及pycaffe的正确加载:
将如下路径添加到“系统变量”或“用户变量”(二选一,推荐“系统变量”)的“Path”中:
C:UsersuserAppDataLocalProgramsPythonPython35Scripts
C:UsersuserAppDataLocalProgramsPythonPython35
C:MVLThirdPartyLibopencvbuildx64vc14bin
C:localboost_1_61_0lib64-msvc-14.0
C:Usersuser.caffedependencieslibraries_v140_x64_py35_1.1.0librariesbin
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”目录,如下所示:
接着打开CMake的GUI界面(cmake-gui),开始配置并生成ssd-caffe的VS2015工程的工作,首先选择刚才clone下来的ssd-caffe的工程路径(在我的机器上clone完成后,为了与BVLC版本有所区别,我把ssd-caffe的根目录名称caffe改成了ssd_caffe):
然后点选confgure,选择VS2015作为编译工具(如果你想用其它版本的VS,建议用高版本的,尽量别用低版本的,特别是VS2010以下的):
“Finish”确认选择,CMake会开始配置并给出初步的配置结果:
令人头疼的“Error”以及后面的一大片红,果然没有什么奇迹,configure失败。点击“OK”,开始一步步消除错误:
1、设定宏观的配置选项,选择BLAS为Open版本,不开启GPU加速,python为3:
设置好后,继续configure;
2、设定OpenBLAS的相关路径:
之后,继续configure(到这一步,CMake界面虽然还是有一大片红,但不会再弹窗提示存在错误了,除非你的编译环境准备工作没有做好,下面的输出信息也会提示“Configuring done”,但到这里其实配置还没有结束,还得继续);
3、设定gflags和glog的库路径,这一步非常重要,否则生成的工程会自动下载相关源码并编译,一旦如此,你会陷入无尽深渊,死在编译这两个工程上:
4、设定生成pycaffe(训练模型之用),同时取消生成Dll动态库。因为生成Dll会对编译生成caffe.exe造成麻烦,虽然造成的麻烦可以解决,但操作起来比较繁琐,干脆就不生成了,反正内存和磁盘空间够大:
至此,configure才算真正完成:
此时,“Generate”按钮不再是灰色了,可以生成VS2015的工程了(对于configure过程中的“CMake Warning”之类的警告信息忽略即可)。点击“Generate”,生成VS2015工程,然后点击“Open Project”按钮,打开该工程,开始我们的编译之旅(真正头疼的时刻来到了)。
首先,把解决方案的工程配置改为“Release x64”:
然后,开始编译生成caffe。鼠标右键点选左侧的“caffe”,然后点击“生成”即可。注意,这里一定是要先生成caffe,千万别直接生成整个解决方案:
大约几分钟后,编译完成,结果是成功两个,失败一个:
还不错,看看都是什么错误,点击“输出”按钮右侧的“错误列表”,错误有52个:
这些错误都是因为编译器的缘故造成的,需要调整代码和预编译宏,针对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实现:
其实源文件已经针对MSVC作出了定义,“GTEST_USE_OWN_TR1_TUPLE”宏为0,意味着不使用google test,但在编辑窗口显示该宏为灰色,没有起作用。这是因为我们在生成工程时,CMake将其定义在了工程配置文件中。打开caffe工程的属性窗口,找到“C/C++”->“预处理器”->“预处理器定义”,点开下选单,选择“编辑”:
删除“GTEST_USE_OWN_TR1_TUPLE”宏即可。接着,我们继续编译,依然错误很多:
鼠标左键双击第一条错误,定位打开发生错误的文件,将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语句中增加两对“{}”而已,确保语句的完整性。改完存盘,继续编译,错误依旧:
现在错误发生的阵地转移到了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; } }
继续编译,再也没有错误了,成功:
接着编译pycaffe,毫无例外的是,错误如幽灵般再次卷土重来:
LINK : fatal error LNK1104: 无法打开文件“libboost_date_time-vc140-mt-1_61.lib”
这显然是找不到库文件,我们将库文件的目录添加上就可以了。打开pycaffe的属性界面,然后在“VC++目录”->“库目录”,打开下选单,选择“编辑”,将第三方库的搜索路径添加进去,在这里就是:
C:Usersuser.caffedependencieslibraries_v140_x64_py35_1.1.0librarieslib
如果你部署的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的属性界面,点选“链接器”->“输入”->“附加依赖项”,打开下选单,选择编辑,输入系统需要引入的第三方支持库的名称:
..libReleasecaffe.lib
..libReleaseproto.lib
glog.lib
gflags.lib
libprotobuf.lib
C:MVLThirdPartyLibopencvbuildx64vc14libopencv_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:localboost_1_61_0lib64-msvc-14.0boost_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:Usersuser.caffedependencieslibraries_v140_x64_py35_1.1.0librarieslib,要引入的库文件如下:
C:UsersuserAppDataLocalProgramsPythonPython35libspython35.lib
..libReleasecaffe.lib
..libReleaseproto.lib
C:MVLThirdPartyLibopencvbuildx64vc14libopencv_world341.lib
glog.lib
gflags.lib
libprotobuf.lib
caffehdf5.lib
caffehdf5_hl.lib
libopenblas.dll.a
编译,此时会报“输出文件名匹配输入文件名“D:caffebuildlibReleasecaffe.lib””错误,这也是这个版本的主要问题,不适合VS编译,编译caffe.exe需要caffe.lib,但中间的输出文件还是caffe.lib,编译器就会无所适从,所以我们需要手动调整这个地方,将引入的文件改为caffe_static.lib,同时修改实际生成的caffe.lib为caffe_static.lib,如下:
1、修改引入库“..libReleasecaffe.lib”名称为“..libReleasecaffe_static.lib”;
2、在ssd-caffe的buildlibRelease文件夹下找到caffe.lib文件,将其重命名为caffe_static.lib;
再次编译即可成功。最后,再到buildlibRelease文件夹下,删除掉新生成的caffe.lib,将原来的caffe_static.lib改成caffe.lib,以为后续工作之用。
接着编译剩余tools,为了省事我们可以批量修改工程属性。鼠标左键点击最上面的“compute_image_mean”工程,然后按下键盘“Shift”键,同时鼠标左键点击最下面的“upgrade_solver_proto_text”工程,鼠标右键打开工程属性界面,添加库的搜索目录和需要引入的库文件。库的搜索路径与上同,需要引入的库文件如下:
ntdll.lib
C:UsersuserAppDataLocalProgramsPythonPython35libspython35.lib
..libReleasecaffe.lib
..libReleaseproto.lib
C:MVLThirdPartyLibopencvbuildx64vc14libopencv_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:UsersuserAppDataLocalProgramsPythonPython35libspython35.lib
..libReleasecaffe.lib
..libReleaseproto.lib
C:MVLThirdPartyLibopencvbuildx64vc14libopencv_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文件夹,如下图所示:
由于训练模型需要用到pycaffe,所以我们好要测试一下pycaffe是否可用。有两种方案配置pycaffe,一种是在环境变量中添加“PYTHONPATH”,将pycaffe的路径(对于我来说就是D:workOpenCVssd_caffebuildinstallpython)添加进去;还有一种方式就是直接把buildinstallpython下的caffe文件夹copy到python安装目录下的Libsite-packages文件夹下。我使用的后者。前面说了,我的机器上已经部署了BVLC版本的pycaffe,那么要想正常使用ssd-caffe就必须解决两个版本并存的问题,我的解决方案就是修改pycaffe的包名称,其实就是pycaffe所在目录的目录名,我把ssd-caffe版本的pycaffe包名称改成了caffe_ssd,如下:
我们在复制buildinstallpython下的caffe文件夹时,把文件夹名称改成caffe_ssd后再复制过来就可以解决版本并存问题。上图中caffe即为BVLC版本的pycaffe。这样我们在导入时,以包名区分即可:
import caffe #导入BVLC版本的caffe
import caffe_ssd #导入weiliu89版本的caffe
在实际进行import之前,我们还需要做最后一步工作,将caffe_ssd下的_caffe.dll文件重命名为_caffe.pyd,如此才可正常import,导入结果如下:
至此整个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,世界终于清净了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用vs2015编译、部署ssd-caffe(weiliu89版,CPU模式) - Python技术站