Caffe 是一個高效的深度學習框架,鑒於不想折騰裝個雙系統,最近鼓搗了下用caffe源碼在windows進行編譯。非常感謝Yangqing Jia博士的caffe開源代碼、Neil Z.Shao's博客的指導,以及happynear的工程文件提供的幫助。本博客caffe里C/C++部分編譯主要參考了Neil Z.Shao's博客,python wapper 和 matlab wapper編譯主要參考了happynear的工程文件。鑒於編譯過程並未記錄下詳細流程,步驟不詳之處可參考上述兩個資料。本博客適合對visual studio 2013和opencv配置有一定了解的同學。
1、准備工作
編譯環境:windows 7 64位系統 + Visual studio 2013
依賴包:
- opencv,opencv版本采用的是opencv 3.0,opencv的安裝請參考官方toutorials。opencv 3.0相比之前的版本,配置簡單了很多。
- cuda,cuda版本采用的是cuda 7.0,這個可以從nvidia官網下載。
- Boost,使用的是boost_1_56_0-msvc-12.0-64.exe.
- OpenBLAS、GFlags、GLog、ProtoBuf、LevelDB、HDF5、LMDB,博主偷懶直接采用了Neil Z.Shao提供的編譯好的文件3rdparty.zip。詳細編譯步驟可以參考其博客,以及另外一個github repository。
- caffe源碼,https://github.com/BVLC/caffe
- python 2.7 以及模塊numpy scipy scikit-image matplotlib ipython h5py networkx nose pandas python-dateutil protobuf python-gflags pyyaml Pillow,這些依賴文件在caffe源碼下的python文件夾里的requirements.txt里說明,其中leveldb貌似是沒有windows版本的,不過缺少這個模塊不安裝不影響使用。
- matlab R2014a
2、C/C++編譯
- 新建工程與相應環境配置
- 安裝opencv、cuda、Boost,這些都有exe文件,安裝很直接。
- 下載caffe源碼,並解壓
- 下載第三方依賴包3rdparty.zip,並解壓至caffe源碼下與cmake、data之類文件夾的同級目錄,如下圖所示
4. 打開visual studio 2013 新建win32 控制台工程,並將位置工程的解決方案設在caffe源碼下的根目錄(具體說就是cmake等文件夾與.sln文件是同級目錄)。
5. 將解決方案平台從win32改至x64(在win32下應該也能編譯通過)。修改方法如下圖所示:
(圖片截至Neil Z.Shao's博客)
6. 編譯環境配置:主要是進行解決方案屬性配置,debug x86 和 release x86 需要分別進行配置,如果你僅使用其中一個,對一個進行配置即可。
debug x86 屬性配置:
1) Configuration Properties -> General, Output Directory 設置為‘../bin’(這個文件夾需要新建,主要用於放置編譯輸出的exe文件,這便於后面使用)
2) Configuration Properties -> C/C++ -> General, Additional Include Directories 添加caffe源碼里的include文件夾,src文件夾,第三方依賴包頭文件,cuda頭文件,opencv頭文件,boost頭文件,比如我的配置如下,
*\caffedev\src;
*\caffedev\include;
*\caffedev\3rdparty\include\openblas;
*\caffedev\3rdparty\include\lmdb;
*\caffedev\3rdparty\include\hdf5;
*\caffedev\3rdparty\include;
*\NVIDIA GPU Computing Toolkit\CUDA\v7.0\include;
*\opencv\build\include\opencv2;
*\opencv\build\include\;
*\opencv\build\include\opencv;
*\boost_1_56_0
*省略了軟件的安裝位置,這個根據你的軟件安裝位置找到這些文件夾即可。
3) Configuration Properties -> linker -> General,添加相應的lib文件路徑,我的配置如下
*\caffedev\3rdparty\lib;
*\boost_1_56_0\lib64-msvc-12.0;
*\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64;
*\opencv\build\x64\vc12\lib;
*省略了軟件的安裝位置,這個根據你的軟件安裝位置找到這些文件夾即可。
4) Configuration Properties -> linker -> Input ,添加相應lib文件
opencv_ts300d.lib;opencv_world300d.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;cudart.lib;cuda.lib;nppi.lib;cufft.lib;cublas.lib;curand.lib
release x86 屬性配置:
前三步與debug x86 配置一樣,第4)步的lib文件需要修改為如下:
opencv_ts300.lib;opencv_world300.lib;gflags.lib;libglog.lib;libopenblas.dll.a;libprotobuf.lib;libprotoc.lib;leveldb.lib;lmdb.lib;libhdf5.lib;libhdf5_hl.lib;Shlwapi.lib;cudart.lib;cuda.lib;nppi.lib;cufft.lib;cublas.lib;curand.lib
7. 系統環境變量設置,opencv bin目錄添加到系統環境變量的path里。比如我添加的就是
*\opencv\build\x64\vc12\bin
- 開始編譯
對於像caffe這種大工程文件,最好的辦法就是一個一個文件進行編譯[1]。首先將caffe/src/caffe內的cpp文件導入到解決方案里的Source Files文件夾下,下面對這個幾個文件進行逐個編譯。
- #include <process.h>添加到common.cpp,修復getpid出錯
- Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions,添加_CRT_SECURE_NO_WARNINGS修復fopen_s問題
- 將出錯的getpid行替換為:
#ifndef _MSC_VER pid = getpid(); #else pid = _getpid(); #endif
2、 blob.cpp文件
- caffe.proto創建caffe.pb.h文件,下載GeneratePB.bat文件並放置caffe/scripts文件夾下,雙擊運行即可,再編譯blob.cpp文件,應該能編譯通過
3、 net.cpp文件
- 添加#include “mkstemp.h”(mkstemp.h和mkstemp.cpp已放在3rdpatty里)到io.hpp,可以解決mkstemp缺失問題。
- io.hpp文件里使用到了close函數的行用如下代碼段替換:
#ifndef _MSC_VER close(fd); #else _close(fd); #endif
- 用到mkstemp函數的用如下代碼段替換:
#ifndef _MSC_VER char* mkdtemp_result = mkdtemp(temp_dirname_cstr); #else errno_t mkdtemp_result = _mktemp_s(temp_dirname_cstr, sizeof(temp_dirname_cstr)); #endif
4、solver.cpp文件
- 添加如下行到solver.cpp里修復snprintf問題。
// port for Win32 #ifdef _MSC_VER #define snprintf sprintf_s #endif
5、caffe/src/layers文件夾的文件
- caffe/src/layers文件夾里主要有兩種文件.cpp和.cu文件,.cu文件是用到了cuda的代碼,要編譯這些文件需要進行些設置。首先在Source Files新建一個layers文件夾,並且導入一個.cu文件。
- PROJECT -> Build Customization
(圖片截至Neil Z.Shao's博客)
- 右擊.cu文件選擇屬性,Item Type 設為 CUDA C/C++。
- 將caffe/src/layers文件夾里文件全部導入解決方案里的layers,此時所有.cu文件都具有相同配置屬性。
- 在bnll_layer.cu里修改const float kBNLL_THRESHOLD = 50.為#define kBNLL_THRESHOLD 50.0
6、caffe/src/util
- 新建util文件夾,導入caffe源碼里util文件夾下的代碼,定位到ReadProtoFromBinaryFile函數,修改O_RDONLY 為O_RDONLY | O_BINARY
- 添加如下行到io.cpp文件
// port for Win32 #ifdef _MSC_VER #define open _open #endif
- 手動修改close() 為_close()。
- 添加如下行到math_functions.cpp文件以修復__builtin_popcount 和 __builtin_popcountl出錯
#define __builtin_popcount __popcnt #define __builtin_popcountl __popcnt
7、caffe/src/proto
- 新建proto文件夾,導入caffe/src/proto里通過GeneratePB.bat生成的.cc文件(caffe.pb.cc” 和 “caffe_pretty_print.pb.cc)
- Configuration Properties -> C/C++ -> Command Line (Both Debug and Release mode)添加 -D_SCL_SECURE_NO_WARNINGS 以修復std::_Copy_impl 不安全問題
8、caffe.cpp
- 從caffe/tools里導入caffe.cpp文件
- 右擊解決方案,選build,整個工程應該能順利編譯通過。
- 無GPU的編譯方法
- 步驟基本與上述一致,caffe/src/layers不導入.cu文件
- 在common.hpp添加宏定義
#define CPU_ONLY
- 測試
- 測試方法請參考Neil Z.Shao's博客,這里不再介紹。
3、python wapper編譯
python wapper編譯的資料較少,非常happynear感謝提供的工程文件。主要步驟如下:
- 新建一個工程,配置方法如上。將caffe.cpp移出工程,添加caffe/python/caffe文件下的_caffe.cpp。
- Configuration Properties -> C/C++ -> General, Additional Include Directories 添加:
*\Python27\Lib\site-packages\numpy\core\include;
*\Python27\include;
- Configuration Properties -> linker -> General,添加相應的lib文件路徑:
*\Python27\libs;
- Configuration Properties -> linker -> Input ,添加相應lib文件
python27.lib
- Configuration Properties -> linker -> General,Output Directory 設置為..\python\caffe,Targe Name 設為_caffe, Target Extension設為.pyd,Configuration Type設為 Dynamic Library(.dll)。
- 此時應該能順利編譯通過。
- 安裝相應的python依賴包,這個使用 pip install 命令即可安裝。leveldb沒有windows版本,這個不安裝不影響使用。
- 若你采用的debug模式編譯,需要將3rdparty壓縮包bin里的dll文件和boost_python-vc120-mt-1_56.dll拷貝至python/caffe。
- 在之前的GeneratePB.bat文件添加如下行,雙擊運行。並將/src/caffe/proto文件夾拷貝至python/caffe下,並在proto文件夾里創建一個名為__init__.py的空文件。
"../3rdparty/bin/protoc" -I="../src/caffe/proto" --python_out="../src/caffe/proto" "../src/caffe/proto/caffe.proto"
- 將src/caffe/proto文件拷至python/caffe
- 將*/python/caffe添加至系統變量。
- 下載安裝Graphviz2.38,並將*\Graphviz2.38\bin添加到系統變量。
- 這樣python文件夾下的大部分功能應該都能使用。
4、matlab wapper編譯
matlab wapper編譯和python差不多較少。主要步驟如下:
- 新建一個工程,配置方法如C/C++部分。將caffe.cpp移出工程,添加caffe/matlab/+caffe/private文件下的caffe_.cpp。
- Configuration Properties -> C/C++ -> General, Additional Include Directories 添加:
*\MATLAB\R2014a\extern\include;
- Configuration Properties -> linker -> General,添加相應的lib文件路徑:
*\MATLAB\R2014a\extern\lib\win64\microsoft;;
- Configuration Properties -> linker -> Input ,添加相應lib文件
libmex.lib;libmat.lib;libmx.lib
- Configuration Properties -> linker -> General,Output Directory 設置為..\matlab\+caffe\private,Targe Name 設為caffe_, Target Extension設為.mexw64,Configuration Type設為 Dynamic Library(.dll)。
- 此時應該能順利編譯通過。
- 這樣matlab\文件夾下的大部分功能應該都能使用。matlab\demo\classification_demo.m 可用於測試是否安裝成功,需要用到的訓練好的模型可以從這里下載http://dl.caffe.berkeleyvision.org/。
5、后記
- C/C++部分參考Neil Z.Shao's博客,編譯還是比較順利的。python資料比較少,走了些彎路,happynear的工程文件提供了不少幫助,對此表示感謝。
reference:
[2] http://blog.csdn.net/happynear/article/details/45372231