Toybrick

标题: 求助!多线程mobilenet ssd的C代码推断出错 [打印本页]

作者: Devin    时间: 2020-2-25 18:08
标题: 求助!多线程mobilenet ssd的C代码推断出错
模型是用caffe训练的mobilenet ssd模型转rknn的,检测类别为2(背景和行人),输入视频流大小640x480的,网络Input尺寸是300x300x3大小。推理出现内存报错。
之前用MIN_SCORE的大小跟demo中设置一样,出现了:validCount too much问题,现在将其设为0.9时,报错解决。但是出现了内存报错(free(): invalid next size (fast)munmap_chunk(): invalid pointer以及Segmentation fault等),但官方demo没有出现该问题。。。代码在附件,请大佬帮忙看下,谢谢!


作者: troy    时间: 2020-2-26 11:05
多提供点信息。
1.转换模型这一步是在PC还是在Toybrick板子上执行的,rknn-toolkit的版本是多少
2.Toybrick板子固件是否是最新的,rknn-api和driver驱动是哪个版本?(这个在程序运行时会有打印信息)
3.推理出现内存报错,可以多加点调试信息,具体是哪一步执行之后出现内存报错。
4.出错的原因应该就局限在ssd_demo_person.cpp之中,因为我以前common也测试过其他不同的模型,也没有出现过内存的错误。但是不排除ssd_demo_person.cpp设置错误,导致common中出现报错。具体需要添加调试信息跟一下流程才知道。
作者: Devin    时间: 2020-2-26 18:23
1. 模型转换是在PC的Ubuntu虚拟机上做的,rknn-toolkit的版本是1.2.0;
2. rknn-api的版本为1.2.0,driver驱动版本为0.9.9;
3. 在第一次出现内存报错时,我尝试逐行cout去查找出错位置,发现在ret = test.load_model(model_path);之后报错,跟进去继续查找,发现common中rknn_test.cpp文件里int rknn_test::load_model(const char *path)这个函数中new的一个变量没释放,尝试加了delete[],报错变成Segmentation fault等内存报错;
4. ssd_demo_person.cpp中目前相比ssd_demo.cpp,目前只把NUM_CLASSES改为2,MIN_SCORE改为0.9,其他没做修改。
补充:在转换模型时,发现如果只去掉detection_out层,会出现
  1. --> Loading model
  2. W Warning: Axis may need to be adjusted according to original model shape.
  3. W Warning: Axis may need to be adjusted according to original model shape.
  4. W Unhandle status: the input shape of reshape layer mbox_conf_reshape_116 is not 4-D
  5. done
  6. --> Building model
  7. W Warning: Axis may need to be adjusted according to original model shape.
  8. W Warning: Axis may need to be adjusted according to original model shape.
  9. W Unhandle status: the input shape of reshape layer mbox_conf_reshape_116 is not 4-D
  10. done
  11. --> Init runtime environment
  12. W [RK_nn_softmax_compute:45]Softmax's beta is 0. Set beta to 1
  13. done
  14. --> Running model
  15. done
复制代码

最后的推断结果显示的图上是十分密集的框,于是,我把网络中detection_out层之前的reshape,softmax和flatten这三层也去掉进行转换,发现不再出现以上关于reshape和softmax的warning,并且最后推理结果不再出现密集的框,而是多个框(并没有进行量化,不清楚为啥会是多个框)。因为网络结构没改,输进网络尺寸跟demo给的一样300x300x3,所以priorbox.txt也直接用的demo提供的。模型转换代码和文件在附件。
谢谢!!
作者: Devin    时间: 2020-2-27 08:22
本帖最后由 Devin 于 2020-2-27 08:24 编辑
Devin 发表于 2020-2-26 18:23
1. 模型转换是在PC的Ubuntu虚拟机上做的,rknn-toolkit的版本是1.2.0;
2. rknn-api的版本为1.2.0,driver驱 ...

这是删了reshpe,softmax和flatten三层后转rk得到的推理结果(无量化):file:///G:/share/detectOut.jpg
作者: troy    时间: 2020-2-27 14:59
Devin 发表于 2020-2-26 18:23
1. 模型转换是在PC的Ubuntu虚拟机上做的,rknn-toolkit的版本是1.2.0;
2. rknn-api的版本为1.2.0,driver驱 ...

关于第三点,你说的rknn_test::load_model中new的变量没有释放,你是指output_size吗?如果是,在load_model当中是不能释放的,因为output_size是类的指针,用来存储输出模型的size信息,在类的其他接口中也有用到,output_size被释放,必定会导致段错误!!!
我的output_size释放,已经在rknn_test的析构函数中做了,无需改动。

另外,可以在load_model加下打印,看下从模型读取到的size和你预期的size是否一致。
作者: Devin    时间: 2020-2-27 17:19
troy 发表于 2020-2-27 14:59
关于第三点,你说的rknn_test::load_model中new的变量没有释放,你是指output_size吗?如果是,在load_mo ...

谢谢版主。前面已经有释放了,那里确实不用。您指的是load_model里的output_size[0]和output_size[1]的大小是吗?它们分别是30672(1917x16)和15336(1917x8)。转模型时推理的结果outputs[0]大小是1917x4,outputs[1]的大小是1917x2。不一致。。请问怎么解决呢
作者: troy    时间: 2020-2-28 08:53
Devin 发表于 2020-2-27 17:19
谢谢版主。前面已经有释放了,那里确实不用。您指的是load_model里的output_size[0]和output_size[1]的大 ...

1.确定caffemodel实际的输出形状,你可以用https://lutzroeder.github.io/netron/加载caffe模型,查看你的输出节点的实际形状。
2.确定转换模型的时候,选择的输出节点,是否就是你想要的节点,是否和caffe模型中的节点一致。
3.你的附件中,ssd.py使用python进行推理,获取到的inference输出数据的大小是否和模型节点一致。
4.如果有使用caffe模型推理的源码,你也可以参考一下原始代码对输出数据的数据,进行对比。
作者: Devin    时间: 2020-2-29 12:31
troy 发表于 2020-2-28 08:53
1.确定caffemodel实际的输出形状,你可以用https://lutzroeder.github.io/netron/加载caffe模型,查看你 ...

1. caffemodel的实际输出形状如下图。
2. 这点不太清楚“选择的输出节点”,TF转rk是有output节点的,以下是rknn-toolkit1.2.0中mobilenet ssd中模型转化时加载原模型部分:
#rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2017_11_17.pb',
     #                    inputs=['FeatureExtractor/MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_1'],
     #                    outputs=['concat', 'concat_1'],
     #                    input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]])
但是load_caffe这里没有outputs:   
    ret = rknn.load_caffe(model='MobileNetSSD_deploy_std_truncate.prototxt',
                          proto='caffe',
                          blobs='ssd_iter_37985.caffemodel')
3. ssd.py获取的inference输出数据outputs[0]为1917x4(框的4个值),outputs[1]为1917x2(两类)。跟caffe模型输出节点是一致的。
作者: Devin    时间: 2020-2-29 12:32
caffemodel




欢迎光临 Toybrick (https://t.rock-chips.com/) Powered by Discuz! X3.3