提交 e598cb9c 编写于 作者: C ceci3

add inception

上级 c5cc8ad1
...@@ -23,10 +23,9 @@ from .search_space_base import SearchSpaceBase ...@@ -23,10 +23,9 @@ 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
__all__ = [ __all__ = ["InceptionABlockSpace", "InceptionCBlockSpace"]
"InceptionABlockSpace", "InceptionBBlockSpace", "InceptionCBlockSpace"
]
### TODO add asymmetric kernel of conv when paddle-lite support ### TODO add asymmetric kernel of conv when paddle-lite support
### inceptionB is same as inceptionA if asymmetric kernel is not support
@SEARCHSPACE.register @SEARCHSPACE.register
...@@ -45,7 +44,7 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -45,7 +44,7 @@ class InceptionABlockSpace(SearchSpaceBase):
### self.filter_num means filter nums ### self.filter_num means filter nums
self.filter_num = np.array([ self.filter_num = np.array([
3, 4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 144, 160, 192, 224, 3, 4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 144, 160, 192, 224,
256, 320, 384, 480, 512, 1024 256, 320, 384, 448, 480, 512, 1024
]) ])
### self.k_size means kernel_size ### self.k_size means kernel_size
self.k_size = np.array([3, 5]) self.k_size = np.array([3, 5])
...@@ -161,7 +160,7 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -161,7 +160,7 @@ class InceptionABlockSpace(SearchSpaceBase):
input = self._inceptionA( input = self._inceptionA(
input, input,
layer_setting[0:7], A_tokens=filter_nums,
filter_size=filter_size, filter_size=filter_size,
stride=stride, stride=stride,
pool_type=pool_type, pool_type=pool_type,
...@@ -244,97 +243,184 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -244,97 +243,184 @@ class InceptionABlockSpace(SearchSpaceBase):
[conv1, conv2, conv3, conv4], axis=1, name=name + '_concat') [conv1, conv2, conv3, conv4], axis=1, name=name + '_concat')
return concat return concat
def _inceptionB(self,
data,
B_tokens=[0] * 7,
filter_size,
stride,
repeat,
name=None):
pool1 = fluid.layers.pool2d(
input=data,
pool_size=filter_size,
pool_padding='SAME',
pool_type='avg',
name=name + '_inceptionB_pool2d')
conv1 = conv_bn_layer(
input=pool1,
filter_size=1,
num_filters=B_tokens[0],
stride=stride,
act='relu',
name=name + '_inceptionB_conv1')
conv2 = conv_bn_layer( @SEARCHSPACE.register
input=data, class InceptionCBlockSpace(SearchSpaceBase):
filter_size=1, def __init__(self, input_size, output_size, block_num, block_mask):
num_filters=B_tokens[1], super(InceptionABlockSpace, self).__init__(input_size, output_size,
stride=stride, block_num, block_mask)
act='relu', if self.block_mask == None:
name=name + '_inceptionB_conv2') # use input_size and output_size to compute self.downsample_num
self.downsample_num = compute_downsample_num(self.input_size,
self.output_size)
if self.block_num != None:
assert self.downsample_num <= self.block_num, 'downsample numeber must be LESS THAN OR EQUAL TO block_num, but NOW: downsample numeber is {}, block_num is {}'.format(
self.downsample_num, self.block_num)
conv3 = conv_bn_layer( ### self.filter_num means filter nums
input=data, self.filter_num = np.array([
filter_size=1, 3, 4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 144, 160, 192, 224,
num_filters=B_tokens[2], 256, 320, 384, 448, 480, 512, 1024
stride=1, ])
act='relu', ### self.k_size means kernel_size
name=name + '_inceptionB_conv3_1') self.k_size = np.array([3, 5])
conv3 = conv_bn_layer( ### self.pool_type means pool type, 0 means avg, 1 means max
input=conv3, self.pool_type = np.array([0, 1])
filter_size=filter_size, ### self.repeat means repeat of 1x1 conv in branch of inception
num_filters=B_tokens[3], ### self.repeat = np.array([0,1])
stride=stride,
act='relu',
name=name + '_inceptionB_conv3_2')
conv4 = conv_bn_layer( def init_tokens(self):
input=data, """
filter_size=1, The initial token.
num_filters=B_tokens[4], """
stride=1, if self.block_mask != None:
act='relu', return [0] * (len(self.block_mask) * 9)
name=name + '_inceptionB_conv4_1') else:
conv4 = conv_bn_layer( return [0] * (self.block_num * 9)
input=conv4,
filter_size=filter_size, def range_table(self):
num_filters=B_tokens[5], """
stride=1, Get range table of current search space, constrains the range of tokens.
act='relu', """
name=name + '_inceptionB_conv4_2') range_table_base = []
conv4 = conv_bn_layer( if self.block_mask != None:
input=conv4, range_table_length = len(self.block_mask)
filter_size=filter_size, else:
num_filters=B_tokens[6], range_table_length = self.block_mum
stride=stride,
act='relu', for i in range(range_table_length):
name=name + '_inceptionB_conv4_3') range_table_base.append(len(self.filter_num))
concat = fluid.layers.concat( range_table_base.append(len(self.filter_num))
[conv1, conv2, conv3, conv4], range_table_base.append(len(self.filter_num))
axis=1, range_table_base.append(len(self.filter_num))
name=name + '_inceptionB_concat') range_table_base.append(len(self.filter_num))
return concat 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.pooltype))
return range_table_base
def token2arch(self, tokens=None):
"""
return net_arch function
"""
#assert self.block_num
if tokens is None:
tokens = self.init_tokens()
self.bottleneck_params_list = []
if self.block_mask != None:
for i in range(len(self.block_mask)):
self.bottleneck_params_list.append(
(self.filter_num[i * 11], self.filter_num[i * 11 + 1],
self.filter_num[i * 11 + 2], self.filter_num[i * 11 + 3],
self.filter_num[i * 11 + 4], self.filter_num[i * 11 + 5],
self.filter_num[i * 11 + 6], self.filter_num[i * 11 + 7],
self.filter_num[i * 11 + 8], self.k_size[i * 11 + 9], 2 if
self.block_mask == 1 else 1, self.pool_type[i * 11 + 10]))
else:
repeat_num = 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
for i in range(self.downsample_num):
self.bottleneck_params_list.append(
(self.filter_num[i * 11], self.filter_num[i * 11 + 1],
self.filter_num[i * 11 + 2], self.filter_num[i * 11 + 3],
self.filter_num[i * 11 + 4], self.filter_num[i * 11 + 5],
self.filter_num[i * 11 + 6], self.filter_num[i * 11 + 7],
self.filter_num[i * 11 + 8], self.k_size[i * 11 + 9], 2,
self.pool_type[i * 11 + 10]))
### if block_num / downsample_num > 1, add (block_num / downsample_num) times stride=1 block
for k in range(repeat_num - 1):
kk = k * self.downsample_num + i
self.bottleneck_params_list.append((
self.filter_num[kk * 11], self.filter_num[kk * 11 + 1],
self.filter_num[kk * 11 + 2],
self.filter_num[kk * 11 + 3],
self.filter_num[kk * 11 + 4],
self.filter_num[kk * 11 + 5],
self.filter_num[kk * 11 + 6],
self.filter_num[kk * 11 + 7],
self.filter_num[kk * 11 + 8], self.k_size[kk * 11 + 9],
1, self.pool_type[kk * 11 + 10]))
if self.downsample_num - i <= num_minus:
j = self.downsample_num * repeat_num + i
self.bottleneck_params_list.append(
(self.filter_num[j * 11], self.filter_num[j * 11 + 1],
self.filter_num[j * 11 + 2],
self.filter_num[j * 11 + 3],
self.filter_num[j * 11 + 4],
self.filter_num[j * 11 + 5],
self.filter_num[j * 11 + 6],
self.filter_num[j * 11 + 7],
self.filter_num[j * 11 + 8], self.k_size[j * 11 + 9],
1, self.pool_type[j * 11 + 10]))
if self.downsample_num == 0 and self.block_num != 0:
for i in range(len(self.block_num)):
self.bottleneck_params_list.append(
(self.filter_num[i * 11], self.filter_num[i * 11 + 1],
self.filter_num[i * 11 + 2],
self.filter_num[i * 11 + 3],
self.filter_num[i * 11 + 4],
self.filter_num[i * 11 + 5],
self.filter_num[i * 11 + 6],
self.filter_num[i * 11 + 7],
self.filter_num[i * 11 + 8], self.k_size[i * 11 + 9],
1, self.pool_type[i * 11 + 10]))
def net_arch(input, return_mid_layer=False, return_block=[]):
assert isinstance(return_block,
list), 'return_block must be a list.'
layer_count = 0
mid_layer = dict()
for i, layer_setting in enumerate(self.bottleneck_params_list):
filter_nums = layer_setting[0:9]
filter_size = layer_setting[9]
stride = layer_setting[10]
pool_type = 'avg' if layer_setting[11] == 0 else 'max'
if stride == 2:
layer_count += 1
if (layer_count - 1) in return_block:
mid_layer[layer_count - 1] = input
input = self._inceptionC(
input,
C_tokens=filter_nums,
filter_size=filter_size,
stride=stride,
pool_type=pool_type,
name='inceptionC_{}'.format(i + 1))
if return_mid_layer:
return input, mid_layer
else:
return input
return net_arch
def _inceptionC(self, def _inceptionC(self,
data, data,
C_tokens=[0] * 9, C_tokens,
filter_size, filter_size,
stride, stride,
repeat, pool_type,
name=None): name=None):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, input=data,
pool_size=filter_size, pool_size=filter_size,
pool_padding='SAME', pool_padding='SAME',
pool_type='avg', pool_type=pool_type,
name=name + '_inceptionC_pool2d') name=name + '_pool2d')
conv1 = conv_bn_layer( conv1 = conv_bn_layer(
input=pool1, input=pool1,
filter_size=1, filter_size=1,
num_filters=C_tokens[0], num_filters=C_tokens[0],
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_inceptionC_conv1') name=name + '_conv1')
conv2 = conv_bn_layer( conv2 = conv_bn_layer(
input=data, input=data,
...@@ -342,7 +428,7 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -342,7 +428,7 @@ class InceptionABlockSpace(SearchSpaceBase):
num_filters=C_tokens[1], num_filters=C_tokens[1],
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_inceptionC_conv2') name=name + '_conv2')
conv3 = conv_bn_layer( conv3 = conv_bn_layer(
input=data, input=data,
...@@ -350,21 +436,21 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -350,21 +436,21 @@ class InceptionABlockSpace(SearchSpaceBase):
num_filters=C_tokens[2], num_filters=C_tokens[2],
stride=1, stride=1,
act='relu', act='relu',
name=name + '_inceptionC_conv3_1') name=name + '_conv3_1')
conv3_1 = conv_bn_layer( conv3_1 = conv_bn_layer(
input=conv3, input=conv3,
filter_size=filter_size, filter_size=filter_size,
num_filters=C_tokens[3], num_filters=C_tokens[3],
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_inceptionC_conv3_2_1') name=name + '_conv3_2_1')
conv3_2 = conv_bn_layer( conv3_2 = conv_bn_layer(
input=conv3, input=conv3,
filter_size=filter_size, filter_size=filter_size,
num_filters=C_tokens[4], num_filters=C_tokens[4],
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_inceptionC_conv3_2_2') name=name + '_conv3_2_2')
conv4 = conv_bn_layer( conv4 = conv_bn_layer(
input=data, input=data,
...@@ -372,31 +458,31 @@ class InceptionABlockSpace(SearchSpaceBase): ...@@ -372,31 +458,31 @@ class InceptionABlockSpace(SearchSpaceBase):
num_filters=C_tokens[5], num_filters=C_tokens[5],
stride=1, stride=1,
act='relu', act='relu',
name=name + '_inceptionC_conv4_1') name=name + '_conv4_1')
conv4 = conv_bn_layer( conv4 = conv_bn_layer(
input=conv4, input=conv4,
filter_size=filter_size, filter_size=filter_size,
num_filters=C_tokens[6], num_filters=C_tokens[6],
stride=1, stride=1,
act='relu', act='relu',
name=name + '_inceptionC_conv4_2') name=name + '_conv4_2')
conv4_1 = conv_bn_layer( conv4_1 = conv_bn_layer(
input=conv4, input=conv4,
filter_size=filter_size, filter_size=filter_size,
num_filters=C_tokens[7], num_filters=C_tokens[7],
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_inceptionC_conv4_3_1') name=name + '_conv4_3_1')
conv4_2 = conv_bn_layer( conv4_2 = conv_bn_layer(
input=conv4, input=conv4,
filter_size=filter_size, filter_size=filter_size,
num_filters=C_tokens[8], num_filters=C_tokens[8],
stride=stride, stride=stride,
act='relu', act='relu',
name=name + '_inceptionC_conv4_3_2') name=name + '_conv4_3_2')
concat = fluid.layers.concat( concat = fluid.layers.concat(
[conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], [conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2],
axis=1, axis=1,
name=name + '_inceptionC_concat') name=name + '_concat')
return concat return concat
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册