Tencent / ncnn

ncnn is a high-performance neural network inference framework optimized for the mobile platform
Other
20.09k stars 4.13k forks source link

修改backbone后的Yolact模型转ncnn,输出错误 #1747

Open mychina75 opened 4 years ago

mychina75 commented 4 years ago

参考nihui大神的说明,成功转了官方resnet-50的yolact模型,运行正常。 我又把backbone改成了efficientdet,训出的pytorch模型结果也不错。所以尝试转成NCNN 过程也一切正常。

不过跑yolact.cpp只输出了原图。调试后发现conf[]的值都是nan或者-nan。貌似模型转换时出错了。 param文件开头就很可疑,有很多行的MemoryData。而之前resnet-50的yolact是没有的。 @nihui 请帮忙分析下,拜谢!

7767517 746 891 Input x.1 0 1 x.1 MemoryData 10037 0 1 10037 0=1 MemoryData 10040 0 1 10040 0=1 MemoryData 5790 0 1 5790 0=1 MemoryData 5793 0 1 5793 0=1 MemoryData 5949 0 1 5949 0=1 MemoryData 5952 0 1 5952 0=1 MemoryData 6108 0 1 6108 0=1 MemoryData 6111 0 1 6111 0=1 MemoryData 6267 0 1 6267 0=1 MemoryData 6270 0 1 6270 0=1 MemoryData 6540 0 1 6540 0=1 MemoryData 6543 0 1 6543 0=1 MemoryData 6547 0 1 6547 0=1 MemoryData 6743 0 1 6743 0=1 MemoryData 6746 0 1 6746 0=1 MemoryData 6750 0 1 6750 0=1 MemoryData 6946 0 1 6946 0=1 MemoryData 6949 0 1 6949 0=1 MemoryData 6953 0 1 6953 0=1 MemoryData 7149 0 1 7149 0=1 MemoryData 7152 0 1 7152 0=1 MemoryData 7348 0 1 7348 0=1 MemoryData 7351 0 1 7351 0=1 MemoryData 7507 0 1 7507 0=1 MemoryData 7510 0 1 7510 0=1 MemoryData 7666 0 1 7666 0=1 MemoryData 7669 0 1 7669 0=1 MemoryData 7825 0 1 7825 0=1 MemoryData 7828 0 1 7828 0=1 MemoryData 7984 0 1 7984 0=1 MemoryData 7987 0 1 7987 0=1 MemoryData 7991 0 1 7991 0=1 MemoryData 8187 0 1 8187 0=1 MemoryData 8190 0 1 8190 0=1 MemoryData 8194 0 1 8194 0=1 MemoryData 8390 0 1 8390 0=1 MemoryData 8393 0 1 8393 0=1 MemoryData 8397 0 1 8397 0=1 MemoryData 8593 0 1 8593 0=1 MemoryData 8596 0 1 8596 0=1 MemoryData 8792 0 1 8792 0=1 MemoryData 8795 0 1 8795 0=1 MemoryData 8951 0 1 8951 0=1 MemoryData 8954 0 1 8954 0=1 MemoryData 9110 0 1 9110 0=1 MemoryData 9113 0 1 9113 0=1 MemoryData 9269 0 1 9269 0=1 MemoryData 9272 0 1 9272 0=1 MemoryData 9428 0 1 9428 0=1 MemoryData 9431 0 1 9431 0=1 MemoryData 9435 0 1 9435 0=1 MemoryData 9631 0 1 9631 0=1 MemoryData 9634 0 1 9634 0=1 MemoryData 9638 0 1 9638 0=1 MemoryData 9834 0 1 9834 0=1 MemoryData 9837 0 1 9837 0=1 MemoryData 9841 0 1 9841 0=1 Convolution 698 1 1 x.1 698 0=32 1=3 11=3 2=1 12=1 3=2 13=2 4=0 14=0 15=1 16=1 5=1 6=864 Split splitncnn_0 1 2 698 698_splitncnn_0 698_splitncnn_1 Sigmoid 700 1 1 698_splitncnn_1 700 BinaryOp 701 2 1 698_splitncnn_0 700 701 0=2 ...

mychina75 commented 4 years ago

ncnn部分网络结构是这样的 ncnn 而相同位置的onnx的结构是这样的 onnx

mychina75 commented 4 years ago

又不太确定是不是因为MemoryData导致的问题,仔细看了下onnx的结构,op是mul,确实乘了一些常量...

mychina75 commented 4 years ago

here is the onnx model, please check on it. Thank you~ yolact.zip

nihui commented 4 years ago

ncnnoptimize 更新了下,MemoryData 现在能 fuse 到 BinaryOp 上去了

mychina75 commented 4 years ago

优化完的结构很完美了,赞! 不过结果输出还是不太对,置信系数的参数值还是nan

nihui commented 4 years ago

你的附件我下载不了了。。

mychina75 commented 4 years ago

[yolact.zip] 抱歉哈,居然下载不了... 重新上传了。 @nihui 多谢!

nihui commented 4 years ago

yolact.zip 抱歉哈,居然下载不了... 重新上传了。 @nihui 多谢!

试了下,没什么问题呀,confidence 都是正常数值

mychina75 commented 4 years ago

哦⊙∀⊙!ncnn转换后可以正常出结果吗?我再试试哈

mychina75 commented 4 years ago

不太确定哪里出了问题,结果还是不对。已经同步了最新版本。。 @nihui 请帮忙看看哪个环节出了问题吧。

我的处理流程如下:

  1. onnx模型简化,输出yolact-sim.onnx
  2. 转ncnn模型,输出yolact.param和yolact.bin
  3. ncnn模型优化,输出yolact-opt.param和yolact-opt.bin
  4. 修改yolact-opt.param文件, Concat 10465 5 1 10283 10322 10361 10400 10439 10465 0=0 Concat 10466 5 1 10295 10334 10373 10412 10451 10466 0=0 Concat 10467 5 1 10308 10347 10386 10425 10464 10467 0=0
  5. 修改yolact.cpp文件,
  6. 编译执行yolact image.jpg,输出:
nihui commented 4 years ago
    yolact.load_param("yolact.param");
    yolact.load_model("yolact.bin");

    const int target_size = 512;

    int img_w = bgr.cols;
    int img_h = bgr.rows;

    ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR2RGB, img_w, img_h, target_size, target_size);

    const float mean_vals[3] = {123.68f, 116.78f, 103.94f};
    const float norm_vals[3] = {1.0/58.40f, 1.0/57.12f, 1.0/57.38f};
    in.substract_mean_normalize(mean_vals, norm_vals);

    ncnn::Extractor ex = yolact.create_extractor();
//     ex.set_num_threads(4);

    ex.input("x.1", in);

    ncnn::Mat maskmaps;
    ncnn::Mat location;
    ncnn::Mat mask;
    ncnn::Mat confidence;

    ex.extract("10268", maskmaps);// 138x138 x 32

    ex.extract("10465", location);// 4 x 19248
    ex.extract("10467", mask);// maskdim 32 x 19248
    ex.extract("10469", confidence);// 81 x 19248

    pretty_print(confidence);
mychina75 commented 4 years ago

啊! @nihui 大神,直接用onnx转换生成的ncnn模型是可以的,结果是对的。!! 用ncnnoptimize 优化后的模型就不行了。

我一直用yolact-opt去试的... Split splitncnn_1 1 2 1068 1068_splitncnn_0 1068_splitncnn_1 Pooling 1069 1 1 1068_splitncnn_1 1069 0=1 4=1 InnerProduct 1125 1 1 1069 1125 0=4 1=1 2=384 1068_splitncnn_1这一层还正常,到1069和1125后就都是-nan了。

nihui commented 4 years ago

啊! @nihui 大神,直接用onnx转换生成的ncnn模型是可以的,结果是对的。!! 用ncnnoptimize 优化后的模型就不行了。

我一直用yolact-opt去试的... Split splitncnn_1 1 2 1068 1068_splitncnn_0 1068_splitncnn_1 Pooling 1069 1 1 1068_splitncnn_1 1069 0=1 4=1 InnerProduct 1125 1 1 1069 1125 0=4 1=1 2=384 1068_splitncnn_1这一层还正常,到1069和1125后就都是-nan了。

如果 ncnnoptimize 后不行,试试看更新下 ncnnoptimize 代码... 正常是不会的,我就是 optimize 后的模型测试的

mychina75 commented 4 years ago

很奇怪,我重新下载了ncnn代码又试了一遍,结果还是一样...

在Ubuntu16.04系统下编译的,会不会是因为编译选项选的不一样? 我编译选项如下,后面没列出来的全选上了。 config

Evoluange commented 3 years ago

不太确定哪里出了问题,结果还是不对。已经同步了最新版本。。 @nihui 请帮忙看看哪个环节出了问题吧。

我的处理流程如下:

  1. onnx模型简化,输出yolact-sim.onnx
  2. 转ncnn模型,输出yolact.param和yolact.bin
  3. ncnn模型优化,输出yolact-opt.param和yolact-opt.bin
  4. 修改yolact-opt.param文件, Concat 10465 5 1 10283 10322 10361 10400 10439 10465 0=0 Concat 10466 5 1 10295 10334 10373 10412 10451 10466 0=0 Concat 10467 5 1 10308 10347 10386 10425 10464 10467 0=0
  5. 修改yolact.cpp文件,
  6. 编译执行yolact image.jpg,输出:

按照您上面的操作,在第三步ncnn模型优化,yolact.param转成yolact-opt.param时出现错误,如下: find_blob_index_by_name 1297 failed find_blob_index_by_name 1898 failed find_blob_index_by_name 2195 failed find_blob_index_by_name 2499 failed find_blob_index_by_name 2796 failed find_blob_index_by_name 3389 failed find_blob_index_by_name 3686 failed find_blob_index_by_name 3983 failed find_blob_index_by_name 4287 failed find_blob_index_by_name 4584 failed find_blob_index_by_name 4881 failed find_blob_index_by_name 5474 failed find_blob_index_by_name 5543 failed find_blob_index_by_name 5611 failed find_blob_index_by_name 5724 failed find_blob_index_by_name 5781 failed find_blob_index_by_name 6614 failed find_blob_index_by_name 6817 failed find_blob_index_by_name 7020 failed find_blob_index_by_name 7219 failed find_blob_index_by_name 8058 failed find_blob_index_by_name 8261 failed find_blob_index_by_name 8464 failed find_blob_index_by_name 8663 failed find_blob_index_by_name 9502 failed find_blob_index_by_name 9705 failed find_blob_index_by_name 9908 failed find_blob_index_by_name 10107 failed 对照param文件都是padding层读取不了,这种情况下怎么处理呢?@mychina75

walker-ai commented 2 years ago

@mychina75 可以请教一下吗,我也是更换了 backbone 为 EfficientNet 后,部署到 android 直接闪退,不知道是否是模型的问题?我对比了一下 resnet 的 param 文件,发现有很多不一样的算子 swishConvolutionDepthWise 等。详情可以看我的 issue

nihui commented 1 month ago

针对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