週六週日在家倒騰了兩天,總算稍微瞭解點pycaffe的一些接口和api設置了,但是針對不同層,還是有很多注意的細節的,所以也準備寫個博客專門總結pycaffe的常見層參數設置,(LZ這個蠢啊,之前居然手寫prototxt,一把辛酸淚,太傻了/(ㄒoㄒ)/~~)
之前已經寫過用Anaconda直接安裝caffe,這樣安裝caffe不香嘛,爲啥非得源碼再來安裝一次呢?
1.項目裏後端是用的tensorflow的接口,前端是要用caffe的接口,caffe的有些參數設置還是源碼查詢比較方便
2.有一些層是比較特殊的,這種定製化的層可能需要使用c寫完之後,再進行源碼編譯
不過源碼編譯還是有很多坑的,且聽LZ一一道來:
首先下載源碼,https://github.com/weiliu89/caffe
按照tutorial安裝依賴項:http://caffe.berkeleyvision.org/installation.html
LZ的小小筆記本是Ubuntu16.04
- 所以需要先安裝對應的依賴庫
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev
- 然後LZ使用的是CMake編譯的,It requires CMake version >= 2.8.7. The basic steps are as follows:
mkdir build
cd build
cmake ..
make all
make install
make runtest
按照教程,好像簡簡單單,10分鐘就能搞定,但是事實卻不是如此。
- 當然你得設置下CUDA
# ---[ Options
caffe_option(CPU_ONLY "Build Caffe without CUDA support" OFF) # TODO: rename to USE_CUDA
caffe_option(USE_CUDNN "Build Caffe with cuDNN library support" ON IF NOT CPU_ONLY)
caffe_option(USE_NCCL "Build Caffe with NCCL library support" OFF)
caffe_option(BUILD_SHARED_LIBS "Build shared libraries" ON)
caffe_option(BUILD_python "Build Python wrapper" ON)
set(python_version "2" CACHE STRING "Specify which Python version to use")
caffe_option(BUILD_matlab "Build Matlab wrapper" OFF IF UNIX OR APPLE)
caffe_option(BUILD_docs "Build documentation" ON IF UNIX OR APPLE)
caffe_option(BUILD_python_layer "Build the Caffe Python layer" ON)
caffe_option(USE_OPENCV "Build with OpenCV support" ON)
caffe_option(USE_LEVELDB "Build with levelDB" ON)
caffe_option(USE_LMDB "Build with lmdb" ON)
caffe_option(ALLOW_LMDB_NOLOCK "Allow MDB_NOLOCK when reading LMDB files (only if necessary)" OFF)
caffe_option(USE_OPENMP "Link with OpenMP (when your BLAS wants OpenMP and you get linker errors)" OFF)
- 首先正常操作:
cmake ..
注意前方高能(ERROR來襲)
- 首先第一個坑就到來了,LZ之前爲了編譯tensorflow源碼,已經源碼安裝過protobuf了,也是用了-std=c++11這個標準
所以在cmake報了一些類似如下的錯誤
error: #error This file requires compiler and library support for the ISO C++ 2011 standard.
This support is currently experimental, and must be enabled with the -std=c++11 or
-std=gnu++11 compiler options
error: 'nullptr' was not declared in this scope 這種一長串
所以第一步要添加-std=c++11, cmakel
makefile得這麼改,不過makefile中LZ沒有嘗試,如果嘗試過的小夥伴歡迎指導
CXXFLAGS += -pthread -fPIC $(COMMON_FLAGS) $(WARNINGS) -std=c++11
NVCCFLAGS += -D_FORCE_INLINES -ccbin=$(CXX) -Xcompiler -fPIC $(COMMON_FLAGS) -std=c++11
LINKFLAGS += -pthread -fPIC $(COMMON_FLAGS) $(WARNINGS) -std=c++11
- 第二個可能遇到的錯誤:
nvcc fatal : Unsupported gpu architecture 'compute_20'
這個是CUDA版本決定的,LZ的版本是10.1, 這個文件是在makefile.config裏面的,就順帶說一下
# CUDA architecture setting: going with all of them.
# For CUDA < 6.0, comment the *_50 through *_61 lines for compatibility.
# For CUDA < 8.0, comment the *_60 and *_61 lines for compatibility.
# For CUDA >= 9.0, comment the *_20 and *_21 lines for compatibility.
CUDA_ARCH := -gencode arch=compute_20,code=sm_20 \
-gencode arch=compute_20,code=sm_21 \
-gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=sm_50 \
-gencode arch=compute_52,code=sm_52 \
-gencode arch=compute_60,code=sm_60 \
-gencode arch=compute_61,code=sm_61 \
-gencode arch=compute_61,code=compute_61
//註釋掉這兩句:
-gencode arch=compute_20,code=sm_20 \
-gencode arch=compute_20,code=sm_21 \
- 第三個可能遇到的錯誤:
fatal error: hdf5.h: No such file or directory compilation terminated.
用locate定位你的hdf5.h的位置,在makefile中添加對應的路徑
# Whatever else you find you need goes here.
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/local/include /usr/include/hdf5/serial/
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/hdf5/serial
修改library
LIBRARIES += glog gflags protobuf boost_system boost_filesystem m hdf5_serial_hl hdf5_serial
- 第四個可能遇到的錯誤:
這個問題就是OpenCV 4版本接口改變導致的,這個改的就有點多了,需要把caffe源碼涉及到這個 CV_LOAD_IMAGE_COLOR都換掉。
../caffe/src/caffe/layers/window_data_layer.cpp:293:42: error: ‘CV_LOAD_IMAGE_COLOR’ was not declared in this scope
cv_img = cv::imread(image.first, CV_LOAD_IMAGE_COLOR);
src/caffe/layers/window_data_layer.cpp
image_database_cache_[window[WindowDataLayer<Dtype>::IMAGE_INDEX]];
cv_img = DecodeDatumToCVMat(image_cached.second, true);
} else {
//cv_img = cv::imread(image.first, CV_LOAD_IMAGE_COLOR);
cv_img = cv::imread(image.first, cv::IMREAD_COLOR);
if (!cv_img.data) {
LOG(ERROR) << "Could not open or find file " << image.first;
return;
src/caffe/test/test_io.cpp
bool ReadImageToDatumReference(const string& filename, const int label,
const int height, const int width, const bool is_color, Datum* datum) {
cv::Mat cv_img;
//int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
//CV_LOAD_IMAGE_GRAYSCALE);
int cv_read_flag = (is_color ? cv::IMREAD_COLOR :
cv::IMREAD_GRAYSCALE);
cv::Mat cv_img_origin = cv::imread(filename, cv_read_flag);
if (!cv_img_origin.data) {
src/caffe/util/io.cpp
void WriteProtoToBinaryFile(const Message& proto, const char* filename) {
cv::Mat ReadImageToCVMat(const string& filename,
const int height, const int width, const bool is_color) {
cv::Mat cv_img;
// int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
// CV_LOAD_IMAGE_GRAYSCALE);
int cv_read_flag = (is_color ? cv::IMREAD_COLOR :
cv::IMREAD_GRAYSCALE);
cv::Mat cv_img_origin = cv::imread(filename, cv_read_flag);
if (!cv_img_origin.data) {
LOG(ERROR) << "Could not open or find file " << filename;
cv::Mat DecodeDatumToCVMat(const Datum& datum, bool is_color) {
CHECK(datum.encoded()) << "Datum not encoded";
const string& data = datum.data();
std::vector<char> vec_data(data.c_str(), data.c_str() + data.size());
// int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
// CV_LOAD_IMAGE_GRAYSCALE);
int cv_read_flag = (is_color ? cv::IMREAD_COLOR :
cv::IMREAD_GRAYSCALE);
cv_img = cv::imdecode(vec_data, cv_read_flag);
if (!cv_img.data) {
LOG(ERROR) << "Could not decode datum ";
- 第五個可能遇到的錯誤:
Anaconda的三方庫和本地庫衝突了,那就把Anaconda的環境變量先註釋掉,編譯好了再放出來就好了
最後放張編譯成功的圖。。。
自己踩坑千千萬,跳出一坑,又進了一坑!
據說OpenCV4.1版本之前存在安全隱患問題,所以現在LZ的公司都換成OpenCV4.2版本了。。。
參考地址:
1.https://blog.csdn.net/m_buddy/article/details/88085425
2.https://blog.csdn.net/qq_18649781/article/details/89047437
3.https://github.com/BVLC/caffe/issues/6680
4.https://github.com/BVLC/caffe/pull/6625/files/7f503bd9a19758a173064e299ab9d4cac65ed60f
PS:
LZ已經在自己家隔離20多天了,到工作的地方還得隔離14天,大門不出二門不賣,真希望能夠肆無忌憚的在一個陽關明媚的午後壓馬路O(∩_∩)O~
現在是關鍵時刻,還不能放鬆,越到緊要關頭,越要能忍住!