未验证 提交 6a359a7a 编写于 作者: L lijianshe02 提交者: GitHub

add FPGM pruning algorithm's implementation test=develop (#172)

上级 b45a4b66
...@@ -156,8 +156,7 @@ def _reader_creator(file_list, ...@@ -156,8 +156,7 @@ def _reader_creator(file_list,
for line in lines: for line in lines:
if mode == 'train' or mode == 'val': if mode == 'train' or mode == 'val':
img_path, label = line.split() img_path, label = line.split()
img_path = os.path.join( img_path = os.path.join(data_dir, img_path)
os.path.join(data_dir, mode), img_path)
yield img_path, int(label) yield img_path, int(label)
elif mode == 'test': elif mode == 'test':
img_path = os.path.join(data_dir, line) img_path = os.path.join(data_dir, line)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
import logging import logging
import sys import sys
import numpy as np import numpy as np
from functools import reduce
import paddle.fluid as fluid import paddle.fluid as fluid
import copy import copy
from ..core import VarWrapper, OpWrapper, GraphWrapper from ..core import VarWrapper, OpWrapper, GraphWrapper
...@@ -152,6 +153,27 @@ class Pruner(): ...@@ -152,6 +153,27 @@ class Pruner():
reduce_dims = [i for i in range(len(param_t.shape)) if i != axis] reduce_dims = [i for i in range(len(param_t.shape)) if i != axis]
criterions = np.sum(np.abs(param_t), axis=tuple(reduce_dims)) criterions = np.sum(np.abs(param_t), axis=tuple(reduce_dims))
pruned_idx = criterions.argsort()[:prune_num] pruned_idx = criterions.argsort()[:prune_num]
elif self.criterion == 'geometry_median':
param_t = np.array(scope.find_var(param).get_tensor())
prune_num = int(round(param_t.shape[axis] * ratio))
def get_distance_sum(param, out_idx):
w = param.view()
reduce_dims = reduce(lambda x, y: x * y, param.shape[1:])
w.shape = param.shape[0], reduce_dims
selected_filter = np.tile(w[out_idx], (w.shape[0], 1))
x = w - selected_filter
x = np.sqrt(np.sum(x * x, -1))
return x.sum()
dist_sum_list = []
for out_i in range(param_t.shape[0]):
dist_sum = get_distance_sum(param_t, out_i)
dist_sum_list.append((dist_sum, out_i))
min_gm_filters = sorted(
dist_sum_list, key=lambda x: x[0])[:prune_num]
pruned_idx = [x[1] for x in min_gm_filters]
elif self.criterion == "batch_norm_scale": elif self.criterion == "batch_norm_scale":
param_var = graph.var(param) param_var = graph.var(param)
conv_op = param_var.outputs()[0] conv_op = param_var.outputs()[0]
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
sys.path.append("../")
import unittest
import paddle.fluid as fluid
from paddleslim.prune import Pruner
from layers import conv_bn_layer
class TestPrune(unittest.TestCase):
def test_prune(self):
main_program = fluid.Program()
startup_program = fluid.Program()
# X X O X O
# conv1-->conv2-->sum1-->conv3-->conv4-->sum2-->conv5-->conv6
# | ^ | ^
# |____________| |____________________|
#
# X: prune output channels
# O: prune input channels
with fluid.program_guard(main_program, startup_program):
input = fluid.data(name="image", shape=[None, 3, 16, 16])
conv1 = conv_bn_layer(input, 8, 3, "conv1")
conv2 = conv_bn_layer(conv1, 8, 3, "conv2")
sum1 = conv1 + conv2
conv3 = conv_bn_layer(sum1, 8, 3, "conv3")
conv4 = conv_bn_layer(conv3, 8, 3, "conv4")
sum2 = conv4 + sum1
conv5 = conv_bn_layer(sum2, 8, 3, "conv5")
conv6 = conv_bn_layer(conv5, 8, 3, "conv6")
shapes = {}
for param in main_program.global_block().all_parameters():
shapes[param.name] = param.shape
place = fluid.CPUPlace()
exe = fluid.Executor(place)
scope = fluid.Scope()
exe.run(startup_program, scope=scope)
criterion = 'geometry_median'
pruner = Pruner(criterion)
main_program, _, _ = pruner.prune(
main_program,
scope,
params=["conv4_weights"],
ratios=[0.5],
place=place,
lazy=False,
only_graph=False,
param_backup=None,
param_shape_backup=None)
shapes = {
"conv1_weights": (4L, 3L, 3L, 3L),
"conv2_weights": (4L, 4L, 3L, 3L),
"conv3_weights": (8L, 4L, 3L, 3L),
"conv4_weights": (4L, 8L, 3L, 3L),
"conv5_weights": (8L, 4L, 3L, 3L),
"conv6_weights": (8L, 8L, 3L, 3L)
}
for param in main_program.global_block().all_parameters():
if "weights" in param.name:
print("param: {}; param shape: {}".format(param.name,
param.shape))
self.assertTrue(param.shape == shapes[param.name])
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册