未验证 提交 ed1cb0ce 编写于 作者: R ruri 提交者: GitHub

Fix shufflenet v2 bug (#3855)

* fix shufflenet v2 bug
上级 e95aee9c
......@@ -20,15 +20,19 @@ import paddle.fluid as fluid
from paddle.fluid.initializer import MSRA
from paddle.fluid.param_attr import ParamAttr
__all__ = ['MobileNetV3','MobileNetV3_small_x0_25', 'MobileNetV3_small_x0_5', 'MobileNetV3_small_x0_75',
'MobileNetV3_small_x1_0', 'MobileNetV3_small_x1_25', 'MobileNetV3_large_x0_25', 'MobileNetV3_large_x0_5',
'MobileNetV3_large_x0_75', 'MobileNetV3_large_x1_0', 'MobileNetV3_large_x1_25']
__all__ = [
'MobileNetV3', 'MobileNetV3_small_x0_25', 'MobileNetV3_small_x0_5',
'MobileNetV3_small_x0_75', 'MobileNetV3_small_x1_0',
'MobileNetV3_small_x1_25', 'MobileNetV3_large_x0_25',
'MobileNetV3_large_x0_5', 'MobileNetV3_large_x0_75',
'MobileNetV3_large_x1_0', 'MobileNetV3_large_x1_25'
]
class MobileNetV3():
def __init__(self, scale=1.0, model_name='small'):
self.scale = scale
self.inplanes=16
self.inplanes = 16
if model_name == "large":
self.cfg = [
# k, exp, c, se, nl, s,
......@@ -47,7 +51,7 @@ class MobileNetV3():
[5, 672, 160, True, 'hard_swish', 2],
[5, 960, 160, True, 'hard_swish', 1],
[5, 960, 160, True, 'hard_swish', 1],
]
]
self.cls_ch_squeeze = 960
self.cls_ch_expand = 1280
elif model_name == "small":
......@@ -64,11 +68,12 @@ class MobileNetV3():
[5, 288, 96, True, 'hard_swish', 2],
[5, 576, 96, True, 'hard_swish', 1],
[5, 576, 96, True, 'hard_swish', 1],
]
]
self.cls_ch_squeeze = 576
self.cls_ch_expand = 1280
else:
raise NotImplementedError
raise NotImplementedError("mode[" + model_name +
"_model] is not implemented!")
def net(self, input, class_dim=1000):
scale = self.scale
......@@ -76,41 +81,45 @@ class MobileNetV3():
cfg = self.cfg
cls_ch_squeeze = self.cls_ch_squeeze
cls_ch_expand = self.cls_ch_expand
#conv1
conv = self.conv_bn_layer(input,
filter_size=3,
num_filters=int(scale*inplanes),
stride=2,
padding=1,
num_groups=1,
if_act=True,
act='hard_swish',
name='conv1')
conv = self.conv_bn_layer(
input,
filter_size=3,
num_filters=int(scale * inplanes),
stride=2,
padding=1,
num_groups=1,
if_act=True,
act='hard_swish',
name='conv1')
i = 0
for layer_cfg in cfg:
conv = self.residual_unit(input=conv,
num_in_filter=inplanes,
num_mid_filter=int(scale*layer_cfg[1]),
num_out_filter=int(scale*layer_cfg[2]),
act=layer_cfg[4],
stride=layer_cfg[5],
filter_size=layer_cfg[0],
use_se=layer_cfg[3],
name='conv' + str(i+2))
inplanes = int(scale*layer_cfg[2])
conv = self.residual_unit(
input=conv,
num_in_filter=inplanes,
num_mid_filter=int(scale * layer_cfg[1]),
num_out_filter=int(scale * layer_cfg[2]),
act=layer_cfg[4],
stride=layer_cfg[5],
filter_size=layer_cfg[0],
use_se=layer_cfg[3],
name='conv' + str(i + 2))
inplanes = int(scale * layer_cfg[2])
i += 1
conv = self.conv_bn_layer(input=conv,
filter_size=1,
num_filters=int(scale*cls_ch_squeeze),
stride=1,
padding=0,
num_groups=1,
if_act=True,
act='hard_swish',
name='conv_last')
conv = fluid.layers.pool2d(input=conv, pool_type='avg', global_pooling=True, use_cudnn=False)
conv = self.conv_bn_layer(
input=conv,
filter_size=1,
num_filters=int(scale * cls_ch_squeeze),
stride=1,
padding=0,
num_groups=1,
if_act=True,
act='hard_swish',
name='conv_last')
conv = fluid.layers.pool2d(
input=conv, pool_type='avg', global_pooling=True, use_cudnn=False)
conv = fluid.layers.conv2d(
input=conv,
num_filters=cls_ch_expand,
......@@ -127,21 +136,18 @@ class MobileNetV3():
param_attr=ParamAttr(name='fc_weights'),
bias_attr=ParamAttr(name='fc_offset'))
return out
def conv_bn_layer(self,
input,
filter_size,
num_filters,
stride,
padding,
num_groups=1,
if_act=True,
act=None,
name=None,
use_cudnn=True):
input,
filter_size,
num_filters,
stride,
padding,
num_groups=1,
if_act=True,
act=None,
name=None,
use_cudnn=True):
conv = fluid.layers.conv2d(
input=input,
num_filters=num_filters,
......@@ -151,73 +157,93 @@ class MobileNetV3():
groups=num_groups,
act=None,
use_cudnn=use_cudnn,
param_attr=ParamAttr(name=name+'_weights'),
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')
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 if_act:
if act == 'relu':
bn = fluid.layers.relu(bn)
elif act == 'hard_swish':
bn = self.hard_swish(bn)
return bn
def hard_swish(self, x):
return x * fluid.layers.relu6(x+3) / 6.
return x * fluid.layers.relu6(x + 3) / 6.
def se_block(self, input, num_out_filter, ratio=4, name=None):
num_mid_filter = int(num_out_filter // ratio)
pool = fluid.layers.pool2d(
input=input, pool_type='avg', global_pooling=True, use_cudnn=False)
conv1 = fluid.layers.conv2d(input=pool, filter_size=1, num_filters=num_mid_filter, act='relu',
param_attr=ParamAttr(name=name+'_1_weights'),
bias_attr=ParamAttr(name=name+'_1_offset'))
conv2 = fluid.layers.conv2d(input=conv1, filter_size=1, num_filters=num_out_filter, act='hard_sigmoid',
param_attr=ParamAttr(name=name+'_2_weights'),
bias_attr=ParamAttr(name=name+'_2_offset'))
conv1 = fluid.layers.conv2d(
input=pool,
filter_size=1,
num_filters=num_mid_filter,
act='relu',
param_attr=ParamAttr(name=name + '_1_weights'),
bias_attr=ParamAttr(name=name + '_1_offset'))
conv2 = fluid.layers.conv2d(
input=conv1,
filter_size=1,
num_filters=num_out_filter,
act='hard_sigmoid',
param_attr=ParamAttr(name=name + '_2_weights'),
bias_attr=ParamAttr(name=name + '_2_offset'))
scale = fluid.layers.elementwise_mul(x=input, y=conv2, axis=0)
return scale
def residual_unit(self, input, num_in_filter, num_mid_filter, num_out_filter, stride,
filter_size, act=None, use_se=False, name=None):
def residual_unit(self,
input,
num_in_filter,
num_mid_filter,
num_out_filter,
stride,
filter_size,
act=None,
use_se=False,
name=None):
first_conv = (num_out_filter != num_mid_filter)
input_data=input
input_data = input
if first_conv:
input = self.conv_bn_layer(input=input,
filter_size=1,
num_filters=num_mid_filter,
stride=1,
padding=0,
if_act=True,
act=act,
name=name + '_expand')
conv1 = self.conv_bn_layer(input=input,
filter_size=filter_size,
num_filters=num_mid_filter,
stride=stride,
padding=int((filter_size-1)//2),
if_act=True,
act=act,
num_groups=num_mid_filter,
use_cudnn=True,
name=name + '_depthwise')
input = self.conv_bn_layer(
input=input,
filter_size=1,
num_filters=num_mid_filter,
stride=1,
padding=0,
if_act=True,
act=act,
name=name + '_expand')
conv1 = self.conv_bn_layer(
input=input,
filter_size=filter_size,
num_filters=num_mid_filter,
stride=stride,
padding=int((filter_size - 1) // 2),
if_act=True,
act=act,
num_groups=num_mid_filter,
use_cudnn=True,
name=name + '_depthwise')
if use_se:
conv1 = self.se_block(input=conv1, num_out_filter=num_mid_filter, name=name+'_se')
conv2 = self.conv_bn_layer(input=conv1,
filter_size=1,
num_filters=num_out_filter,
stride=1,
padding=0,
if_act=False,
name=name + '_linear')
conv1 = self.se_block(
input=conv1, num_out_filter=num_mid_filter, name=name + '_se')
conv2 = self.conv_bn_layer(
input=conv1,
filter_size=1,
num_filters=num_out_filter,
stride=1,
padding=0,
if_act=False,
name=name + '_linear')
if num_in_filter != num_out_filter or stride != 1:
return conv2
else:
......@@ -225,41 +251,50 @@ class MobileNetV3():
def MobileNetV3_small_x0_25():
model=MobileNetV3(model_name='small', scale=0.25)
model = MobileNetV3(model_name='small', scale=0.25)
return model
def MobileNetV3_small_x0_5():
model=MobileNetV3(model_name='small', scale=0.5)
model = MobileNetV3(model_name='small', scale=0.5)
return model
def MobileNetV3_small_x0_75():
model=MobileNetV3(model_name='small', scale=0.75)
model = MobileNetV3(model_name='small', scale=0.75)
return model
def MobileNetV3_small_x1_0():
model=MobileNetV3(model_name='small', scale=1.0)
model = MobileNetV3(model_name='small', scale=1.0)
return model
def MobileNetV3_small_x1_25():
model=MobileNetV3(model_name='small', scale=1.25)
model = MobileNetV3(model_name='small', scale=1.25)
return model
def MobileNetV3_large_x0_25():
model=MobileNetV3(model_name='large', scale=0.25)
model = MobileNetV3(model_name='large', scale=0.25)
return model
def MobileNetV3_large_x0_5():
model=MobileNetV3(model_name='large', scale=0.5)
model = MobileNetV3(model_name='large', scale=0.5)
return model
def MobileNetV3_large_x0_75():
model=MobileNetV3(model_name='large', scale=0.75)
model = MobileNetV3(model_name='large', scale=0.75)
return model
def MobileNetV3_large_x1_0():
model=MobileNetV3(model_name='large', scale=1.0)
model = MobileNetV3(model_name='large', scale=1.0)
return model
def MobileNetV3_large_x1_25():
model=MobileNetV3(model_name='large', scale=1.25)
model = MobileNetV3(model_name='large', scale=1.25)
return model
......@@ -50,9 +50,8 @@ class ShuffleNetV2():
elif scale == 2.0:
stage_out_channels = [-1, 24, 224, 488, 976, 2048]
else:
raise ValueError("""{} groups is not supported for
1x1 Grouped Convolutions""".format(num_groups))
raise NotImplementedError("This scale size:[" + str(scale) +
"] is not implemented!")
#conv1
input_channel = stage_out_channels[1]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册