使用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,世界終於清凈了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM