未验证 提交 f891064a 编写于 作者: K Kaipeng Deng 提交者: GitHub

add yolov3_mobilenet_v3 pruned model for mobile side (#532)

上级 cbddf331
...@@ -19,6 +19,7 @@ MobileNetV3: ...@@ -19,6 +19,7 @@ MobileNetV3:
norm_decay: 0. norm_decay: 0.
model_name: large model_name: large
scale: 1. scale: 1.
extra_block_filters: []
feature_maps: [1, 2, 3, 4, 6] feature_maps: [1, 2, 3, 4, 6]
YOLOv3Head: YOLOv3Head:
......
# Practical Mobile-side detection method base on PaddleDetection
Mobile-side models are provided base on following architecture:
1. YOLOv3
2. Cascade Faster RCNN
3. SSD
## YOLOv3 mobile-side model
Mobile-side model based on YOLOv3 is a pruned model of YOLOv3-MobileNetv3, we pruned the YOLO-head of YOLOv3-MobileNetv3 and distill the pruned model by YOLOv3-ResNet34, which has a higher mAP on COCO as 31.4(input shape as 320\*320). For pruning, configurations as as follows:
1. pruning YOLO-head with following configuration and the FLOPS pruned ratios is 86%.
```
--pruned_params="yolo_block.0.0.0.conv.weights,yolo_block.0.0.1.conv.weights,yolo_block.0.1.0.conv.weights,yolo_block.0.1.1.conv.weights,yolo_block.0.2.conv.weights,yolo_block.0.tip.conv.weights,yolo_block.1.0.0.conv.weights,yolo_block.1.0.1.conv.weights,yolo_block.1.1.0.conv.weights,yolo_block.1.1.1.conv.weights,yolo_block.1.2.conv.weights,yolo_block.1.tip.conv.weights,yolo_block.2.0.0.conv.weights,yolo_block.2.0.1.conv.weights,yolo_block.2.1.0.conv.weights,yolo_block.2.1.1.conv.weights,yolo_block.2.2.conv.weights,yolo_block.2.tip.conv.weights" \
--pruned_ratios="0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.75,0.875,0.875,0.875,0.875,0.875,0.875"
```
2. pruning YOLO-head by [Filter Pruning via Geometric Median](https://arxiv.org/abs/1811.00250), use FPGM algorithm by setting:
```
--prune_criterion=geometry_median
```
### Model Zoo
| Backbone | prune method | GFLOPs | Model size(MB) | input shape | teacher model | Box AP | SD845 latency | download |
| :----------------| :----------: | :-----------: | :------------: | :---------: | :-------------------: | :--------: | :-----------: |:-----------------------------------------------------: |
| MobileNetv3 | baseline | 4.93 | 90.23 | 320 | - | 27.1 | 319ms | [下载链接](https://paddlemodels.bj.bcebos.com/object_detection/yolov3_mobilenet_v3.pdparams) |
| MobileNetv3 | prune | 0.66(-86.57%) | 16.21(-82.03%) | 320 | YOLOv3-ResNet34(31.4) | 24.6(-2.5) | 91ms | [下载链接](https://paddlemodels.bj.bcebos.com/object_detection/yolov3_mobilenet_v3_mobilenetv3_prune75875_FPGM_distillby_r34.pdparams) |
**NOTE:** `baseline` is the YOLOv3-MobileNetv3 base model, `prune` is the pruned model from YOLOv3-MobileNetv3 and pruned by configurations above, `Box AP` is test by `320*320` as input shape in both two models, and `latency` is test on Snapdragon845 with single thread. The pruned model is 2.5 times faster than the base model when the `Box AP` only decreased by 2.5.
...@@ -231,7 +231,9 @@ def main(): ...@@ -231,7 +231,9 @@ def main():
assert pruned_ratios > [0] * len(pruned_ratios) and pruned_ratios < [1] * len(pruned_ratios), \ assert pruned_ratios > [0] * len(pruned_ratios) and pruned_ratios < [1] * len(pruned_ratios), \
"The elements of pruned ratios should be in range (0, 1)." "The elements of pruned ratios should be in range (0, 1)."
pruner = Pruner() assert FLAGS.prune_criterion in ['l1_norm', 'geometry_median'], \
"unsupported prune criterion {}".format(FLAGS.prune_criterion)
pruner = Pruner(criterion=FLAGS.prune_criterion)
distill_prog = pruner.prune( distill_prog = pruner.prune(
fluid.default_main_program(), fluid.default_main_program(),
fluid.global_scope(), fluid.global_scope(),
...@@ -361,5 +363,11 @@ if __name__ == '__main__': ...@@ -361,5 +363,11 @@ if __name__ == '__main__':
type=str, type=str,
help="The ratios pruned iteratively for each parameter when calculating sensitivities." help="The ratios pruned iteratively for each parameter when calculating sensitivities."
) )
parser.add_argument(
"--prune_criterion",
default='l1_norm',
type=str,
help="criterion function type for channels sorting in pruning, can be set " \
"as 'l1_norm' or 'geometry_median' currently, default 'l1_norm'")
FLAGS = parser.parse_args() FLAGS = parser.parse_args()
main() main()
...@@ -187,7 +187,9 @@ def main(): ...@@ -187,7 +187,9 @@ def main():
pruned_ratios < [1] * len(pruned_ratios) pruned_ratios < [1] * len(pruned_ratios)
), "The elements of pruned ratios should be in range (0, 1)." ), "The elements of pruned ratios should be in range (0, 1)."
pruner = Pruner() assert FLAGS.prune_criterion in ['l1_norm', 'geometry_median'], \
"unsupported prune criterion {}".format(FLAGS.prune_criterion)
pruner = Pruner(criterion=FLAGS.prune_criterion)
train_prog = pruner.prune( train_prog = pruner.prune(
train_prog, train_prog,
fluid.global_scope(), fluid.global_scope(),
...@@ -388,5 +390,11 @@ if __name__ == '__main__': ...@@ -388,5 +390,11 @@ if __name__ == '__main__':
default=False, default=False,
action='store_true', action='store_true',
help="Whether to only print the parameters' names and shapes.") help="Whether to only print the parameters' names and shapes.")
parser.add_argument(
"--prune_criterion",
default='l1_norm',
type=str,
help="criterion function type for channels sorting in pruning, can be set " \
"as 'l1_norm' or 'geometry_median' currently, default 'l1_norm'")
FLAGS = parser.parse_args() FLAGS = parser.parse_args()
main() main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册