From b8c5848d5b6aba1b2facb4f3930f324f655c7635 Mon Sep 17 00:00:00 2001 From: ceci3 <592712189@qq.com> Date: Wed, 13 Nov 2019 13:11:53 +0000 Subject: [PATCH] add resnet --- paddleslim/nas/search_space/base_layer.py | 21 ++--- paddleslim/nas/search_space/resnet.py | 93 ++++++++++++++++++----- 2 files changed, 81 insertions(+), 33 deletions(-) diff --git a/paddleslim/nas/search_space/base_layer.py b/paddleslim/nas/search_space/base_layer.py index 2e769ec6..b497c92a 100644 --- a/paddleslim/nas/search_space/base_layer.py +++ b/paddleslim/nas/search_space/base_layer.py @@ -20,7 +20,7 @@ def conv_bn_layer(input, filter_size, num_filters, stride, - padding, + padding='SAME', num_groups=1, act=None, name=None, @@ -51,15 +51,10 @@ def conv_bn_layer(input, param_attr=ParamAttr(name=name + '_weights'), bias_attr=False) bn_name = name + '_bn' - bn = fluid.layers.batch_norm( - input=conv, - param_attr=ParamAttr(name=bn_name + '_scale'), - bias_attr=ParamAttr(name=bn_name + '_offset'), - moving_mean_name=bn_name + '_mean', - moving_variance_name=bn_name + '_variance') - if act == 'relu6': - return fluid.layers.relu6(bn) - elif act == 'sigmoid': - return fluid.layers.sigmoid(bn) - else: - return bn + return fluid.layers.batch_norm( + input=conv, + act = act, + param_attr=ParamAttr(name=bn_name + '_scale'), + bias_attr=ParamAttr(name=bn_name + '_offset'), + moving_mean_name=bn_name + '_mean', + moving_variance_name=bn_name + '_variance') diff --git a/paddleslim/nas/search_space/resnet.py b/paddleslim/nas/search_space/resnet.py index 7ed404e5..e4e29d1f 100644 --- a/paddleslim/nas/search_space/resnet.py +++ b/paddleslim/nas/search_space/resnet.py @@ -28,35 +28,88 @@ __all__ = ["ResNetSpace"] @SEARCHSPACE.register class ResNetSpace(SearchSpaceBase): - def __init__(self, - input_size, - output_size, - block_num, - scale=1.0, - class_dim=1000): + def __init__(self, input_size, output_size, block_num, extract_feature=False, class_dim=1000): super(ResNetSpace, self).__init__(input_size, output_size, block_num) - pass + self.filter_num1 = np.array([48,64,96,128,160,192,224]) #7 + self.filter_num2 = np.array([64,96,128,160,192,256,320]) #7 + self.filter_num3 = np.array([128,160,192,256,320,384]) #6 + self.filter_num4 = np.array([192,256,384,512,640]) #5 + self.repeat1 = [2,3,4,5,6]#5 + self.repeat2 = [2,3,4,5,6,7]#6 + self.repeat3 = [2,3,4,5,6,7,8,10,12,14,16,20,24]#13 + self.repeat4 = [2,3,4,5,6,7]#6 + self.class_dim = class_dim + self.extract_feature = extract_feature + def init_tokens(self): - return [0, 0, 0, 0, 0, 0] + init_token_base = [0,0,0,0,0,0,0,0] + self.token_len = self.block_num * 2 + return init_token_base[:self.token_len] def range_table(self): - return [2, 2, 2, 2, 2, 2] + range_table_base = [3,3,3,3,3,3,3,3] + return range_table_base[:self.token_len] + + def token2arch(self,tokens=None): + assert self.block_num < 5, 'block number must less than 5, but receive block number is {}'.format(self.block_num) - def token2arch(self, tokens=None): if tokens is None: - self.init_tokens() + tokens = self.init_tokens() def net_arch(input): - input = conv_bn_layer( - input, - num_filters=32, - filter_size=3, - stride=2, - padding='SAME', - act='sigmoid', - name='resnet_conv1_1') + depth = [] + num_filters = [] + if self.block_num <= 1: + filter1 = self.filter_num1[tokens[0]] + repeat1 = self.repeat1[tokens[1]] + depth.append(filter1) + num_filters.append(repeat1) + if self.block_num <= 2: + filter2 = self.filter_num2[tokens[2]] + repeat2 = self.repeat2[tokens[3]] + depth.append(filter2) + num_filters.append(repeat2) + if self.block_num <= 3: + filter3 = self.filter_num3[tokens[4]] + repeat3 = self.repeat3[tokens[5]] + depth.append(filter3) + num_filters.append(repeat3) + if self.block_num <= 4: + filter4 = self.filter_num4[tokens[6]] + repeat4 = self.repeat4[tokens[7]] + depth.append(filter4) + num_filters.append(repeat4) - return input + conv = conv_bn_layer(input=input, filter_size=5, num_filters=filter1, stride=2, act='relu') + for block in range(len(depth)): + for i in range(depth[block]): + conv = self._basicneck_block(input=conv, num_filters=num_filters[block], stride=2 if i == 0 and block != 0 else 1) + + if self.output_size == 1: + conv = fluid.layers.fc( + input=conv, + size=self.class_dim, + act=None, + param_attr=fluid.param_attr.ParamAttr( + initializer=fluid.initializer.NormalInitializer(0.0,0.01)), + bias_attr=fluid.param_attr.ParamAttr( + initializer=fluid.initializer.ConstantInitializer())) + + return conv return net_arch + + def _shortcut(self, input, ch_out, stride): + ch_in = input.shape[1] + if ch_in != ch_out or stride != 1: + return conv_bn_layer(input=input, filter_size=1, num_filters=ch_out, stride=stride) + else: + return input + + def _basicneck_block(self, input, num_filters, stride): + conv0 = conv_bn_layer(input=input, filter_size=3, num_filters=num_filters, stride=stride, act='relu') + conv1 = conv_bn_layer(input=conv0, filter_size=3, num_filters=num_filters, stride=1, act=None) + short = self._shortcut(input, num_filters, stride) + return fluid.layers.elementwise_add(x=short, y=conv1, act='relu') + -- GitLab