Repository: PaddlePaddle/PaddleDetection

Issue:
请问模型裁剪只能针对yolov3么？
如果想对faster-rcnn的模型进行裁剪，应该怎么做呢？

谢谢！


Discussion:
首先，参考这个教程计算敏感度：
https://github.com/PaddlePaddle/PaddleDetection/tree/release/0.2/slim/sensitive

然后，参考这个教程，将其中的配置文件选项设置为faster-rcnn配置文件即可。
https://github.com/PaddlePaddle/PaddleDetection/tree/release/0.2/slim/prune
> 
> 
> 首先，参考这个教程计算敏感度：
> https://github.com/PaddlePaddle/PaddleDetection/tree/release/0.2/slim/sensitive
> 
> 然后，参考这个教程，将其中的配置文件选项设置为faster-rcnn配置文件即可。
> https://github.com/PaddlePaddle/PaddleDetection/tree/release/0.2/slim/prune

按照这个操作计算敏感度，然后prune都没问题，但是prune之后eval的时候报错了。AssertionError: Shape not matching: the Program requires a parameter with a shape of ((128,)), while the loaded parameter (namely [ bn3a_branch2b_mean ]) has a shape of  ((30,)).

刚试了下yolo模型剪枝后的eval也报了一个类似的错 @wanghaoshuang 麻烦老师帮忙看下，谢谢啦~
@mitsuix 请问您是怎么调用eval.py的？是按这一节的介绍么？https://github.com/PaddlePaddle/PaddleDetection/tree/release/0.2/slim/prune#5-%E8%AF%84%E4%BC%B0%E5%89%AA%E8%A3%81%E6%A8%A1%E5%9E%8B
PaddleSlim使用的哪个版本，建议使用v1.0.1， develop上prune方式有修改
> 
> 
> @mitsuix 请问您是怎么调用eval.py的？是按这一节的介绍么？https://github.com/PaddlePaddle/PaddleDetection/tree/release/0.2/slim/prune#5-%E8%AF%84%E4%BC%B0%E5%89%AA%E8%A3%81%E6%A8%A1%E5%9E%8B

是按这节介绍做的，PaddleSlimv1.0.1和v.1.0.0都试过了，都报这个错呢
> 
> 
> PaddleSlim使用的哪个版本，建议使用v1.0.1， develop上prune方式有修改

v1.0.1和v1.0.0都试过了，一样的报错，和用自己的数据集有关系么？ @heavengate
```
python eval.py \
-c ../../configs/yolov3_mobilenet_v1_voc.yml \
--pruned_params "yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights" \
--pruned_ratios="0.2,0.3,0.4" \
-o weights=output/yolov3_mobilenet_v1_voc/model_final
```
请确认下`--pruned_params`和`--pruned_ratios`设置的和训练时一致？
> 
> 
> ```
> python eval.py \
> -c ../../configs/yolov3_mobilenet_v1_voc.yml \
> --pruned_params "yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights" \
> --pruned_ratios="0.2,0.3,0.4" \
> -o weights=output/yolov3_mobilenet_v1_voc/model_final
> ```
> 
> 请确认下`--pruned_params`和`--pruned_ratios`设置的和训练时一致？

一致的。刚用了示例的参数重跑了，还是一样的报错，日志如下：

python prune.py -c G:\workspace\github\paddle\PaddleDetection\configs\test\yolov3_mobilenet_v1_p.yml --pruned_params "yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights" --pruned_ratios="0.2,0.3,0.4"

2020-03-18 11:35:46,569-INFO: Save model to I:/test/models/output_prune\yolov3_mobilenet_v1_p\model_final.

python eval.py -c G:\workspace\github\paddle\PaddleDetection\configs\test\yolov3_mobilenet_v1_p.yml --pruned_params "yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights" --pruned_ratios="0.2,0.3,0.4" -o weights=I:/test/models/output_prune/yolov3_mobilenet_v1_p/model_final

Traceback (most recent call last):
  File "eval.py", line 229, in <module>
    main()
  File "eval.py", line 179, in main
    checkpoint.load_params(exe, eval_prog, cfg.weights)
  File "G:\workspace\github\paddle\PaddleDetection\ppdet\utils\checkpoint.py", line 141, in load_params
    fluid.io.set_program_state(prog, state)
  File "C:\Users\admin\AppData\Roaming\Python\Python36\site-packages\paddle\fluid\io.py", line 1942, in set_program_state
    .format(orig_para_np.shape, para.name, new_para_np.shape)
AssertionError: Shape not matching: the Program requires a parameter with a shape of ((512,)), while the loaded parameter (namely [ yolo_block.0.1.0.bn.mean ]) has a shape of  ((307,)).



@wanghaoshuang 老师，这个问题怎么解决啊？
@mitsuix 我在linux执行demo是没有问题的:
训练：
```
python prune.py -c ../../configs/yolov3_mobilenet_v1_voc.yml --pruned_params "yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights" --pruned_ratios="0.2,0.3,0.4"
```
测试：
```
python eval.py -c ../../configs/yolov3_mobilenet_v1_voc.yml  --pruned_params "yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights" --pruned_ratios="0.2,0.3,0.4" -o weights=output/yolov3_mobilenet_v1_voc/model_final
```

您在windows上测试时，有以下log么？
```
2020-03-20 07:48:40,384-INFO: pruned params: ['yolo_block.0.0.0.conv.weights', 'yolo_block.0.0.1.conv.weights', 'yolo_block.0.1.0.conv.weights']
2020-03-20 07:48:40,384-INFO: pruned ratios: [0.2, 0.3, 0.4]
2020-03-20 07:48:40,530-INFO: pruned FLOPS: 0.0727296159478
```
@wanghaoshuang 有。完整的是这样的。

`2020-03-20 16:27:59,260-INFO: pruned params: ['yolo_block.0.0.0.conv.weights', 'yolo_block.0.0.1.conv.weights', 'yolo_block.0.1.0.conv.weights']
2020-03-20 16:27:59,261-INFO: pruned ratios: [0.2, 0.3, 0.4]
2020-03-20 16:27:59,437-INFO: pruned FLOPS: 0.18126663050258127
W0320 16:28:02.881803 20184 device_context.cc:237] Please NOTE: device: 0, CUDA Capability: 61, Driver API Version: 10.0, Runtime API Version: 9.0
W0320 16:28:07.694550 20184 device_context.cc:245] device: 0, cuDNN Version: 7.4.
2020-03-20 16:28:09,742-INFO: Loading parameters from I:/test/models/output_prune/yolov3_mobilenet_v1_p/model_final...
Traceback (most recent call last):
File "eval.py", line 229, in 
File "eval.py", line 179, in main
checkpoint.load_params(exe, eval_prog, cfg.weights)
File "G:\workspace\github\paddle\PaddleDetection\ppdet\utils\checkpoint.py", line 141, in load_params
fluid.io.set_program_state(prog, state)
File "C:\Users\admin\AppData\Roaming\Python\Python36\site-packages\paddle\fluid\io.py", line 1942, in set_program_state
.format(orig_para_np.shape, para.name, new_para_np.shape)
AssertionError: Shape not matching: the Program requires a parameter with a shape of ((512,)), while the loaded parameter (namely [ yolo_block.0.1.0.bn.mean ]) has a shape of ((307,)).`
@wanghaoshuang 
老师，你用的啥版本啊？
我在aistudio上创建了一个paddlepaddle-gpu1.7.0的环境，PaddleDetection用的最新clone的版本，PaddleSlim是1.0.1，运行demo，还是类似的报错啊。
@mitsuix 你方便把你的aistudio demo链接公开后分享给我么？
@wanghaoshuang https://aistudio.baidu.com/aistudio/projectdetail/332084 谢谢啦
@wanghaoshuang 老师看aistudio了么？是哪个操作导致报错了啊，囧~

Resolving patch:
diff --git a/slim/prune/eval.py b/slim/prune/eval.py
--- a/slim/prune/eval.py
+++ b/slim/prune/eval.py
@@ -86,6 +86,7 @@ def main():
                 fetches = model.eval(feed_vars, multi_scale_test)
     eval_prog = eval_prog.clone(True)
 
+    exe.run(startup_prog)
     reader = create_reader(cfg.EvalReader)
     loader.set_sample_list_generator(reader, place)
 
@@ -123,7 +124,7 @@ def main():
         params=pruned_params,
         ratios=pruned_ratios,
         place=place,
-        only_graph=True)
+        only_graph=False)
     pruned_flops = flops(eval_prog)
     logger.info("pruned FLOPS: {}".format(
         float(base_flops - pruned_flops) / base_flops))
@@ -174,7 +175,6 @@ def main():
         sub_eval_prog = sub_eval_prog.clone(True)
 
     # load model
-    exe.run(startup_prog)
     if 'weights' in cfg:
         checkpoint.load_checkpoint(exe, eval_prog, cfg.weights)
 


Test patch: