1 使用 caffe-int-convert-tools 量化
-
下载
git clone https://github.com/BUG1989/caffe-int8-convert-tools.git # wget https://github.com/BUG1989/caffe-int8-convert-tools/archive/master.zip -
准备文件
test/ ├── images │ ├── 001.jpeg │ ├── 002.jpeg │ └── 003.jpeg └── models ├── ResNet_50_train.prototxt └── ResNet_50.caffemodel -
执行
python caffe-int8-convert-tools/caffe-int8-convert-tool-dev-weight.py \ --proto=model_resnet/ResNet_50_train.prototxt \ --model=model_resnet/ResNet_50.caffemodel \ --mean 127.5 127.5 127.5 \ --norm=0.00777 \ --images=caffe-int8-convert-tools/test/images/ \ --output=caffe-int8-convert-tools/test/ResNet_50.table \ --gpu=1其中,output 参数是生成的
.table文件。 -
执行遇到问题1
执行 np.set_printoptions(threshold=np.nan) 报错解决:将其改为
np.set_printoptions(threshold=np.inf),是版本问题。 -
执行遇到问题2
TypeError: _open() got an unexpected keyword argument 'as_grey'解决:浏览错误信息,找到包含
as_grey字符的文件,打开该文件,修改as_grey为as_gray即可,是版本问题。
如果上面步骤执行完会在指定路径产生 .table 文件。
2 转换为 ncnn 模型
-
下载
git clone https://github.com/Tencent/ncnn.git # wget https://github.com/Tencent/ncnn/archive/master.zip -
编译
cd ncnn mkdir build && cd build cmake .. make -j8 make install编译完成后,会在
./ncnn/build/tools目录下生成caffe/caffe2ncnn和ncnn2mem可执行程序。caffe2ncnn 是将 caffe 模型转换为 ncnn 模型;
ncnn2mem 可以对 ncnn 模型加密(本文省略); -
caffe 转换为 ncnn
./ncnn/build/tools/caffe/caffe2ncnn \ model_resnet/ResNet_50_train.prototxt \ model_resnet/ResNet_50.caffemodel \ caffe-int8-convert-tools/test/ResNet_50-int8.param \ caffe-int8-convert-tools/test/ResNet_50-int8.bin \ 256 \ caffe-int8-convert-tools/test/ResNet_50.table会生成
ResNet_50-int8.param和ResNet_50-int8.bin。 -
调用 ncnn 模型
内容参考 ncnn 源码:
./ncnn/examples/squeezenet.cpp。需要的头文件和库文件在./ncnn/build/install中,编译时需要添加。CMakeLists.txt:#SET(CMAKE_CXX_FLAGS "-std=c++11 -O3") cmake_minimum_required(VERSION 2.8) project(use_model) set(CMAKE_BUILD_TYPE Release) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # OpenMP FIND_PACKAGE( OpenMP REQUIRED) if(OPENMP_FOUND) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() # OpenCV find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) # Boost add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY) find_package(Boost REQUIRED COMPONENTS filesystem system) include_directories(${Boost_INCLUDE_DIRS}) # Ncnn set(Ncnn_INCLUDE_DIR /home/tamray/trcaffe/ncnn/build/install/include) set(Ncnn_LIBRARY_DIR /home/tamray/trcaffe/ncnn/build/install/lib) include_directories(${Ncnn_INCLUDE_DIR}) LINK_DIRECTORIES(${Ncnn_LIBRARY_DIR}) add_executable(app main.cpp) target_link_libraries(app ${OpenCV_LIBS} ${Boost_LIBS} libncnn.a )main.cpp#include <ncnn/net.h> #include <algorithm> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <stdio.h> #include <vector> static int detect_squeezenet(const cv::Mat& bgr, std::vector<float>& cls_scores) { ncnn::Net squeezenet; squeezenet.opt.use_vulkan_compute = true; // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models squeezenet.load_param("squeezenet_v1.1.param"); squeezenet.load_model("squeezenet_v1.1.bin"); ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR, bgr.cols, bgr.rows, 227, 227); const float mean_vals[3] = {104.f, 117.f, 123.f}; in.substract_mean_normalize(mean_vals, 0); ncnn::Extractor ex = squeezenet.create_extractor(); ex.input("data", in); ncnn::Mat out; ex.extract("prob", out); cls_scores.resize(out.w); for (int j = 0; j < out.w; j++) { cls_scores[j] = out[j]; } return 0; } static int print_topk(const std::vector<float>& cls_scores, int topk) { // partial sort topk with index int size = cls_scores.size(); std::vector<std::pair<float, int> > vec; vec.resize(size); for (int i = 0; i < size; i++) { vec[i] = std::make_pair(cls_scores[i], i); } std::partial_sort(vec.begin(), vec.begin() + topk, vec.end(), std::greater<std::pair<float, int> >()); // print topk and score for (int i = 0; i < topk; i++) { float score = vec[i].first; int index = vec[i].second; fprintf(stderr, "%d = %f\n", index, score); } return 0; } int main(int argc, char** argv) { if (argc != 2) { fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]); return -1; } const char* imagepath = argv[1]; cv::Mat m = cv::imread(imagepath, 1); if (m.empty()) { fprintf(stderr, "cv::imread %s failed\n", imagepath); return -1; } std::vector<float> cls_scores; detect_squeezenet(m, cls_scores); print_topk(cls_scores, 3); return 0; }

226

被折叠的 条评论
为什么被折叠?



