Sanster / pytorch-network-slimming

A package to make do Network Slimming a little easier
47 stars 10 forks source link

conv pruning issue #7

Open sungh66 opened 3 years ago

sungh66 commented 3 years ago

Thanks for your work, i have pruning my two-stage detection model faster rcnn with the resnet50+fpn backbone, while running the gen_schema.py, i met a conv pruned issue, becuase the model isn't the classification task, is there anything i need to change, Traceback (most recent call last): File "gen_schema.py", line 86, in <module> pruner.run(0.6) File "model_compression/src/pns/pns.py", line 311, in run self.bn2d_modules[conv2d.next_bn_name] if conv2d.next_bn_name else None, File "model_compression/src/pns/pns.py", line 53, in prune next_bn.keep_idxes if next_bn else None, File "model_compression/src/pns/functional.py", line 97, in prune_conv2d module.bias = torch.nn.Parameter(module.bias.data[out_keep_idxes]) RuntimeError: CUDA error: device-side assert triggered My email is kevinrex66@qq.com and my wechat is 13773273112.Looking forward to your reply, thanks!

sungh66 commented 3 years ago
my model structure : name module
0 backbone.body.conv1 Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
1 backbone.body.bn1 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
2 backbone.body.layer1.0.conv1 Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
3 backbone.body.layer1.0.bn1 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
4 backbone.body.layer1.0.conv2 Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
5 backbone.body.layer1.0.bn2 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
6 backbone.body.layer1.0.conv3 Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
7 backbone.body.layer1.0.bn3 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
8 backbone.body.layer1.0.downsample.0 Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
9 backbone.body.layer1.0.downsample.1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
10 backbone.body.layer1.1.conv1 Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
11 backbone.body.layer1.1.bn1 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
12 backbone.body.layer1.1.conv2 Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
13 backbone.body.layer1.1.bn2 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
14 backbone.body.layer1.1.conv3 Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
15 backbone.body.layer1.1.bn3 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
16 backbone.body.layer1.2.conv1 Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
17 backbone.body.layer1.2.bn1 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
18 backbone.body.layer1.2.conv2 Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
19 backbone.body.layer1.2.bn2 BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
20 backbone.body.layer1.2.conv3 Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
21 backbone.body.layer1.2.bn3 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
22 backbone.body.layer2.0.conv1 Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
23 backbone.body.layer2.0.bn1 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
24 backbone.body.layer2.0.conv2 Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
25 backbone.body.layer2.0.bn2 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
26 backbone.body.layer2.0.conv3 Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
27 backbone.body.layer2.0.bn3 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
28 backbone.body.layer2.0.downsample.0 Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
29 backbone.body.layer2.0.downsample.1 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
30 backbone.body.layer2.1.conv1 Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
31 backbone.body.layer2.1.bn1 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
32 backbone.body.layer2.1.conv2 Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
33 backbone.body.layer2.1.bn2 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
34 backbone.body.layer2.1.conv3 Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
35 backbone.body.layer2.1.bn3 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
36 backbone.body.layer2.2.conv1 Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
37 backbone.body.layer2.2.bn1 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
38 backbone.body.layer2.2.conv2 Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
39 backbone.body.layer2.2.bn2 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
40 backbone.body.layer2.2.conv3 Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
41 backbone.body.layer2.2.bn3 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
42 backbone.body.layer2.3.conv1 Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
43 backbone.body.layer2.3.bn1 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
44 backbone.body.layer2.3.conv2 Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
45 backbone.body.layer2.3.bn2 BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
46 backbone.body.layer2.3.conv3 Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
47 backbone.body.layer2.3.bn3 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
48 backbone.body.layer3.0.conv1 Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
49 backbone.body.layer3.0.bn1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
50 backbone.body.layer3.0.conv2 Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
51 backbone.body.layer3.0.bn2 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
52 backbone.body.layer3.0.conv3 Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
53 backbone.body.layer3.0.bn3 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
54 backbone.body.layer3.0.downsample.0 Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
55 backbone.body.layer3.0.downsample.1 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
56 backbone.body.layer3.1.conv1 Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
57 backbone.body.layer3.1.bn1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
58 backbone.body.layer3.1.conv2 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
59 backbone.body.layer3.1.bn2 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
60 backbone.body.layer3.1.conv3 Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
61 backbone.body.layer3.1.bn3 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
62 backbone.body.layer3.2.conv1 Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
63 backbone.body.layer3.2.bn1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
64 backbone.body.layer3.2.conv2 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
65 backbone.body.layer3.2.bn2 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
66 backbone.body.layer3.2.conv3 Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
67 backbone.body.layer3.2.bn3 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
68 backbone.body.layer3.3.conv1 Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
69 backbone.body.layer3.3.bn1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
70 backbone.body.layer3.3.conv2 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
71 backbone.body.layer3.3.bn2 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
72 backbone.body.layer3.3.conv3 Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
73 backbone.body.layer3.3.bn3 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
74 backbone.body.layer3.4.conv1 Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
75 backbone.body.layer3.4.bn1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
76 backbone.body.layer3.4.conv2 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
77 backbone.body.layer3.4.bn2 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
78 backbone.body.layer3.4.conv3 Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
79 backbone.body.layer3.4.bn3 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
80 backbone.body.layer3.5.conv1 Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
81 backbone.body.layer3.5.bn1 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
82 backbone.body.layer3.5.conv2 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
83 backbone.body.layer3.5.bn2 BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
84 backbone.body.layer3.5.conv3 Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
85 backbone.body.layer3.5.bn3 BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
86 backbone.body.layer4.0.conv1 Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
87 backbone.body.layer4.0.bn1 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
88 backbone.body.layer4.0.conv2 Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
89 backbone.body.layer4.0.bn2 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
90 backbone.body.layer4.0.conv3 Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
91 backbone.body.layer4.0.bn3 BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
92 backbone.body.layer4.0.downsample.0 Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
93 backbone.body.layer4.0.downsample.1 BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
94 backbone.body.layer4.1.conv1 Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
95 backbone.body.layer4.1.bn1 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
96 backbone.body.layer4.1.conv2 Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
97 backbone.body.layer4.1.bn2 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
98 backbone.body.layer4.1.conv3 Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
99 backbone.body.layer4.1.bn3 BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
100 backbone.body.layer4.2.conv1 Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
101 backbone.body.layer4.2.bn1 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
102 backbone.body.layer4.2.conv2 Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
103 backbone.body.layer4.2.bn2 BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
104 backbone.body.layer4.2.conv3 Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
105 backbone.body.layer4.2.bn3 BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
106 backbone.fpn.inner_blocks.0 Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))
107 backbone.fpn.inner_blocks.1 Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
108 backbone.fpn.inner_blocks.2 Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))
109 backbone.fpn.inner_blocks.3 Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1))
110 backbone.fpn.layer_blocks.0 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
111 backbone.fpn.layer_blocks.1 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
112 backbone.fpn.layer_blocks.2 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
113 backbone.fpn.layer_blocks.3 Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
114 rpn.head.conv Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
115 rpn.head.cls_logits Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
116 rpn.head.bbox_pred Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
117 roi_heads.box_head.fc6 Linear(in_features=12544, out_features=1024, bias=True)
118 roi_heads.box_head.fc7 Linear(in_features=1024, out_features=1024, bias=True)
119 roi_heads.box_predictor.cls_score Linear(in_features=1024, out_features=2, bias=True)
120 roi_heads.box_predictor.bbox_pred Linear(in_features=1024, out_features=8, bias=True)
BatchNorm2d prune info name channels prune percent
0 backbone.body.bn1 46/64 28.12%
1 backbone.body.layer1.0.bn1 22/64 65.62%
2 backbone.body.layer1.0.bn2 8/64 87.50%
3 backbone.body.layer1.0.bn3 172/256 32.81%
4 backbone.body.layer1.0.downsample.1 172/256 32.81%
5 backbone.body.layer1.1.bn1 17/64 73.44%
6 backbone.body.layer1.1.bn2 12/64 81.25%
7 backbone.body.layer1.1.bn3 172/256 32.81%
8 backbone.body.layer1.2.bn1 10/64 84.38%
9 backbone.body.layer1.2.bn2 47/64 26.56%
10 backbone.body.layer1.2.bn3 172/256 32.81%
11 backbone.body.layer2.0.bn1 49/128 61.72%
12 backbone.body.layer2.0.bn2 42/128 67.19%
13 backbone.body.layer2.0.bn3 256/512 50.00%
14 backbone.body.layer2.0.downsample.1 256/512 50.00%
15 backbone.body.layer2.1.bn1 1/128 99.22%
16 backbone.body.layer2.1.bn2 11/128 91.41%
17 backbone.body.layer2.1.bn3 256/512 50.00%
18 backbone.body.layer2.2.bn1 15/128 88.28%
19 backbone.body.layer2.2.bn2 30/128 76.56%
20 backbone.body.layer2.2.bn3 256/512 50.00%
21 backbone.body.layer2.3.bn1 5/128 96.09%
22 backbone.body.layer2.3.bn2 48/128 62.50%
23 backbone.body.layer2.3.bn3 256/512 50.00%
24 backbone.body.layer3.0.bn1 185/256 27.73%
25 backbone.body.layer3.0.bn2 33/256 87.11%
26 backbone.body.layer3.0.bn3 201/1024 80.37%
27 backbone.body.layer3.0.downsample.1 201/1024 80.37%
28 backbone.body.layer3.1.bn1 10/256 96.09%
29 backbone.body.layer3.1.bn2 40/256 84.38%
30 backbone.body.layer3.1.bn3 201/1024 80.37%
31 backbone.body.layer3.2.bn1 7/256 97.27%
32 backbone.body.layer3.2.bn2 38/256 85.16%
33 backbone.body.layer3.2.bn3 201/1024 80.37%
34 backbone.body.layer3.3.bn1 17/256 93.36%
35 backbone.body.layer3.3.bn2 12/256 95.31%
36 backbone.body.layer3.3.bn3 201/1024 80.37%
37 backbone.body.layer3.4.bn1 15/256 94.14%
38 backbone.body.layer3.4.bn2 19/256 92.58%
39 backbone.body.layer3.4.bn3 201/1024 80.37%
40 backbone.body.layer3.5.bn1 38/256 85.16%
41 backbone.body.layer3.5.bn2 49/256 80.86%
42 backbone.body.layer3.5.bn3 201/1024 80.37%
43 backbone.body.layer4.0.bn1 339/512 33.79%
44 backbone.body.layer4.0.bn2 109/512 78.71%
45 backbone.body.layer4.0.bn3 2048/2048 0.00%
46 backbone.body.layer4.0.downsample.1 2048/2048 0.00%
47 backbone.body.layer4.1.bn1 90/512 82.42%
48 backbone.body.layer4.1.bn2 218/512 57.42%
49 backbone.body.layer4.1.bn3 2048/2048 0.00%
50 backbone.body.layer4.2.bn1 321/512 37.30%
51 backbone.body.layer4.2.bn2 241/512 52.93%
52 backbone.body.layer4.2.bn3 2048/2048 0.00%
sungh66 commented 3 years ago

如果我运行main.py的slimprune会报这个错 Traceback (most recent call last): File "/home/highsai/Desktop/fire_train/model_compression/main.py", line 373, in <module> pruning_result = pruner.run(args.prune_ratio) File "/home/highsai/Desktop/fire_train/model_compression/src/pns/pns.py", line 311, in run self.bn2d_modules[conv2d.next_bn_name] if conv2d.next_bn_name else None, File "/home/highsai/Desktop/fire_train/model_compression/src/pns/pns.py", line 53, in prune next_bn.keep_idxes if next_bn else None, File "/home/highsai/Desktop/fire_train/model_compression/src/pns/functional.py", line 80, in prune_conv2d ), f"len(in_keep_idxes): {len(in_keep_idxes)}, module.weight.shape[1]: {module.weight.shape[1]}" AssertionError: len(in_keep_idxes): 377, module.weight.shape[1]: 256 错误原因大概是fpn的输入尺寸问题,请问涉及fpn的模型如何做剪枝呢

Sanster commented 3 years ago

如果 fpn 各层是 sum 的,可以在 "shortcuts" 配置里手动加一组 fpn 的 bn 名字

    {
      "names": [
        "fpn.norm1",
        "fpn.norm2",
        "fpn.norm3"    
      ],
      "method": "or"
    },

或者只剪 backbone 部分

sungh66 commented 3 years ago

如果fpn没有bn层呢,你可以看一下我上面的网络结构,两个四层的block,都是conv。如果不剪fpn,那每个resnet的剪过的层输出怎么给没变化的fpn各层

Sanster commented 3 years ago

resnet 每个 stage 最后一层 bn 前的 conv,在配置里把 "next_bn" 改成空字符串,这样输出的 channel 就不会变

dy1998 commented 3 years ago

如果 fpn 各层是 sum 的,可以在 "shortcuts" 配置里手动加一组 fpn 的 bn 名字

    {
      "names": [
        "fpn.norm1",
        "fpn.norm2",
        "fpn.norm3"    
      ],
      "method": "or"
    },

或者只剪 backbone 部分

你好,请问怎么设置只裁剪backbone部分?

Sanster commented 3 years ago

如果 fpn 各层是 sum 的,可以在 "shortcuts" 配置里手动加一组 fpn 的 bn 名字

    {
      "names": [
        "fpn.norm1",
        "fpn.norm2",
        "fpn.norm3"    
      ],
      "method": "or"
    },

或者只剪 backbone 部分

你好,请问怎么设置只裁剪backbone部分?

初始化 SlimPruner(restored_model, prune_schema) 的时候只给 backbone(nn.Module),prune_schema 也是只包含 backbone 的设置,恢复剪枝结果和参数的时候同理

dy1998 commented 3 years ago

resnet 每个 stage 最后一层 bn 前的 conv,在配置里把 "next_bn" 改成空字符串,这样输出的 channel 就不会变

感谢回答,我尝试了你的建议,修改了各个downsample前一层的next_bn,但是downsampling里面的batchnorm并未改变,请问该怎么做?

之前的: (layer1): ResLayer( (0): Bottleneck( (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False) (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False) (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (relu): ReLU(inplace=True) (downsample): Sequential( (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False) (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) ) )

改了之后的:

(layer1): ResLayer( (0): Bottleneck( (conv1): Conv2d(46, 35, kernel_size=(1, 1), stride=(1, 1), bias=False) (bn1): BatchNorm2d(35, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (conv2): Conv2d(35, 11, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) (bn2): BatchNorm2d(11, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (conv3): Conv2d(11, 256, kernel_size=(1, 1), stride=(1, 1), bias=False) (bn3): BatchNorm2d(246, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (relu): ReLU(inplace=True) (downsample): Sequential( (0): Conv2d(46, 246, kernel_size=(1, 1), stride=(1, 1), bias=False) (1): BatchNorm2d(246, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) ) )

sungh66 commented 3 years ago

感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。

dy1998 commented 3 years ago

感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。

你好,请问你是直接修改了json文件里面的fpn的next_bn吗?

sungh66 commented 3 years ago

不用,删除json里fpn的4个256-->256的layer_block(注意inner_block不要删)和包含conv的rpn的结构(linear的不要删),然后在pns.py的218行左右的isinstance(module,Conv2d)后面增加判断条件筛选不需要剪枝的部分,比如 and name != 'backbone.fpn.layer_blocks.0'的四个以及rpn的三个,意思就是这些部分都不剪,总共只改输入的fpn的inner_layer的输入尺寸

------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2021年9月30日(星期四) 上午10:17 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [Sanster/pytorch-network-slimming] conv pruning issue (#7)

感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。

你好,请问你是直接修改了json文件里面的fpn的next_bn吗?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

Sanster commented 3 years ago

感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。

1
dy1998 commented 3 years ago

不用,删除json里fpn的4个256-->256的layer_block(注意inner_block不要删)和包含conv的rpn的结构(linear的不要删),然后在pns.py的218行左右的isinstance(module,Conv2d)后面增加判断条件筛选不需要剪枝的部分,比如 and name != 'backbone.fpn.layer_blocks.0'的四个以及rpn的三个,意思就是这些部分都不剪,总共只改输入的fpn的inner_layer的输入尺寸 ------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2021年9月30日(星期四) 上午10:17 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [Sanster/pytorch-network-slimming] conv pruning issue (#7) 感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。 你好,请问你是直接修改了json文件里面的fpn的next_bn吗? — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

感谢你的建议,模型能剪枝成功了,但是在跑推理的时候出现了size_mismatch的问题,应该是全连接层那里出错了,请问你有遇到这个错误吗?

sungh66 commented 3 years ago

感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。

1
  • 「4」 里面的 restored_model:是已经加载了大模型参数的部分网络,例如一个 backbone 的实例(nn.Module类)
  • 执行完 pruner.run(prune_ratio=0.75) 以后 pruner.pruned_model 即为加载了大模型参数,并剪枝了的模型,可以用 torch.save 保存
  • 恢复的时候也只恢复部分的网络,参考截图里的「5」

这个restored_model可以是稀疏训练后的大模型吧,你的意思是不是4步骤里的pruned_model直接继续finetune就好了,还是需要得到步骤5里的pruned_state_dict,这个是怎么得到的?

Sanster commented 3 years ago

是的,4 里面的 pruned_model 直接finetune,然后保存到你喜欢的地方。5 是加载 finetune 好的剪枝模型的步骤,pruned_state_dict 需要你自己加载 4 里面 finetune 好的参数

dy1998 commented 3 years ago

不用,删除json里fpn的4个256-->256的layer_block(注意inner_block不要删)和包含conv的rpn的结构(linear的不要删),然后在pns.py的218行左右的isinstance(module,Conv2d)后面增加判断条件筛选不需要剪枝的部分,比如 and name != 'backbone.fpn.layer_blocks.0'的四个以及rpn的三个,意思就是这些部分都不剪,总共只改输入的fpn的inner_layer的输入尺寸 ------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2021年9月30日(星期四) 上午10:17 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [Sanster/pytorch-network-slimming] conv pruning issue (#7) 感谢您的回答!现在我已可以跑通整个模型结构,是更改了fpn的输入尺寸和resnet的4个layer输出尺寸相同即可,然后还有一点疑问,就是slimpruner这个工具的参数移植在哪呀,而且我部分修改的网络从哪里进行筛选需要转移的参数,我知道需要大模型的剪枝部分的参数移植才能恢复较高的精度。 你好,请问你是直接修改了json文件里面的fpn的next_bn吗? — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

之前报了size_mismatch问题,我去掉了对fc层的剪枝,然后跑推理,速度提升了20%,但是mAP全部为0,请问你那边性能如何?

sungh66 commented 3 years ago

是的,4 里面的 pruned_model 直接finetune,然后保存到你喜欢的地方。5 是加载 finetune 好的剪枝模型的步骤,pruned_state_dict 需要你自己加载 4 里面 finetune 好的参数 所以就是其实步骤4就已经够了,5只是用来做迭代剪枝的创建模型的方式是吧。其实就是怕参数移植问题,我做了一些尺寸的修改,具体你可以看一下我回复dy1998的,我也是直接加载的原稀疏大模型,应该没问题吧。因为我这边精度恢复效果不太好,所以比较担心这点

Sanster commented 3 years ago

是的,4 里面的 pruned_model 直接finetune,然后保存到你喜欢的地方。5 是加载 finetune 好的剪枝模型的步骤,pruned_state_dict 需要你自己加载 4 里面 finetune 好的参数 所以就是其实步骤4就已经够了,5只是用来做迭代剪枝的创建模型的方式是吧。其实就是怕参数移植问题,我做了一些尺寸的修改,具体你可以看一下我回复dy1998的,我也是直接加载的原稀疏大模型,应该没问题吧。因为我这边精度恢复效果不太好,所以比较担心这点

如果只剪 backbone 的话,稀疏化训练的正则也应该只应用到 backbone 的参数上,这里可能要改下。你是 finetune 了多少步呢?我之前是训 DBNet,语义分割作文本检测,0.5 的剪枝率(backbone+fpn+head都剪了)基本是无损的

dy1998 commented 3 years ago

是的,4 里面的 pruned_model 直接finetune,然后保存到你喜欢的地方。5 是加载 finetune 好的剪枝模型的步骤,pruned_state_dict 需要你自己加载 4 里面 finetune 好的参数 所以就是其实步骤4就已经够了,5只是用来做迭代剪枝的创建模型的方式是吧。其实就是怕参数移植问题,我做了一些尺寸的修改,具体你可以看一下我回复dy1998的,我也是直接加载的原稀疏大模型,应该没问题吧。因为我这边精度恢复效果不太好,所以比较担心这点

如果只剪 backbone 的话,稀疏化训练的正则也应该只应用到 backbone 的参数上,这里可能要改下。你是 finetune 了多少步呢?我之前是训 DBNet,语义分割作文本检测,0.5 的剪枝率(backbone+fpn+head都剪了)基本是无损的

请问你一开始一定是稀疏化训练的吗?我是直接拿训练好的网络剪枝的

Sanster commented 3 years ago

是的,4 里面的 pruned_model 直接finetune,然后保存到你喜欢的地方。5 是加载 finetune 好的剪枝模型的步骤,pruned_state_dict 需要你自己加载 4 里面 finetune 好的参数 所以就是其实步骤4就已经够了,5只是用来做迭代剪枝的创建模型的方式是吧。其实就是怕参数移植问题,我做了一些尺寸的修改,具体你可以看一下我回复dy1998的,我也是直接加载的原稀疏大模型,应该没问题吧。因为我这边精度恢复效果不太好,所以比较担心这点

如果只剪 backbone 的话,稀疏化训练的正则也应该只应用到 backbone 的参数上,这里可能要改下。你是 finetune 了多少步呢?我之前是训 DBNet,语义分割作文本检测,0.5 的剪枝率(backbone+fpn+head都剪了)基本是无损的

请问你一开始一定是稀疏化训练的吗?我是直接拿训练好的网络剪枝的

。。。一定要稀疏化训练的

dy1998 commented 3 years ago

是的,4 里面的 pruned_model 直接finetune,然后保存到你喜欢的地方。5 是加载 finetune 好的剪枝模型的步骤,pruned_state_dict 需要你自己加载 4 里面 finetune 好的参数 所以就是其实步骤4就已经够了,5只是用来做迭代剪枝的创建模型的方式是吧。其实就是怕参数移植问题,我做了一些尺寸的修改,具体你可以看一下我回复dy1998的,我也是直接加载的原稀疏大模型,应该没问题吧。因为我这边精度恢复效果不太好,所以比较担心这点

如果只剪 backbone 的话,稀疏化训练的正则也应该只应用到 backbone 的参数上,这里可能要改下。你是 finetune 了多少步呢?我之前是训 DBNet,语义分割作文本检测,0.5 的剪枝率(backbone+fpn+head都剪了)基本是无损的

请问你一开始一定是稀疏化训练的吗?我是直接拿训练好的网络剪枝的

。。。一定要稀疏化训练的

感谢回答,主要我是在mmdet上改的,请问你当时dbnet是在mmocr上改的还是在官方的上面改的啊?

Sanster commented 3 years ago

detectron2。业务上用的话其实剪枝前可以直接试试mobilenet v3,可能就能满足需求了 。。

sungh66 commented 3 years ago

好像这个不能够真正生成小模型,从创建模型开始。实际上是创建了大模型然后赋值了保存的小模型的参数,好像不能实际部署啊

Sanster commented 3 years ago

部署有两种选择

  1. 剪枝 fine tune 完的小模型保存成 onnx,torchscript 或者 tensorrt 这种既保存网络结构也保存网络参数模型格式
  2. 像你说的「创建大模型然后赋值了保存的小模型的参数」
    • 创建大模型的时候是不需要原先模型的参数的,只要build好网络结构
    • 中间 pruner.apply_pruning_result 这一步会把大模型的参数剪掉,这样 pruner.pruned_model.load_state_dict 就能 load 小模型的参数
sungh66 commented 3 years ago

我想要的是直接创建小型的模型结构,而不是通过apply_pruning_result置零的方式,如何去通过index创建小模型结构有什么建议吗

Sanster commented 3 years ago

apply_pruning_result 不是置零,是真的修改了conv 的权重 https://github.com/Sanster/pytorch-network-slimming/blob/e3fd71d3d2d21b00acc03249cc83f15c7161a077/src/pns/functional.py#L62

sungh66 commented 3 years ago

嗯嗯,我知道实际修改了,但有没有可以直接在第一次创建模型的时候,在apply之前就是小模型的方法呢

Sanster commented 3 years ago

这样做目的是为了什么呢?据我所知没有,只能转 onnx,torchscript 这种。

sungh66 commented 3 years ago

就是如果第一次就直接创建大模型,然后在线prune就不太符合我的要求,想要的是直接创建小的模型,然后直接加载参数就够了,不需要prune_result这样的文件去加载和在线剪枝。我可以根据尺寸在创建模型的时候就直接创建独特的小模型吧

Sanster commented 3 years ago

可以的,要改 build 网络的代码,把每层 Conv/BN 的 channel 数传进去,类似原作者的 pytorch 实现 link

defaultcfg = {
    11 : [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512],
    13 : [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512],
    16 : [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512],
    19 : [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512],
}

class vgg(nn.Module):
    def __init__(self, dataset='cifar10', depth=19, init_weights=True, cfg=None):
        super(vgg, self).__init__()
        if cfg is None:
            cfg = defaultcfg[depth]

        self.feature = self.make_layers(cfg, True)
sungh66 commented 3 years ago

好的,感谢您耐心的讲解!!!