resnet模型推理结果不准
以下是一个resnet18的二分类模型,输入3x224x224,经pytorch--onnx--ncnn转换 由onnx转ncnn后推理准确性只有70%,netron打开ncnn和onnx对比各结点也未发现异常
ncnn模型
7767517 58 66 Input input 0 1 input Convolution Conv_0 1 1 input 192 0=64 1=7 11=7 2=1 12=1 3=2 13=2 4=3 14=3 15=3 16=3 5=1 6=9408 ReLU Relu_1 1 1 192 125 Pooling MaxPool_2 1 1 125 126 0=0 1=3 11=3 2=2 12=2 3=1 13=1 14=1 15=1 5=1 Split splitncnn_0 1 2 126 126_splitncnn_0 126_splitncnn_1 Convolution Conv_3 1 1 126_splitncnn_1 195 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864 ReLU Relu_4 1 1 195 129 Convolution Conv_5 1 1 129 198 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864 BinaryOp Add_6 2 1 198 126_splitncnn_0 132 0=0 ReLU Relu_7 1 1 132 133 Split splitncnn_1 1 2 133 133_splitncnn_0 133_splitncnn_1 Convolution Conv_8 1 1 133_splitncnn_1 201 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864 ReLU Relu_9 1 1 201 136 Convolution Conv_10 1 1 136 204 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864 BinaryOp Add_11 2 1 204 133_splitncnn_0 139 0=0 ReLU Relu_12 1 1 139 140 Split splitncnn_2 1 2 140 140_splitncnn_0 140_splitncnn_1 Convolution Conv_13 1 1 140_splitncnn_1 207 0=128 1=1 11=1 2=1 12=1 3=2 13=2 4=0 14=0 15=0 16=0 5=1 6=8192 Convolution Conv_14 1 1 140_splitncnn_0 210 0=128 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=73728 ReLU Relu_15 1 1 210 145 Convolution Conv_16 1 1 145 213 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456 BinaryOp Add_17 2 1 213 207 148 0=0 ReLU Relu_18 1 1 148 149 Split splitncnn_3 1 2 149 149_splitncnn_0 149_splitncnn_1 Convolution Conv_19 1 1 149_splitncnn_1 216 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456 ReLU Relu_20 1 1 216 152 Convolution Conv_21 1 1 152 219 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456 BinaryOp Add_22 2 1 219 149_splitncnn_0 155 0=0 ReLU Relu_23 1 1 155 156 Split splitncnn_4 1 2 156 156_splitncnn_0 156_splitncnn_1 Convolution Conv_24 1 1 156_splitncnn_1 222 0=256 1=1 11=1 2=1 12=1 3=2 13=2 4=0 14=0 15=0 16=0 5=1 6=32768 Convolution Conv_25 1 1 156_splitncnn_0 225 0=256 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=294912 ReLU Relu_26 1 1 225 161 Convolution Conv_27 1 1 161 228 0=256 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=589824 BinaryOp Add_28 2 1 228 222 164 0=0 ReLU Relu_29 1 1 164 165 Split splitncnn_5 1 2 165 165_splitncnn_0 165_splitncnn_1 Convolution Conv_30 1 1 165_splitncnn_1 231 0=256 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=589824 ReLU Relu_31 1 1 231 168 Convolution Conv_32 1 1 168 234 0=256 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=589824 BinaryOp Add_33 2 1 234 165_splitncnn_0 171 0=0 ReLU Relu_34 1 1 171 172 Split splitncnn_6 1 2 172 172_splitncnn_0 172_splitncnn_1 Convolution Conv_35 1 1 172_splitncnn_1 237 0=512 1=1 11=1 2=1 12=1 3=2 13=2 4=0 14=0 15=0 16=0 5=1 6=131072 Convolution Conv_36 1 1 172_splitncnn_0 240 0=512 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=1179648 ReLU Relu_37 1 1 240 177 Convolution Conv_38 1 1 177 243 0=512 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=2359296 BinaryOp Add_39 2 1 243 237 180 0=0 ReLU Relu_40 1 1 180 181 Split splitncnn_7 1 2 181 181_splitncnn_0 181_splitncnn_1 Convolution Conv_41 1 1 181_splitncnn_1 246 0=512 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=2359296 ReLU Relu_42 1 1 246 184 Convolution Conv_43 1 1 184 249 0=512 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=2359296 BinaryOp Add_44 2 1 249 181_splitncnn_0 187 0=0 ReLU Relu_45 1 1 187 188 Pooling GlobalAveragePool_46 1 1 188 189 0=1 4=1 Flatten Flatten_47 1 1 189 190 InnerProduct Gemm_48 1 1 190 output 0=2 1=1 2=1024
预处理
ncnn::Mat in = ncnn::Mat::from_pixels_resize(pInBuf, ncnn::Mat::PIXEL_BGR, nWidth, nHeight, 224, 224);
const float mean_vals[3] = {123.675f, 116.28f, 103.53f};
const float norm_vals[3] = {1.0f / 58.395f, 1.0f / 57.12f, 1.0 / 57.375f};
in.substract_mean_normalize(mean_vals, norm_vals);
onnx模型推理结果是准确的,opset V8和V10都试过
推荐使用pnnx转换模型 https://github.com/pnnx/pnnx
推荐使用pnnx转换模型 https://github.com/pnnx/pnnx
@nihui 我试了pnnx,结果和onnx转ncnn的结果一样。
顺便问个问题,pytorch模型要求输入维度是CHW,但是输入bmp的buffer是HWC的分布,这里是否需要做维度转换?在ncnn的sample里没有看到转换的例子。
cv::Mat m = cv::imread(“test.bmp”);
ncnn::Mat in = ncnn::Mat::from_pixels_resize(m.data, ncnn::Mat::PIXEL_BGR, nWidth, nHeight, 224, 224);
const float mean_vals[3] = {123.675f, 116.28f, 103.53f};
const float norm_vals[3] = {1.0f / 58.395f, 1.0f / 57.12f, 1.0 / 57.375f};
in.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Extractor ex = resnet18.create_extractor();
ex.input("in0", in);
ncnn::Mat out;
ex.extract("out0", out);
@hum-yong 兄弟请问解决了吗,我也遇到一样的问题
推荐使用pnnx转换模型 https://github.com/pnnx/pnnx
@nihui 我试了pnnx,结果和onnx转ncnn的结果一样。
顺便问个问题,pytorch模型要求输入维度是CHW,但是输入bmp的buffer是HWC的分布,这里是否需要做维度转换?在ncnn的sample里没有看到转换的例子。
cv::Mat m = cv::imread(“test.bmp”); ncnn::Mat in = ncnn::Mat::from_pixels_resize(m.data, ncnn::Mat::PIXEL_BGR, nWidth, nHeight, 224, 224); const float mean_vals[3] = {123.675f, 116.28f, 103.53f}; const float norm_vals[3] = {1.0f / 58.395f, 1.0f / 57.12f, 1.0 / 57.375f}; in.substract_mean_normalize(mean_vals, norm_vals); ncnn::Extractor ex = resnet18.create_extractor(); ex.input("in0", in); ncnn::Mat out; ex.extract("out0", out);
使用 pnnx 转换后,可以用 xxx_pnnx.py 与 xxx_ncnn.py 检查模型结果,与原始 torch 模型做比较
@hum-yong ,我也是有这个问题,导致推理结果一致有问题,怎么解决
@hum-yong 兄弟请问解决了吗,我也遇到一样的问题
问题解决了,犯了低级错误,在预处理resize时把WH搞错。模型用pnnx和onnx转ncnn推理结果都没问题,因为是标准resnet模型,理应没问题
推荐使用pnnx转换模型 https://github.com/pnnx/pnnx
@nihui 我试了pnnx,结果和onnx转ncnn的结果一样。 顺便问个问题,pytorch模型要求输入维度是CHW,但是输入bmp的buffer是HWC的分布,这里是否需要做维度转换?在ncnn的sample里没有看到转换的例子。
cv::Mat m = cv::imread(“test.bmp”); ncnn::Mat in = ncnn::Mat::from_pixels_resize(m.data, ncnn::Mat::PIXEL_BGR, nWidth, nHeight, 224, 224); const float mean_vals[3] = {123.675f, 116.28f, 103.53f}; const float norm_vals[3] = {1.0f / 58.395f, 1.0f / 57.12f, 1.0 / 57.375f}; in.substract_mean_normalize(mean_vals, norm_vals); ncnn::Extractor ex = resnet18.create_extractor(); ex.input("in0", in); ncnn::Mat out; ex.extract("out0", out);使用 pnnx 转换后,可以用 xxx_pnnx.py 与 xxx_ncnn.py 检查模型结果,与原始 torch 模型做比较
谢谢
@hum-yong ,我也是有这个问题,导致推理结果一致有问题,怎么解决
图像resize低级错误,模型转换没问题
针对onnx模型转换的各种问题,推荐使用最新的pnnx工具转换到ncnn In view of various problems in onnx model conversion, it is recommended to use the latest pnnx tool to convert your model to ncnn
pip install pnnx
pnnx model.onnx inputshape=[1,3,224,224]
详细参考文档 Detailed reference documentation https://github.com/pnnx/pnnx https://github.com/Tencent/ncnn/wiki/use-ncnn-with-pytorch-or-onnx#how-to-use-pnnx