Tengine是一個優秀的輕量級端側/嵌入式環境深度神經網絡推理引擎。兼容多種操做系統和深度學習算法,以AI推理框架爲基礎的AIoT開發套件。本文檔將分別在x86 Linux和Arm64 Linux平臺,以分類模型(TensorFlow MobileNetv1模型)爲例,帶你快速上手Tengine。java
Linux x86 平臺編譯
下載代碼
$ git clone https://github.com/OAID/tengine/
安裝所需工具和依賴庫
在開始編譯Tengine以前,你須要確認你已經安裝了cmake,g++,若是沒有,你能夠經過以下指令安裝:linux
$ sudo apt install cmake g++
進入tengine目錄,執行編譯腳本
$ cd /path/to/Tengine $ mkdir build $ cd build $ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/x86.gcc.toolchain.cmake .. $ make -j4 && make install
編譯完成後,在build目錄下若是有libtengine.so文件,說明編譯成功。ios
qtang@tengine-train:~/github/Tengine/build$ ls benchmark CMakeCache.txt CMakeFiles cmake_install.cmake examples libtengine.so Makefile tests
arm64 Linux 平臺編譯
arm64 Linux編譯方式與x86平臺相似c++
下載代碼
$ git clone https://github.com/OAID/tengine/
安裝所需工具
$ sudo apt install cmake g++
進入tengine目錄,執行編譯腳本
$ cd /path/to/Tengine $ mkdir build $ cd build $ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm64.native.gcc.toolchain.cmake .. $ make -j4 && make install
編譯完成後,在build目錄下若是有libtengine.so文件,說明編譯成功。git
轉換模型
二進制工具
- 咱們提供模型轉換工具convert_model_to_tm,方便您將Tensorflow/Caffe/MxNet/ONNX等框架模型轉換成Tengine模型格式tmfile:
convert_model_to_tmgithub
- 若採用源碼編譯,編譯完成後該工具的存放路徑在
$ tree install/ install/ ├── benchmark │ ├── bench_mobilenet │ └── bench_sqz ├── convert_tools │ └── convert_model_to_tm (here!)
模型倉庫
咱們提供了常見開源模型的tmfile文件,您能夠在這裏找到他們:算法
Tengine Model zoo(Password : hhgc)api
模式轉換demo
使用convert_model_to_tm將mobilenet.pb模型轉換成Tengine模型很是簡單,執行如下命令:網絡
$ ./convert_model_to_tm -f tensorflow -m ./mobilenet.pb -o ./mobilenet_tf.tmfile
其中:框架
$ ./install/convert_tools/convert_model_to_tm -h [Usage]: ./install/convert_tools/convert_model_to_tm [-h] [-f file_format] [-p proto_file] [-m model_file] [-o output_tmfile] -f:模型框架類型[caffe、caffe_single、onnx、mxnet、tensorflow、darknet、tflite],當輸入只有一個模型文件時,不須要指定「-p」選項,只指定「-m」選項便可。這裏咱們使用的是tensorflow mobilenet模型,所以設置該參數爲tensorflow -m:源模型路徑 -o:轉換後Tengine模型路徑 // 轉換Caffe Model $ ./install/tool/convert_model_to_tm -f caffe -p models/sqz.prototxt -m models/squeezenet_v1.1.caffemodel -o models/squeezenet.tmfile // 轉換TensorFlow Model $ ./install/tool/convert_model_to_tm -f tensorflow -m models/squeezenet.pb -o models/squeezenet_tf.tmfile
須要注意的是,convert_model_to_tm只能在Linux x86平臺上編譯或運行,同時編譯的時候依賴protobuf第三庫(>= 3.0),須要提早安裝
$ sudo apt-get install libprotobuf-dev protobuf-compiler
當拿到Tengine模型文件如Mobilenet.tmfile以後,就能夠用Tengine在各類平臺上愉快的進行應用開發了。
經常使用API介紹
Tengine核心API以下:
- init_tengine
初始化Tengine,該函數在程序中只要調用一次便可。
- create_graph
建立Tengine計算圖。
- prerun_graph
預運行,準備計算圖推理所需資源。
- run_graph
啓動Tengine計算圖推理。
- postrun_graph
中止運行graph,並釋放graph佔據的資源。
- destroy_graph
銷燬graph。
postrun_graph和destroy_graph在執行完模型推理後調用,通常是連續調用。
使用Tengine C API開發mobilenet圖片分類代碼
Tengine提供了C、C++、Python API供用戶使用,這裏咱們使用Tengine C++ API展現如何運行MobileNetv1網絡模型實現圖片分類功能,讓你快速上手Tengine C++ API。代碼中咱們將使用詳細的代碼註釋,方便你熟悉Tengine核心API的功能,更快地開發出本身的代碼。這裏,咱們使用行業內無人不識,無人不曉的tiger cat圖片做爲測試圖片。
測試代碼
完整的測試代碼以下:
#include <unistd.h> #include <iostream> #include <functional> #include <algorithm> #include <fstream> #include <iomanip> #include "tengine_operations.h" #include "tengine_c_api.h" #include "tengine_cpp_api.h" #include "common_util.hpp" const char* model_file = "./models/mobilenet.tmfile"; const char* image_file = "./tests/images/cat.jpg"; const char* label_file = "./models/synset_words.txt"; const float channel_mean[3] = {104.007, 116.669, 122.679}; using namespace TEngine; int repeat_count = 100; void LoadLabelFile(std::vector<std::string>& result, const char* fname) { std::ifstream labels(fname); std::string line; if(labels.is_open()) { while(std::getline(labels, line)) result.push_back(line); } } void PrintTopLabels(const char* label_file, float* data) { // load labels std::vector<std::string> labels; LoadLabelFile(labels, label_file); float* end = data + 1000; std::vector<float> result(data, end); std::vector<int> top_N = Argmax(result, 5); for(unsigned int i = 0; i < top_N.size(); i++) { int idx = top_N[i]; if(labels.size()) std::cout << std::fixed << std::setprecision(4) << result[idx] << " - \"" << labels[idx] << "\"\n"; else std::cout << std::fixed << std::setprecision(4) << result[idx] << " - " << idx << "\n"; } } void get_input_data(const char* image_file, float* input_data, int img_h, int img_w, const float* mean, float scale) { image img = imread(image_file); image resImg = resize_image(img, img_w, img_h); resImg = rgb2bgr_premute(resImg); float* img_data = ( float* )resImg.data; int hw = img_h * img_w; for(int c = 0; c < 3; c++) for(int h = 0; h < img_h; h++) for(int w = 0; w < img_w; w++) { input_data[c * hw + h * img_w + w] = (*img_data - mean[c]) * scale; img_data++; } } int main(int argc, char* argv[]) { std::string device = ""; std::string file_path = ""; char* cpu_list_str = nullptr; int res; while((res = getopt(argc, argv, "p:d:f:r:")) != -1) { switch(res) { case 'p': cpu_list_str = optarg; break; case 'd': device = optarg; break; case 'f': file_path = optarg; break; case 'r': repeat_count = strtoul(optarg, NULL, 10); break; default: break; } } int img_h = 224; int img_w = 224; tengine::Net mobilenet; tengine::Tensor input_tensor; tengine::Tensor output_tensor; /* load model */ mobilenet.load_model(NULL, "tengine", model_file); /* prepare input data */ input_tensor.create(img_w, img_h, 3); get_input_data(image_file, (float* )input_tensor.data, img_h, img_w, channel_mean, 0.017); mobilenet.input_tensor("data", input_tensor); /* forward */ mobilenet.run(); /* get result */ mobilenet.extract_tensor("fc7", output_tensor); /* after process */ PrintTopLabels(label_file, (float*)output_tensor.data); std::cout << "--------------------------------------\n"; std::cout << "ALL TEST DONE\n"; return 0; }
編譯
build.sh編譯腳本默認配置已實現自動編譯examples中的demo程序,以x86平臺爲例,demo存放在./build-linux-x86/install/examples/目錄下。
./build-linux-x86/install/ ├── benchmark │ ├── bench_mobilenet │ └── bench_sqz ├── examples │ ├── classification │ ├── mobilenet_ssd │ └── synset_words.txt
運行結果
將測試圖片和分類標籤文件放在指定目錄下,運行便可:
export LD_LIBRARY_PATH=./build-linux-x86/install/lib cd ./build-linux-x86/install/examples/ $ ./classification -m /path/to/mobilenet.tmfile -l /path/to/labels.txt -i /path/to/img.jpg -g 224,224 -s 0.017 -w 104.007,116.669,122.679 -------------------------------------- 0.3465 - "tiger cat" 0.1609 - "tabby" 0.1564 - "weasel" 0.0844 - "Egyptian cat" 0.0258 - "bucket" -------------------------------------- ALL TEST DONE
能夠看出,咱們已經成功的分類出測試圖片是虎貓了。 到這裏最基本的上手指北已經完成,剩下的小夥伴們能夠自行探索,咱們也會不按期更新各類教程範例給你們~
...\(^0^)/...233
更多資訊歡迎關注公衆號Tengine開發者社區,拜了個拜