前幾天看到鵝廠放出了NCNN源碼,去GITHUB上搞下來(lái),一堆CMAKE的腳本和幾段源碼,還有一個(gè)CAFFEMODEL和幾個(gè)不知名文件。README里是一堆吹牛逼的廢話,對(duì)編譯src、tools和example完全沒有指導(dǎo)意義??磥?lái)要自己摸索了。
其實(shí)編譯src里的東西不難,這里就寫一下在Linux系統(tǒng)下的源碼編譯過程和Android Demo跑通過程。(Windows用戶可以開啟Linux子系統(tǒng)然后一塊編譯,其實(shí)我就是受人鄙視的Windows用戶。??)
需要編譯的目標(biāo)有4個(gè)(括號(hào)內(nèi)為所需工具):
1. src源碼(cmake make gcc g++)
2. Android/iOS所需的鏈接庫(kù)(cmake make gcc g++ zip NDK)
3. example源碼(gradle/ant NDK Android-SDK)
4. tools源碼(protobuf ncnn)
如果沒有protobuf,那么需要先去github上把Protobuf的源碼給搞下來(lái),然后根據(jù)Protobuf安裝指南安裝這個(gè)工具。
安裝了protobuf以后上述工具基本上都已經(jīng)齊備。
編譯源碼SRC
進(jìn)入src目錄,創(chuàng)建build目錄,然后執(zhí)行cmake,具體執(zhí)行順序如下
mkdir build
cd build
cmake ..
make
sudo make install
在build目錄下就可以得到一個(gè)大小1.4M不到的libncnn.a靜態(tài)庫(kù)
此外,默認(rèn)的SRC編譯是不會(huì)把ncnn的完整屬性打入包內(nèi)的(少了一些方法),這時(shí)編譯tools中的轉(zhuǎn)換工具會(huì)出現(xiàn)錯(cuò)誤。如果需要編譯加入這些方法,在cmake中……不知道咋辦,在cmake之后build目錄中有platform.h文件,把其中
#define NCNN_STDIO 0
#define NCNN_STRING 0
#define NCNN_OPENCV 0
改為
#define NCNN_STDIO 1
#define NCNN_STRING 1
#define NCNN_OPENCV 1
即可
編譯Android鏈接庫(kù)
這部分比較簡(jiǎn)單,直接在ncnn的根目錄執(zhí)行
bash build.sh
和
bash package.sh
就行
在執(zhí)行完一堆編譯(編譯過程中如果沒有配置IOS專門的OC編譯器,IOS庫(kù)無(wú)法產(chǎn)出,不過沒關(guān)系,咱們說的是Android Demo跑通嘛。)后會(huì)得到:build-android-aarch64 build-android-armv7兩個(gè)文件夾
以及ncnn.framework.zip ncnn-android-lib.zip兩個(gè)壓縮包
我們只要把ncnn-android-lib.zip這個(gè)壓縮包搞出來(lái)就行了
編譯example源碼
Example里的squeezencnn是一個(gè)Ant工程,這里以WIndows編譯為例,Mac用戶雷同(Linux可以直接下載ant編譯工具,修改ant.properties然后編譯):
直接備份導(dǎo)入到Android Studio中,升級(jí)為Gradle工程(AS會(huì)自動(dòng)創(chuàng)建build.gradle等文件)
咱們采用原始方法加入NDK支持:
經(jīng)過一系列等待,會(huì)告訴你NDK錯(cuò)誤
在根目錄下創(chuàng)建
gradle.properties
內(nèi)容為
android.useDeprecatedNdk=true
修改根目錄中的build.gradle里gradle的版本到一個(gè)比較新的版本
修改app/build.gradle的內(nèi)容(AS會(huì)自動(dòng)調(diào)整目錄結(jié)構(gòu))
主要修改兩項(xiàng)內(nèi)容,增加兩項(xiàng)內(nèi)容:
修改
compileSdkVersion 9
為
compileSdkVersion 14或者更高
修改
buildToolsVersion XXX
為
buildToolsVersion '24.0.2'或更高
增加
sourceSets {
? ?main {
? ? ? jniLibs.srcDirs = ['libs']
? ?}
}
增加
dependencies {
? ?compile fileTree(dir: 'libs', include: ['*.so'])
}
然后進(jìn)入app/src/main/jni
修改
Android.mk中
NCNN_INSTALL_PATH到你編譯出的build-android-XXX目錄的install目錄下
修改Application.mk中
APP_ABI := all
APP_PLATFORM := android-14
然后在jni目錄下直接執(zhí)行
ndk-build
就會(huì)在上層目錄得到一個(gè)libs文件夾,里面包含了所有編譯輸出的so庫(kù)
我們把libs文件夾移動(dòng)到app的目錄下
然后直接gradle build install
跑起來(lái),應(yīng)該就沒問題了。
這是一個(gè)圖片分類的demo,啟動(dòng)后會(huì)發(fā)現(xiàn)無(wú)論什么圖片都不能識(shí)別分類(顯示一個(gè)神秘路徑)
反查app\src\main目錄下的asserts中放的squeezenet_v1.1.bin文件內(nèi)容是一個(gè)路徑,synset_words.txt也是所以我們要用原始example目錄下
squeezenet_v1.1.bin
和
squeezenet_v1.1.param
以及
synset_words.txt
替換同名文件。
再次運(yùn)行,就有結(jié)果了。。。雖然結(jié)果看起來(lái)不太理想,不過效果還不錯(cuò)。。。

編譯工具TOOLS
工具的編譯也非常簡(jiǎn)單,去tools目錄下直接創(chuàng)建build文件夾然后:
cd build
cmake ..
make
sudo make install
即可得到caffe2ncnn和ncnn2mem這兩個(gè)工具,
caffe2ncnn接受2個(gè)、4個(gè)或者5個(gè)參數(shù)
依次是:
caffe的模型prototxt文件
caffe的模型caffemodel文件
輸出的
ncnn模型bin文件名
ncnn模型的param文件名
以及量化深度
支持(0,256,65536)三種,默認(rèn)是0(完全)
結(jié)尾
從執(zhí)行的效果和代碼的快速瀏覽來(lái)看,NCNN的目標(biāo)在于輕量級(jí)的更注重CPU運(yùn)算優(yōu)化的方向(包括這兩天的更新都是在針對(duì)不同的硬件架構(gòu)進(jìn)行代碼優(yōu)化),和TensorFlow on Android還是有一些差別的。感覺這個(gè)項(xiàng)目要成熟起來(lái)還有很長(zhǎng)的路要走。
再增加一些其他平臺(tái)的模型轉(zhuǎn)換工具吧。
有空會(huì)寫代碼閱讀理解報(bào)告的。。。