目前使用騰訊所改寫的MTCNN detector做人臉偵測,其框架使用的是NCNN,但現階段我們是使用tensorflow or caffe 框架來訓練model,所以勢必要使用轉換程式將tensorflow or caffe轉為NCNN格式讓MTCNN detector使用,目前我們的環境如下圖所示,使用tensorflow 框架來訓練model,但必須先轉換為caffe 框架再轉為NCNN框架,為何要這麼麻煩呢?原因是tensorflow是現階段做深度學習最熱門的工具,但騰訊目前並無支援tensorflow直接轉NCNN(據說前陣子官方有提供,但bug太多,所以就停止支援,但未來若再提供,一定會更方便),所以一定要先有中繼轉換再轉為NCNN,本篇就是教學如何建立出轉檔程式,並且成功生出NCNN格式的model。
觀念建立:
使用caffe轉ncnn的格式,有個很重要的工具,就是Protocol Buffers ,Protocol Buffers又簡稱為Protobuf、PB。是Google推出的一種數據交換格式。注意,這還是二進制的交換數據。Protobuf有自己的編譯器,在Linux中叫做protoc,可以解釋.proto文件並且聲稱對應語言的源文件。目前Google提供了三種語言:Java, C++, Python。後面我們就以C++來說明,其他語言類似。
總結一下:我們所說的Protobuf,其實可以說是包含以下幾部分:
1. 一種數據交換格式,可以將C++ 中定義的存儲類的內容與二進制序列串相互轉換,主要用於數據傳輸或保存
2. 定義了一種源文件,擴展名為.proto,使用這種源文件,可以定義存儲類的內容
3. Google提供了一個編譯器protoc,可以編譯.proto編譯成.cc文件,使之成為一個可以在C++工程中直接使用的類。
所以我們使用現成的*.proro檔生成生成C++類,根據caffe.proto的描述,生成caffe.pb.cc and caffe.pb.h 給caffe2ncnn的轉檔程式使用。以上參考出處: https://segmentfault.com/a/1190000010098194
實作步驟:
1. 下載proto buffer的開源碼,在此使用3.6.1版本, https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1
a.在ubuntu環境下,安裝基本套件工具
$ sudo apt-get install autoconf automake libtool curl make g++ unzip
b. 建立和安裝C++ Protocol Buffer tuntime 和 Protocol Buffer compiler (protoc)
$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig # refresh shared library cache.
c. 檢查Compiling dependent packages相關路徑
$ pkg-config --cflags --libs protobuf
-prhtrad -I/usr/local/include -L/usr/local/lib -lprotobuf -pthread
d. 檢查src/ 資料夾下生成protoc的執行檔。
以上安裝步驟,參考: https://github.com/protocolbuffers/protobuf/blob/master/src/README.md
2. 編譯出caffe2ncnn的轉檔程式
a. deepinsight detector的開源碼下載,https://github.com/deepinsight/mtcnn-ncnn
$ git clone https://github.com/deepinsight/mtcnn-ncnn
b. 編譯caffe.pb.cc and caffe.pb.h
b.1 至mtcnn-ncnn\tools下取出caffe.proto複製到proto buffer的src\使用。
b.2 使用proroc編譯
$ sudo ./protoc caffe.proto --cpp_out=OUT_DIR
#OUT_DIR是你指定的產出caffe.pb.cc and caffe.pb.h的路徑.
c. 編譯caffe2ncnn,其makefile如下示範
EXE_FILE = caffe2ncnn.out CC = g++ -std=c++11 INC = -I/share/caffe2ncnn_tool/caffe2ncnn LIB_INC = -L/usr/local/lib LIB = -protobuf -lprotoc -lpthread SRC = caffe2ncnn_mtcnn.cpp caffe.pb.cc ALL:$(SRC) #(CC) $(INC) $(SRC) $(LIB_INC) $(LIB) -o $(EXE_FILE) clean: rm *.o |
3. 轉檔出ncnn格式的model
caffe2ncnn_mtcnn src.prototxt src.caffemodel target.param target.bin 65536
其*.param及*.bin即是使用ncnn框架的model。