提交 faa73513 编写于 作者: C ceci3

update block

上级 51c23929
...@@ -87,9 +87,9 @@ class CombineSearchSpace(object): ...@@ -87,9 +87,9 @@ class CombineSearchSpace(object):
block_num = config['block_num'] if 'block_num' in config else None block_num = config['block_num'] if 'block_num' in config else None
if 'Block' in cls.__name__: if 'Block' in cls.__name__:
if block_mask == None and (self.block_num == None or if block_mask == None and (block_num == None or
self.input_size == None or input_size == None or
self.output_size == None): output_size == None):
raise NotImplementedError( raise NotImplementedError(
"block_mask or (block num and input_size and output_size) can NOT be None at the same time in Block SPACE!" "block_mask or (block num and input_size and output_size) can NOT be None at the same time in Block SPACE!"
) )
......
...@@ -22,6 +22,7 @@ from paddle.fluid.param_attr import ParamAttr ...@@ -22,6 +22,7 @@ from paddle.fluid.param_attr import ParamAttr
from .search_space_base import SearchSpaceBase from .search_space_base import SearchSpaceBase
from .base_layer import conv_bn_layer from .base_layer import conv_bn_layer
from .search_space_registry import SEARCHSPACE from .search_space_registry import SEARCHSPACE
from .utils import compute_downsample_num
__all__ = ["InceptionABlockSpace", "InceptionCBlockSpace"] __all__ = ["InceptionABlockSpace", "InceptionCBlockSpace"]
### TODO add asymmetric kernel of conv when paddle-lite support ### TODO add asymmetric kernel of conv when paddle-lite support
...@@ -70,7 +71,7 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -70,7 +71,7 @@ class InceptionABlockSpace(SearchSpaceBase):
if self.block_mask != None: if self.block_mask != None:
range_table_length = len(self.block_mask) range_table_length = len(self.block_mask)
else: else:
range_table_length = self.block_mum range_table_length = self.block_num
for i in range(range_table_length): for i in range(range_table_length):
range_table_base.append(len(self.filter_num)) range_table_base.append(len(self.filter_num))
...@@ -107,7 +108,7 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -107,7 +108,7 @@ class InceptionABlockSpace(SearchSpaceBase):
self.k_size[tokens[i * 9 + 7]], 2 if self.block_mask == 1 self.k_size[tokens[i * 9 + 7]], 2 if self.block_mask == 1
else 1, self.pool_type[tokens[i * 9 + 8]])) else 1, self.pool_type[tokens[i * 9 + 8]]))
else: else:
repeat_num = self.block_num / self.downsample_num repeat_num = int(self.block_num / self.downsample_num)
num_minus = self.block_num % self.downsample_num num_minus = self.block_num % self.downsample_num
### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers ### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers
for i in range(self.downsample_num): for i in range(self.downsample_num):
...@@ -136,7 +137,7 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -136,7 +137,7 @@ class InceptionABlockSpace(SearchSpaceBase):
self.pool_type[tokens[kk * 9 + 8]])) self.pool_type[tokens[kk * 9 + 8]]))
if self.downsample_num - i <= num_minus: if self.downsample_num - i <= num_minus:
j = self.downsample_num * repeat_num + i j = self.downsample_num * (repeat_num - 1) + i
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
(self.filter_num[tokens[j * 9]], (self.filter_num[tokens[j * 9]],
self.filter_num[tokens[j * 9 + 1]], self.filter_num[tokens[j * 9 + 1]],
...@@ -304,7 +305,7 @@ class InceptionCBlockSpace(SearchSpaceBase): ...@@ -304,7 +305,7 @@ class InceptionCBlockSpace(SearchSpaceBase):
if self.block_mask != None: if self.block_mask != None:
range_table_length = len(self.block_mask) range_table_length = len(self.block_mask)
else: else:
range_table_length = self.block_mum range_table_length = self.block_num
for i in range(range_table_length): for i in range(range_table_length):
range_table_base.append(len(self.filter_num)) range_table_base.append(len(self.filter_num))
...@@ -343,7 +344,7 @@ class InceptionCBlockSpace(SearchSpaceBase): ...@@ -343,7 +344,7 @@ class InceptionCBlockSpace(SearchSpaceBase):
self.k_size[tokens[i * 11 + 9]], 2 if self.block_mask == 1 self.k_size[tokens[i * 11 + 9]], 2 if self.block_mask == 1
else 1, self.pool_type[tokens[i * 11 + 10]])) else 1, self.pool_type[tokens[i * 11 + 10]]))
else: else:
repeat_num = self.block_num / self.downsample_num repeat_num = int(self.block_num / self.downsample_num)
num_minus = self.block_num % self.downsample_num num_minus = self.block_num % self.downsample_num
### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers ### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers
for i in range(self.downsample_num): for i in range(self.downsample_num):
...@@ -376,7 +377,7 @@ class InceptionCBlockSpace(SearchSpaceBase): ...@@ -376,7 +377,7 @@ class InceptionCBlockSpace(SearchSpaceBase):
self.pool_type[tokens[kk * 11 + 10]])) self.pool_type[tokens[kk * 11 + 10]]))
if self.downsample_num - i <= num_minus: if self.downsample_num - i <= num_minus:
j = self.downsample_num * repeat_num + i j = self.downsample_num * (repeat_num - 1) + i
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
(self.filter_num[tokens[j * 11]], (self.filter_num[tokens[j * 11]],
self.filter_num[tokens[j * 11 + 1]], self.filter_num[tokens[j * 11 + 1]],
......
...@@ -70,7 +70,7 @@ class MobileNetV2BlockSpace(SearchSpaceBase): ...@@ -70,7 +70,7 @@ class MobileNetV2BlockSpace(SearchSpaceBase):
if self.block_mask != None: if self.block_mask != None:
range_table_length = len(self.block_mask) range_table_length = len(self.block_mask)
else: else:
range_table_length = self.block_mum range_table_length = self.block_num
for i in range(range_table_length): for i in range(range_table_length):
range_table_base.append(len(self.multiply)) range_table_base.append(len(self.multiply))
...@@ -98,7 +98,7 @@ class MobileNetV2BlockSpace(SearchSpaceBase): ...@@ -98,7 +98,7 @@ class MobileNetV2BlockSpace(SearchSpaceBase):
if self.block_mask[i] == 1 else 1, if self.block_mask[i] == 1 else 1,
self.k_size[tokens[i * 4 + 3]])) self.k_size[tokens[i * 4 + 3]]))
else: else:
repeat_num = self.block_num / self.downsample_num repeat_num = int(self.block_num / self.downsample_num)
num_minus = self.block_num % self.downsample_num num_minus = self.block_num % self.downsample_num
### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers ### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers
for i in range(self.downsample_num): for i in range(self.downsample_num):
...@@ -118,7 +118,7 @@ class MobileNetV2BlockSpace(SearchSpaceBase): ...@@ -118,7 +118,7 @@ class MobileNetV2BlockSpace(SearchSpaceBase):
self.k_size[tokens[kk * 4 + 3]])) self.k_size[tokens[kk * 4 + 3]]))
if self.downsample_num - i <= num_minus: if self.downsample_num - i <= num_minus:
j = self.downsample_num * repeat_num + i j = self.downsample_num * (repeat_num - 1) + i
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
(self.multiply[tokens[j * 4]], (self.multiply[tokens[j * 4]],
self.filter_num[tokens[j * 4 + 1]], self.filter_num[tokens[j * 4 + 1]],
...@@ -343,9 +343,9 @@ class MobileNetV1BlockSpace(SearchSpaceBase): ...@@ -343,9 +343,9 @@ class MobileNetV1BlockSpace(SearchSpaceBase):
if self.block_mask[i] == 1 else 1, if self.block_mask[i] == 1 else 1,
self.k_size[tokens[i * 3 + 2]])) self.k_size[tokens[i * 3 + 2]]))
else: else:
repeat_num = self.block_num / self.downsample_num repeat_num = int(self.block_num / self.downsample_num)
num_minus = self.block_num % self.downsample_num num_minus = self.block_num % self.downsample_num
for i in range(self.block_num): for i in range(self.downsample_num):
### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers ### if block_num > downsample_num, add stride=1 block at last (block_num-downsample_num) layers
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
(self.filter_num[tokens[i * 3]], (self.filter_num[tokens[i * 3]],
...@@ -361,7 +361,7 @@ class MobileNetV1BlockSpace(SearchSpaceBase): ...@@ -361,7 +361,7 @@ class MobileNetV1BlockSpace(SearchSpaceBase):
self.k_size[tokens[kk * 3 + 2]])) self.k_size[tokens[kk * 3 + 2]]))
if self.downsample_num - i <= num_minus: if self.downsample_num - i <= num_minus:
j = self.downsample_num * repeat_num + i j = self.downsample_num * (repeat_num - 1) + i
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
(self.filter_num[tokens[j * 3]], (self.filter_num[tokens[j * 3]],
self.filter_num[tokens[j * 3 + 1]], 1, self.filter_num[tokens[j * 3 + 1]], 1,
...@@ -399,7 +399,7 @@ class MobileNetV1BlockSpace(SearchSpaceBase): ...@@ -399,7 +399,7 @@ class MobileNetV1BlockSpace(SearchSpaceBase):
if return_mid_layer: if return_mid_layer:
return input, mid_layer return input, mid_layer
else: else:
return input return input,
return net_arch return net_arch
...@@ -412,10 +412,17 @@ class MobileNetV1BlockSpace(SearchSpaceBase): ...@@ -412,10 +412,17 @@ class MobileNetV1BlockSpace(SearchSpaceBase):
kernel_size, kernel_size,
name=None): name=None):
num_groups = input.shape[1] num_groups = input.shape[1]
s_oc = int(num_filters1 * scale)
if s_oc > num_groups:
output_channel = s_oc - (s_oc % num_groups)
else:
output_channel = num_groups
depthwise_conv = conv_bn_layer( depthwise_conv = conv_bn_layer(
input=input, input=input,
filter_size=kernel_size, filter_size=kernel_size,
num_filters=int(num_filters1 * scale), num_filters=output_channel,
stride=stride, stride=stride,
num_groups=num_groups, num_groups=num_groups,
use_cudnn=False, use_cudnn=False,
......
...@@ -182,7 +182,7 @@ class MobileNetV1Space(SearchSpaceBase): ...@@ -182,7 +182,7 @@ class MobileNetV1Space(SearchSpaceBase):
name='mobilenetv1_conv1') name='mobilenetv1_conv1')
layer_count = 1 layer_count = 1
for i, layer_setting in enumerate(bottleneck_param_list): for i, layer_setting in enumerate(self.bottleneck_param_list):
filter_num1, filter_num2, stride, kernel_size = layer_setting filter_num1, filter_num2, stride, kernel_size = layer_setting
if stride == 2: if stride == 2:
layer_count += 1 layer_count += 1
...@@ -225,6 +225,14 @@ class MobileNetV1Space(SearchSpaceBase): ...@@ -225,6 +225,14 @@ class MobileNetV1Space(SearchSpaceBase):
scale, scale,
kernel_size, kernel_size,
name=None): name=None):
num_groups = input.shape[1]
s_oc = int(num_filters1 * scale)
if s_oc > num_groups:
output_channel = s_oc - (s_oc % num_groups)
else:
output_channel = num_groups
depthwise_conv = conv_bn_layer( depthwise_conv = conv_bn_layer(
input=input, input=input,
filter_size=kernel_size, filter_size=kernel_size,
......
...@@ -168,7 +168,7 @@ class MobileNetV2Space(SearchSpaceBase): ...@@ -168,7 +168,7 @@ class MobileNetV2Space(SearchSpaceBase):
depthwise_output = None depthwise_output = None
# bottleneck sequences # bottleneck sequences
in_c = int(32 * self.scale) in_c = int(32 * self.scale)
for layer_setting in self.bottleneck_params_list: for i, layer_setting in enumerate(self.bottleneck_params_list):
t, c, n, s, k = layer_setting t, c, n, s, k = layer_setting
if s == 2: if s == 2:
layer_count += 1 layer_count += 1
......
...@@ -40,26 +40,29 @@ class ResNetBlockSpace(SearchSpaceBase): ...@@ -40,26 +40,29 @@ class ResNetBlockSpace(SearchSpaceBase):
self.downsample_num, self.block_num) self.downsample_num, self.block_num)
self.filter_num = np.array( self.filter_num = np.array(
[48, 64, 96, 128, 160, 192, 224, 256, 320, 384, 512, 640]) [48, 64, 96, 128, 160, 192, 224, 256, 320, 384, 512, 640])
### TODO: use repeat to compute normal cell self.repeat = np.array([0, 1, 2])
#self.repeat = [2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24]
self.k_size = np.array([3, 5]) self.k_size = np.array([3, 5])
def init_tokens(self): def init_tokens(self):
if self.block_mask != None: if self.block_mask != None:
return [0] * (len(self.block_mask) * 2) return [0] * (len(self.block_mask) * 6)
else: else:
return [0] * (self.block_num * 2) return [0] * (self.block_num * 6)
def range_table(self): def range_table(self):
range_table_base = [] range_table_base = []
if self.block_mask != None: if self.block_mask != None:
range_table_length = len(self.block_mask) range_table_length = len(self.block_mask)
else: else:
range_table_length = self.block_mum range_table_length = self.block_num
for i in range(range_table_length): for i in range(range_table_length):
range_table_base.append(len(self.filter_num))
range_table_base.append(len(self.filter_num))
range_table_base.append(len(self.filter_num)) range_table_base.append(len(self.filter_num))
range_table_base.append(len(self.k_size)) range_table_base.append(len(self.k_size))
range_table_base.append(len(self.repeat))
range_table_base.append(len(self.repeat))
return range_table_base return range_table_base
...@@ -71,32 +74,52 @@ class ResNetBlockSpace(SearchSpaceBase): ...@@ -71,32 +74,52 @@ class ResNetBlockSpace(SearchSpaceBase):
if self.block_mask != None: if self.block_mask != None:
for i in range(len(self.block_mask)): for i in range(len(self.block_mask)):
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
(self.filter_num[tokens[i * 2]], (self.filter_num[tokens[i * 6]],
self.k_size[tokens[i * 2 + 1]], 2 self.filter_num[tokens[i * 6 + 1]],
self.filter_num[tokens[i * 6 + 2]],
self.k_size[tokens[i * 6 + 3]],
self.repeat[tokens[i * 6 + 4]],
self.repeat[tokens[i * 6 + 5]], 2
if self.block_mask[i] == 1 else 1)) if self.block_mask[i] == 1 else 1))
else: else:
repeat_num = self.block_num / self.downsample_num repeat_num = int(self.block_num / self.downsample_num)
num_minus = self.block_num % self.downsample_num num_minus = self.block_num % self.downsample_num
for i in range(self.downsample_num): for i in range(self.downsample_num):
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
self.filter_num[tokens[i * 2]], (self.filter_num[tokens[i * 6]],
self.k_size[tokens[i * 2 + 1]], 2) self.filter_num[tokens[i * 6 + 1]],
self.filter_num[tokens[i * 6 + 2]],
self.k_size[tokens[i * 6 + 3]],
self.repeat[tokens[i * 6 + 4]],
self.repeat[tokens[i * 6 + 5]], 2))
for k in range(repeat_num - 1): for k in range(repeat_num - 1):
kk = k * self.downsample_num + i kk = k * self.downsample_num + i
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
self.filter_num[tokens[kk * 2]], (self.filter_num[tokens[kk * 6]],
self.k_size[tokens[kk * 2 + 1]], 1) self.filter_num[tokens[kk * 6 + 1]],
self.filter_num[tokens[kk * 6 + 2]],
self.k_size[tokens[kk * 6 + 3]],
self.repeat[tokens[kk * 6 + 4]],
self.repeat[tokens[kk * 6 + 5]], 1))
if self.downsample_num - i <= num_minus: if self.downsample_num - i <= num_minus:
j = self.downsample_num * repeat_num + i j = self.downsample_num * (repeat_num - 1) + i
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
self.filter_num[tokens[j * 2]], (self.filter_num[tokens[j * 6]],
self.k_size[tokens[j * 2 + 1]], 1) self.filter_num[tokens[j * 6 + 1]],
self.filter_num[tokens[j * 6 + 2]],
self.k_size[tokens[j * 6 + 3]],
self.repeat[tokens[j * 6 + 4]],
self.repeat[tokens[j * 6 + 5]], 1))
if self.downsample_num == 0 and self.block_num != 0: if self.downsample_num == 0 and self.block_num != 0:
for i in range(len(self.block_num)): for i in range(len(self.block_num)):
self.bottleneck_params_list.append( self.bottleneck_params_list.append(
self.filter_num[tokens[i * 2]], (self.filter_num[tokens[i * 6]],
self.k_size[tokens[i * 2 + 1]], 1) self.filter_num[tokens[i * 6 + 1]],
self.filter_num[tokens[i * 6 + 2]],
self.k_size[tokens[i * 6 + 3]],
self.repeat[tokens[i * 6 + 4]],
self.repeat[tokens[i * 6 + 5]], 1))
def net_arch(input, return_mid_layer=False, return_block=[]): def net_arch(input, return_mid_layer=False, return_block=[]):
assert isinstance(return_block, assert isinstance(return_block,
...@@ -104,7 +127,7 @@ class ResNetBlockSpace(SearchSpaceBase): ...@@ -104,7 +127,7 @@ class ResNetBlockSpace(SearchSpaceBase):
layer_count = 0 layer_count = 0
mid_layer = dict() mid_layer = dict()
for i, layer_setting in enumerate(self.bottleneck_params_list): for i, layer_setting in enumerate(self.bottleneck_params_list):
filter_num, k_size, stride = layer_setting filter_num1, filter_num2, filter_num3, k_size, repeat1, repeat2, stride = layer_setting
if stride == 2: if stride == 2:
layer_count += 1 layer_count += 1
if (layer_count - 1) in return_block: if (layer_count - 1) in return_block:
...@@ -112,8 +135,12 @@ class ResNetBlockSpace(SearchSpaceBase): ...@@ -112,8 +135,12 @@ class ResNetBlockSpace(SearchSpaceBase):
input = self._bottleneck_block( input = self._bottleneck_block(
input=input, input=input,
num_filters=filter_num, num_filters1=filter_num1,
num_filters2=filter_num3,
num_filters3=filter_num3,
kernel_size=k_size, kernel_size=k_size,
repeat1=repeat1,
repeat2=repeat2,
stride=stride, stride=stride,
name='resnet' + str(i + 1)) name='resnet' + str(i + 1))
...@@ -138,33 +165,40 @@ class ResNetBlockSpace(SearchSpaceBase): ...@@ -138,33 +165,40 @@ class ResNetBlockSpace(SearchSpaceBase):
def _bottleneck_block(self, def _bottleneck_block(self,
input, input,
num_filters, num_filters1,
num_filters2,
num_filters3,
kernel_size, kernel_size,
repeat1,
repeat2,
stride, stride,
name=None): name=None):
conv0 = conv_bn_layer( short = self._shortcut(input, num_filters3, stride, name=name)
for i in range(repeat1):
input = conv_bn_layer(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters1,
filter_size=1, filter_size=1,
stride=1, stride=1,
act='relu', act='relu',
name=name + '_bottleneck_conv0') name=name + '_bottleneck_conv0_{}'.format(str(i)))
conv1 = conv_bn_layer(
input=conv0, input = conv_bn_layer(
num_filters=num_filters, input=input,
num_filters=num_filters2,
filter_size=kernel_size, filter_size=kernel_size,
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_bottleneck_conv1') name=name + '_bottleneck_conv1')
conv2 = conv_bn_layer( for i in range(repeat2):
input=conv1, input = conv_bn_layer(
num_filters=num_filters * 4, input=input,
num_filters=num_filters3,
filter_size=1, filter_size=1,
stride=1, stride=1,
act=None, act=None,
name=name + '_bottleneck_conv2') name=name + '_bottleneck_conv2_{}'.format(str(i)))
short = self._shortcut(input, num_filters * 4, stride, name=name)
return fluid.layers.elementwise_add( return fluid.layers.elementwise_add(
x=short, y=conv2, act='relu', name=name + '_bottleneck_add') x=short, y=input, act='relu', name=name + '_bottleneck_add')
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册