MobileNet-SSD利用caffe-int8-convert-tools工具量化经验(二)

MobileNet-SSD利用caffe-int8-convert-tools工具量化经验(二)

从NCNN框架的param和bin文件中提取权重参数

参考:ncnn:提取所有层特征值
在ncnn-master/src/net.cpp结尾添加函数:

int Extractor::extract_all_blobs()
{
    for (int blob_index = 0; blob_index < (int)d->blob_mats.size(); blob_index++)
    {
      Mat outMat;
      extract(blob_index, outMat);

      // write to file
      char path[256];
      char id[8];

      strcpy(path, "../../weights/");
      sprintf(id, "%d", blob_index);
      strcat(path, id);
      strcat(path, ".txt");

      FILE *fp = fopen(path, "w+");
      if(!fp)
        fprintf(stderr, "error open file\n");

      // header
      fprintf(fp, d->net->blobs()[blob_index].name.c_str());
      fprintf(fp, "\n");

      for (int idx = 0; idx < outMat.w * outMat.h * outMat.c; idx++)
        fprintf(fp, "%f\n", outMat[idx]);
      fclose(fp);
    }

    return 0;
}

将权重参数写到与ncnn-master同目录下的weights文件夹中。
另外写一个提取参数的测试cpp文件:

#include "../src/net.h"
#include "../src/net.cpp"
#include "../src/layer.h"
#include "../src/layer/convolution.h"

#include <stdarg.h>
#include <stdint.h>
#include <string.h>

#if defined(USE_NCNN_SIMPLEOCV)
#include "simpleocv.h"
#else
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#endif
#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);
        return -1;
    }

    const char* imagepath = argv[1];

//使用opencv以灰度图读取图片
    cv::Mat m = cv::imread(imagepath, 1);
    if (m.empty())
    {
        fprintf(stderr, "cv::imread %s failed\n", imagepath);
        return -1;
    }

//定义模型的网络
    ncnn::Net mobilenet;

    mobilenet.opt.use_vulkan_compute = true;

//加载模型
    mobilenet.load_param("../../caffe-int8-convert-tools/test/bin_param/MobileNetSSD-int8.param");
    mobilenet.load_model("../../caffe-int8-convert-tools/test/bin_param/MobileNetSSD-int8.bin");

    /*ncnn::Convolution* conv1 = (ncnn::Convolution*)mobilenet.extract_layer(1);//(旧版本的函数)
    ncnn::Mat conv1_weight; 
    conv1_weight = conv1->weight_data;
    int i;
    char path[256];
    strcpy(path, "conv1.txt");
    FILE *fp = fopen(path, "w+");
      if(!fp)
        fprintf(stderr, "error open file\n");

    for(i=0;i<500;i++)
    {
	fprintf(fp, conv1_weight.data[i]);
    }*/
    
//新版本函数(bug)
    /*ncnn::Layer layers = mobilenet.layers;
    const int layer_count = layers.size();
    for (int i=0; i<layer_count; i++)
    {
        // find convoultion layer
        if (layers[i]->type != "Convolution")
            continue;
        ncnn::Convolution* conv = (ncnn::Convolution*)layers[i];
 	ncnn::Mat conv_weight; 
        conv_weight = conv->weight_data;

	// write to file
      	char path[256];
      	char name[16];

      	strcpy(path, "../../weights/");
      	sprintf(name, "%s", conv->name.c_str());
      	strcat(path, name);
      	strcat(path, ".txt");
	
      	FILE *fp = fopen(path, "w+");
      	if(!fp)
        	fprintf(stderr, "error open file\n");

      	for (int idx = 0; idx < 500; idx++)
        	fprintf(fp, "%f\n", conv_weight.data[idx]);
      	fclose(fp);
    }*/
    

    const int target_size = 300;

//获取图片的宽和高
    int img_w = m.cols;
    int img_h = m.rows;

//将opencv的图片转为ncnn格式的图片,并将图片缩放到300×300之间
    ncnn::Mat in = ncnn::Mat::from_pixels_resize(m.data, ncnn::Mat::PIXEL_BGR, m.cols, m.rows, target_size, target_size);
//对图片进行归一化,将像素归一化到-1~1之间
    const float mean_vals[3] = {127.5f, 127.5f, 127.5f};
    const float norm_vals[3] = {1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5};
    in.substract_mean_normalize(mean_vals, norm_vals);

    ncnn::Extractor ex = mobilenet.create_extractor();
//将图片放入网络中,进行前向推理
    ex.input("data", in);

    ex.extract_all_blobs();

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值