# Ubuntu 建立 ncnn 模型環境 ### 先取得需轉換好的模型權重從 pth 到 onnx https://docs.microsoft.com/zh-cn/windows/ai/windows-ml/tutorials/pytorch-convert-model ```python= # Export the model # torch_out = torch.onnx._export(model, # model being run # x.to(device), # model input (or a tuple for multiple # f='Magface.onnx', # export_params=True, # verbose=True, # opset_version=11) onnx_model = load_model("Magface.onnx") trans_model = float16_converter.convert_float_to_float16(onnx_model, keep_io_types=True) save_model(trans_model, "Magface_fp16.onnx") ``` ### 建立 ncnn 編譯環境: 1. 先下載環境建置文件 https://github.com/BoshiLee/dockerfiles/tree/main/ncnn_python_ubuntu 2. 完成 TODO 事項 ### 簡化 onnx 模型: 簡化非必要的 onnx 模型參數,也可以讓後續轉換更順利 * 參考Git 安裝過程 https://github.com/daquexian/onnx-simplifier 安裝好後可下: ```bash= onnxsim onnx_models/v5s-p6_wider_face.onnx onnx_models/v5s-p6_wider_face_sim.onnx ``` ### 將 onnx 編譯成 ncnn ```bash= cd tools/onnx ./onnx example.onnx example.parm example.bin ``` 或者使用模型轉換網站: [省去编译转换工具的时间开箱即用,一键转换](https://www.convertmodel.com/#input=onnx&output=onnx) ### 導入模型 1. 建立CMake 專案: ``` cmake_minimum_required(VERSION 2.8) project(yolo_ncnn) # ncnn set(ncnn_install_dir "/home/app/ncnn/build/install") set(ncnn_DIR "${ncnn_install_dir}/lib/cmake/ncnn") find_package(ncnn REQUIRED) # open cv find_package( OpenCV REQUIRED ) add_executable(yolo_ncnn main.cpp) if(ncnn_FOUND) message(STATUS "ncnn library: ${ncnn_INSTALL_PATH}") message(STATUS " version: ${ncnn_VERSION}") message(STATUS " libraries: ${ncnn_LIBS}") message(STATUS " include path: ${ncnn_INCLUDE_DIRS}") target_link_libraries(yolo_ncnn ncnn) endif() if(OpenCV_FOUND) message(STATUS "OpenCV library: ${OpenCV_INSTALL_PATH}") message(STATUS " version: ${OpenCV_VERSION}") message(STATUS " libraries: ${OpenCV_LIBS}") message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") include_directories( ${OpenCV_INCLUDE_DIRS} ) target_link_libraries(yolo_ncnn ${OpenCV_LIBS} ) endif() ``` 2. 建立載入模型範例程式 ```C++ // // Created by boshi on 2022/6/6. // #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include "headers/net.h" int main() { cv::Mat img = cv::imread("face.jpg", cv::IMREAD_GRAYSCALE); int w = img.cols; int h = img.rows; // subtract 128, norm to -1 ~ 1 ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 60, 60); float mean[1] = { 128.f }; float norm[1] = { 1/128.f }; in.substract_mean_normalize(mean, norm); ncnn::Net net; net.load_param("models/model.param"); net.load_model("models/model.bin"); ncnn::Extractor ex = net.create_extractor(); ex.set_light_mode(true); ex.set_num_threads(4); // 這裡要修改成模型輸入的名稱,請找 model.param 的 input layer 是什麼名稱 ex.input("images", in); ncnn::Mat feat; ex.extract("output", feat); printf("x = %d\n", feat); return 0; } ``` [參考專案 Git](https://github.com/BoshiLee/yolov5s_ncnn_test) ### 編譯專案 ```bash= cmake . make ``` ### 執行專案 ```bash= ./yolo_ncnn ```