fpgm_pruner.py 1.9 KB
Newer Older
W
whs 已提交
1 2 3
import logging
import numpy as np
import paddle
4
from paddleslim.common import get_logger
W
whs 已提交
5 6 7 8 9 10 11 12 13 14
from .var_group import *
from .pruning_plan import *
from .filter_pruner import FilterPruner

__all__ = ['FPGMFilterPruner']

_logger = get_logger(__name__, logging.INFO)


class FPGMFilterPruner(FilterPruner):
W
whs 已提交
15 16
    def __init__(self, model, inputs, sen_file=None):
        super(FPGMFilterPruner, self).__init__(model, inputs, sen_file=sen_file)
W
whs 已提交
17

W
whs 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30
    def cal_mask(self, pruned_ratio, collection):
        var_name = collection.master_name
        pruned_axis = collection.master_axis
        value = collection.values[var_name]
        groups = 1
        for _detail in collection.all_pruning_details():
            assert (isinstance(_detail.axis, int))
            if _detail.axis == 1:
                _groups = _detail.op.attr('groups')
                if _groups is not None and _groups > 1:
                    groups = _groups
                    break

W
whs 已提交
31 32 33 34 35 36
        dist_sum_list = []
        for out_i in range(value.shape[0]):
            dist_sum = self.get_distance_sum(value, out_i)
            dist_sum_list.append(dist_sum)
        scores = np.array(dist_sum_list)

W
whs 已提交
37 38 39 40
        if groups > 1:
            scores = scores.reshape([groups, -1])
            scores = np.mean(scores, axis=1)

W
whs 已提交
41 42 43
        sorted_idx = scores.argsort()
        pruned_num = int(round(len(sorted_idx) * pruned_ratio))
        pruned_idx = sorted_idx[:pruned_num]
W
whs 已提交
44
        mask_shape = [value.shape[pruned_axis]]
W
whs 已提交
45
        mask = np.ones(mask_shape, dtype="int32")
W
whs 已提交
46 47
        if groups > 1:
            mask = mask.reshape([groups, -1])
W
whs 已提交
48
        mask[pruned_idx] = 0
W
whs 已提交
49
        return mask.reshape(mask_shape)
W
whs 已提交
50 51 52 53 54 55 56 57

    def get_distance_sum(self, value, out_idx):
        w = value.view()
        w.shape = value.shape[0], np.product(value.shape[1:])
        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()