NCNN在设备端精度问题

wangchunlin 2022-8-11 97 8/11

用pytorch、darknet、dnn等实现的推理在转换为ncnn模型后,以官方给的示例代码为模板,推理出来的精度可能和原来差距较大,有如下可能原因:

BGR和RGB的问题

其实就是训练时,通道顺序和推理时不一致,如下转换:

// construct RGB blob from rgb image
ncnn::Mat in_rgb = ncnn::Mat::from_pixels(rgb_data, ncnn::Mat::PIXEL_RGB, w, h);

// construct BGR blob from bgr image
ncnn::Mat in_bgr = ncnn::Mat::from_pixels(bgr_data, ncnn::Mat::PIXEL_BGR, w, h);

// construct BGR blob from rgb image
ncnn::Mat in_bgr = ncnn::Mat::from_pixels(rgb_data, ncnn::Mat::PIXEL_RGB2BGR, w, h);

// construct RGB blob from bgr image
ncnn::Mat in_rgb = ncnn::Mat::from_pixels(bgr_data, ncnn::Mat::PIXEL_BGR2RGB, w, h);

或者用其他写法:

// 或者采用cvtcolor的写法,具体谁快没有测试。
// 或者在ncnn::Mat中使用2RGB的写法
// cv::Mat in = bgr.clone();
/*
std::vector<cv::Mat> chs;
split(in, chs);
std::swap(chs[0], chs[2]);
merge(chs, in);
*/
// cv::cvtColor(bgr, in, cv::COLOR_BGR2RGB); 

预处理部分

保证这一部分的值和模型是匹配的,每个模型都不一样,yolov3的在darknet转ncnn时,工具会输出提示:

const float mean_vals[3] = { 103.94f, 116.78f, 123.68f };
const float norm_vals[3] = { 0.017f, 0.017f, 0.017f };
in.substract_mean_normalize(mean_vals, norm_vals);

每个图像新建一个Extractor

原因是extractor是有状态对象,其中应该存在大量的中间全局量,不同输入图片可能得到相同值

使用正确的输入输出接口名称

每种算法默认的输入输出接口名称不尽相同,yolov3在param中可以看:

NCNN在设备端精度问题
NCNN在设备端精度问题
ex.input("data", in_reRB);

ncnn::Mat out;
ex.extract("output", out);

其他原因

其他原因,我暂时没有遇到过,记录一下

ncnn关于精度问题的FAQ

- THE END -

wangchunlin

8月11日11:53

最后修改:2022年8月11日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论