Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleClas
提交
7f80e25c
P
PaddleClas
项目概览
PaddlePaddle
/
PaddleClas
大约 1 年 前同步成功
通知
115
Star
4999
Fork
1114
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
19
列表
看板
标记
里程碑
合并请求
6
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleClas
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
19
Issue
19
列表
看板
标记
里程碑
合并请求
6
合并请求
6
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7f80e25c
编写于
7月 31, 2020
作者:
C
cuicheng01
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add mobilenet, resnet and senet series dymodels
上级
0e7bea51
变更
15
展开全部
隐藏空白更改
内联
并排
Showing
15 changed file
with
2916 addition
and
2692 deletion
+2916
-2692
ppcls/modeling/architectures/__init__.py
ppcls/modeling/architectures/__init__.py
+14
-2
ppcls/modeling/architectures/mobilenet_v1.py
ppcls/modeling/architectures/mobilenet_v1.py
+217
-166
ppcls/modeling/architectures/mobilenet_v2.py
ppcls/modeling/architectures/mobilenet_v2.py
+182
-163
ppcls/modeling/architectures/mobilenet_v3.py
ppcls/modeling/architectures/mobilenet_v3.py
+240
-218
ppcls/modeling/architectures/res2net.py
ppcls/modeling/architectures/res2net.py
+213
-158
ppcls/modeling/architectures/res2net_vd.py
ppcls/modeling/architectures/res2net_vd.py
+216
-207
ppcls/modeling/architectures/resnet.py
ppcls/modeling/architectures/resnet.py
+154
-56
ppcls/modeling/architectures/resnet_vc.py
ppcls/modeling/architectures/resnet_vc.py
+255
-136
ppcls/modeling/architectures/resnet_vd.py
ppcls/modeling/architectures/resnet_vd.py
+256
-241
ppcls/modeling/architectures/resnext.py
ppcls/modeling/architectures/resnext.py
+177
-130
ppcls/modeling/architectures/resnext_vd.py
ppcls/modeling/architectures/resnext_vd.py
+202
-190
ppcls/modeling/architectures/se_resnet_vd.py
ppcls/modeling/architectures/se_resnet_vd.py
+297
-249
ppcls/modeling/architectures/se_resnext_vd.py
ppcls/modeling/architectures/se_resnext_vd.py
+245
-283
ppcls/modeling/architectures/shufflenet_v2.py
ppcls/modeling/architectures/shufflenet_v2.py
+248
-200
ppcls/modeling/architectures/shufflenet_v2_swish.py
ppcls/modeling/architectures/shufflenet_v2_swish.py
+0
-293
未找到文件。
ppcls/modeling/architectures/__init__.py
浏览文件 @
7f80e25c
...
@@ -12,7 +12,19 @@
...
@@ -12,7 +12,19 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
from
.resnet_name
import
*
from
.resnet
import
ResNet18
,
ResNet34
,
ResNet50
,
ResNet101
,
ResNet152
from
.resnet_vc
import
ResNet18_vc
,
ResNet34_vc
,
ResNet50_vc
,
ResNet101_vc
,
ResNet152_vc
from
.resnet_vd
import
ResNet18_vd
,
ResNet34_vd
,
ResNet50_vd
,
ResNet101_vd
,
ResNet152_vd
,
ResNet200_vd
from
.resnext
import
ResNeXt50_32x4d
,
ResNeXt50_64x4d
,
ResNeXt101_32x4d
,
ResNeXt101_64x4d
,
ResNeXt152_32x4d
,
ResNeXt152_64x4d
from
.resnext_vd
import
ResNeXt50_vd_32x4d
,
ResNeXt50_vd_64x4d
,
ResNeXt101_vd_32x4d
,
ResNeXt101_vd_64x4d
,
ResNeXt152_vd_32x4d
,
ResNeXt152_vd_64x4d
from
.res2net
import
Res2Net50_48w_2s
,
Res2Net50_26w_4s
,
Res2Net50_14w_8s
,
Res2Net50_48w_2s
,
Res2Net50_26w_6s
,
Res2Net50_26w_8s
,
Res2Net101_26w_4s
,
Res2Net152_26w_4s
,
Res2Net200_26w_4s
from
.res2net_vd
import
Res2Net50_vd_48w_2s
,
Res2Net50_vd_26w_4s
,
Res2Net50_vd_14w_8s
,
Res2Net50_vd_48w_2s
,
Res2Net50_vd_26w_6s
,
Res2Net50_vd_26w_8s
,
Res2Net101_vd_26w_4s
,
Res2Net152_vd_26w_4s
,
Res2Net200_vd_26w_4s
from
.se_resnet_vd
import
SE_ResNet18_vd
,
SE_ResNet34_vd
,
SE_ResNet50_vd
,
SE_ResNet101_vd
,
SE_ResNet152_vd
,
SE_ResNet200_vd
from
.se_resnext_vd
import
SE_ResNeXt50_vd_32x4d
,
SE_ResNeXt50_vd_32x4d
,
SENet154_vd
from
.dpn
import
DPN68
from
.dpn
import
DPN68
from
.densenet
import
DenseNet121
from
.densenet
import
DenseNet121
from
.hrnet
import
HRNet_W18_C
from
.hrnet
import
HRNet_W18_C
\ No newline at end of file
from
.mobilenet_v1
import
MobileNetV1_x0_25
,
MobileNetV1_x0_5
,
MobileNetV1_x0_75
,
MobileNetV1
from
.mobilenet_v2
import
MobileNetV2_x0_25
,
MobileNetV2_x0_5
,
MobileNetV2_x0_75
,
MobileNetV2
,
MobileNetV2_x1_5
,
MobileNetV2_x2_0
from
.mobilenet_v3
import
MobileNetV3_small_x0_35
,
MobileNetV3_small_x0_5
,
MobileNetV3_small_x0_75
,
MobileNetV3_small_x1_0
,
MobileNetV3_small_x1_25
,
MobileNetV3_large_x0_35
,
MobileNetV3_large_x0_5
,
MobileNetV3_large_x0_75
,
MobileNetV3_large_x1_0
,
MobileNetV3_large_x1_25
from
.shufflenet_v2
import
ShuffleNetV2_x0_25
,
ShuffleNetV2_x0_33
,
ShuffleNetV2_x0_5
,
ShuffleNetV2
,
ShuffleNetV2_x1_5
,
ShuffleNetV2_x2_0
,
ShuffleNetV2_swish
ppcls/modeling/architectures/mobilenet_v1.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
numpy
as
np
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.initializer
import
MSRA
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
from
paddle.fluid.initializer
import
MSRA
import
math
__all__
=
[
__all__
=
[
'MobileNetV1'
,
'MobileNetV1_x0_25'
,
'MobileNetV1_x0_5'
,
'MobileNetV1_x1_0'
,
"MobileNetV1_x0_25"
,
"MobileNetV1_x0_5"
,
"MobileNetV1_x0_75"
,
"MobileNetV1"
'MobileNetV1_x0_75'
]
]
class
MobileNetV1
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
scale
=
1.0
):
def
__init__
(
self
,
self
.
scale
=
scale
num_channels
,
filter_size
,
def
net
(
self
,
input
,
class_dim
=
1000
):
num_filters
,
scale
=
self
.
scale
stride
,
# conv1: 112x112
padding
,
input
=
self
.
conv_bn_layer
(
channels
=
None
,
input
,
num_groups
=
1
,
filter_size
=
3
,
act
=
'relu'
,
channels
=
3
,
use_cudnn
=
True
,
num_filters
=
int
(
32
*
scale
),
name
=
None
):
stride
=
2
,
super
(
ConvBNLayer
,
self
).
__init__
()
padding
=
1
,
name
=
"conv1"
)
# 56x56
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
32
,
num_filters2
=
64
,
num_groups
=
32
,
stride
=
1
,
scale
=
scale
,
name
=
"conv2_1"
)
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
64
,
num_filters2
=
128
,
num_groups
=
64
,
stride
=
2
,
scale
=
scale
,
name
=
"conv2_2"
)
# 28x28
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
128
,
num_filters2
=
128
,
num_groups
=
128
,
stride
=
1
,
scale
=
scale
,
name
=
"conv3_1"
)
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
128
,
num_filters2
=
256
,
num_groups
=
128
,
stride
=
2
,
scale
=
scale
,
name
=
"conv3_2"
)
# 14x14
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
256
,
num_filters2
=
256
,
num_groups
=
256
,
stride
=
1
,
scale
=
scale
,
name
=
"conv4_1"
)
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
256
,
num_filters2
=
512
,
num_groups
=
256
,
stride
=
2
,
scale
=
scale
,
name
=
"conv4_2"
)
# 14x14
self
.
_conv
=
Conv2D
(
for
i
in
range
(
5
):
num_channels
=
num_channels
,
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
512
,
num_filters2
=
512
,
num_groups
=
512
,
stride
=
1
,
scale
=
scale
,
name
=
"conv5"
+
"_"
+
str
(
i
+
1
))
# 7x7
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
512
,
num_filters2
=
1024
,
num_groups
=
512
,
stride
=
2
,
scale
=
scale
,
name
=
"conv5_6"
)
input
=
self
.
depthwise_separable
(
input
,
num_filters1
=
1024
,
num_filters2
=
1024
,
num_groups
=
1024
,
stride
=
1
,
scale
=
scale
,
name
=
"conv6"
)
input
=
fluid
.
layers
.
pool2d
(
input
=
input
,
pool_type
=
'avg'
,
global_pooling
=
True
)
output
=
fluid
.
layers
.
fc
(
input
=
input
,
size
=
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
MSRA
(),
name
=
"fc7_weights"
),
bias_attr
=
ParamAttr
(
name
=
"fc7_offset"
))
return
output
def
conv_bn_layer
(
self
,
input
,
filter_size
,
num_filters
,
stride
,
padding
,
channels
=
None
,
num_groups
=
1
,
act
=
'relu'
,
use_cudnn
=
True
,
name
=
None
):
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
...
@@ -161,58 +56,214 @@ class MobileNetV1():
...
@@ -161,58 +56,214 @@ class MobileNetV1():
param_attr
=
ParamAttr
(
param_attr
=
ParamAttr
(
initializer
=
MSRA
(),
name
=
name
+
"_weights"
),
initializer
=
MSRA
(),
name
=
name
+
"_weights"
),
bias_attr
=
False
)
bias_attr
=
False
)
bn_name
=
name
+
"_bn"
return
fluid
.
layers
.
batch_n
orm
(
self
.
_batch_norm
=
BatchN
orm
(
input
=
conv
,
num_filters
,
act
=
act
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
"_scale"
),
param_attr
=
ParamAttr
(
name
+
"_bn_scale"
),
bias_attr
=
ParamAttr
(
name
=
bn_name
+
"_offset"
),
bias_attr
=
ParamAttr
(
name
+
"_bn_offset"
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_mean_name
=
name
+
"_bn_mean"
,
moving_variance_name
=
bn_name
+
'_variance'
)
moving_variance_name
=
name
+
"_bn_variance"
)
def
depthwise_separable
(
self
,
def
forward
(
self
,
inputs
):
input
,
y
=
self
.
_conv
(
inputs
)
num_filters1
,
y
=
self
.
_batch_norm
(
y
)
num_filters2
,
return
y
num_groups
,
stride
,
scale
,
class
DepthwiseSeparable
(
fluid
.
dygraph
.
Layer
):
name
=
None
):
def
__init__
(
self
,
depthwise_conv
=
self
.
conv_bn_layer
(
num_channels
,
input
=
input
,
num_filters1
,
filter_size
=
3
,
num_filters2
,
num_groups
,
stride
,
scale
,
name
=
None
):
super
(
DepthwiseSeparable
,
self
).
__init__
()
self
.
_depthwise_conv
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
int
(
num_filters1
*
scale
),
num_filters
=
int
(
num_filters1
*
scale
),
filter_size
=
3
,
stride
=
stride
,
stride
=
stride
,
padding
=
1
,
padding
=
1
,
num_groups
=
int
(
num_groups
*
scale
),
num_groups
=
int
(
num_groups
*
scale
),
use_cudnn
=
False
,
use_cudnn
=
False
,
name
=
name
+
"_dw"
)
name
=
name
+
"_dw"
)
pointwise_conv
=
self
.
conv_bn_l
ayer
(
self
.
_pointwise_conv
=
ConvBNL
ayer
(
input
=
depthwise_conv
,
num_channels
=
int
(
num_filters1
*
scale
)
,
filter_size
=
1
,
filter_size
=
1
,
num_filters
=
int
(
num_filters2
*
scale
),
num_filters
=
int
(
num_filters2
*
scale
),
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
name
=
name
+
"_sep"
)
name
=
name
+
"_sep"
)
return
pointwise_conv
def
forward
(
self
,
inputs
):
y
=
self
.
_depthwise_conv
(
inputs
)
y
=
self
.
_pointwise_conv
(
y
)
return
y
class
MobileNet
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
scale
=
1.0
,
class_dim
=
1000
):
super
(
MobileNet
,
self
).
__init__
()
self
.
scale
=
scale
self
.
block_list
=
[]
self
.
conv1
=
ConvBNLayer
(
num_channels
=
3
,
filter_size
=
3
,
channels
=
3
,
num_filters
=
int
(
32
*
scale
),
stride
=
2
,
padding
=
1
,
name
=
"conv1"
)
conv2_1
=
self
.
add_sublayer
(
"conv2_1"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
32
*
scale
),
num_filters1
=
32
,
num_filters2
=
64
,
num_groups
=
32
,
stride
=
1
,
scale
=
scale
,
name
=
"conv2_1"
))
self
.
block_list
.
append
(
conv2_1
)
conv2_2
=
self
.
add_sublayer
(
"conv2_2"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
64
*
scale
),
num_filters1
=
64
,
num_filters2
=
128
,
num_groups
=
64
,
stride
=
2
,
scale
=
scale
,
name
=
"conv2_2"
))
self
.
block_list
.
append
(
conv2_2
)
conv3_1
=
self
.
add_sublayer
(
"conv3_1"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
128
*
scale
),
num_filters1
=
128
,
num_filters2
=
128
,
num_groups
=
128
,
stride
=
1
,
scale
=
scale
,
name
=
"conv3_1"
))
self
.
block_list
.
append
(
conv3_1
)
conv3_2
=
self
.
add_sublayer
(
"conv3_2"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
128
*
scale
),
num_filters1
=
128
,
num_filters2
=
256
,
num_groups
=
128
,
stride
=
2
,
scale
=
scale
,
name
=
"conv3_2"
))
self
.
block_list
.
append
(
conv3_2
)
conv4_1
=
self
.
add_sublayer
(
"conv4_1"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
256
*
scale
),
num_filters1
=
256
,
num_filters2
=
256
,
num_groups
=
256
,
stride
=
1
,
scale
=
scale
,
name
=
"conv4_1"
))
self
.
block_list
.
append
(
conv4_1
)
conv4_2
=
self
.
add_sublayer
(
"conv4_2"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
256
*
scale
),
num_filters1
=
256
,
num_filters2
=
512
,
num_groups
=
256
,
stride
=
2
,
scale
=
scale
,
name
=
"conv4_2"
))
self
.
block_list
.
append
(
conv4_2
)
for
i
in
range
(
5
):
conv5
=
self
.
add_sublayer
(
"conv5_"
+
str
(
i
+
1
),
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
512
*
scale
),
num_filters1
=
512
,
num_filters2
=
512
,
num_groups
=
512
,
stride
=
1
,
scale
=
scale
,
name
=
"conv5_"
+
str
(
i
+
1
)))
self
.
block_list
.
append
(
conv5
)
conv5_6
=
self
.
add_sublayer
(
"conv5_6"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
512
*
scale
),
num_filters1
=
512
,
num_filters2
=
1024
,
num_groups
=
512
,
stride
=
2
,
scale
=
scale
,
name
=
"conv5_6"
))
self
.
block_list
.
append
(
conv5_6
)
conv6
=
self
.
add_sublayer
(
"conv6"
,
sublayer
=
DepthwiseSeparable
(
num_channels
=
int
(
1024
*
scale
),
num_filters1
=
1024
,
num_filters2
=
1024
,
num_groups
=
1024
,
stride
=
1
,
scale
=
scale
,
name
=
"conv6"
))
self
.
block_list
.
append
(
conv6
)
self
.
pool2d_avg
=
Pool2D
(
pool_type
=
'avg'
,
global_pooling
=
True
)
self
.
out
=
Linear
(
int
(
1024
*
scale
),
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
MSRA
(),
name
=
"fc7_weights"
),
bias_attr
=
ParamAttr
(
name
=
"fc7_offset"
))
def
forward
(
self
,
inputs
):
y
=
self
.
conv1
(
inputs
)
for
block
in
self
.
block_list
:
y
=
block
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
int
(
1024
*
self
.
scale
)])
y
=
self
.
out
(
y
)
return
y
def
MobileNetV1_x0_25
():
def
MobileNetV1_x0_25
(
**
args
):
model
=
MobileNet
V1
(
scale
=
0.25
)
model
=
MobileNet
(
scale
=
0.25
,
**
args
)
return
model
return
model
def
MobileNetV1_x0_5
():
def
MobileNetV1_x0_5
(
**
args
):
model
=
MobileNet
V1
(
scale
=
0.5
)
model
=
MobileNet
(
scale
=
0.5
,
**
args
)
return
model
return
model
def
MobileNetV1_x
1_0
(
):
def
MobileNetV1_x
0_75
(
**
args
):
model
=
MobileNet
V1
(
scale
=
1.0
)
model
=
MobileNet
(
scale
=
0.75
,
**
args
)
return
model
return
model
def
MobileNetV1
_x0_75
(
):
def
MobileNetV1
(
**
args
):
model
=
MobileNet
V1
(
scale
=
0.75
)
model
=
MobileNet
(
scale
=
1.0
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/mobilenet_v2.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
numpy
as
np
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.initializer
import
MSRA
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
__all__
=
[
__all__
=
[
'MobileNetV2_x0_25'
,
'MobileNetV2_x0_5'
"MobileNetV2_x0_25"
,
"MobileNetV2_x0_5"
,
"MobileNetV2_x0_75"
,
'MobileNetV2_x0_75'
,
'MobileNetV2_x1_0'
,
'MobileNetV2_x1_5'
,
"MobileNetV2"
,
"MobileNetV2_x1_5"
,
"MobileNetV2_x2_0"
'MobileNetV2_x2_0'
,
'MobileNetV2'
]
]
class
MobileNetV2
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
scale
=
1.0
):
def
__init__
(
self
,
self
.
scale
=
scale
num_channels
,
filter_size
,
def
net
(
self
,
input
,
class_dim
=
1000
):
num_filters
,
scale
=
self
.
scale
stride
,
bottleneck_params_list
=
[
padding
,
(
1
,
16
,
1
,
1
),
channels
=
None
,
(
6
,
24
,
2
,
2
),
num_groups
=
1
,
(
6
,
32
,
3
,
2
),
name
=
None
,
(
6
,
64
,
4
,
2
),
use_cudnn
=
True
):
(
6
,
96
,
3
,
1
),
super
(
ConvBNLayer
,
self
).
__init__
()
(
6
,
160
,
3
,
2
),
(
6
,
320
,
1
,
1
),
self
.
_conv
=
Conv2D
(
]
num_channels
=
num_channels
,
#conv1
input
=
self
.
conv_bn_layer
(
input
,
num_filters
=
int
(
32
*
scale
),
filter_size
=
3
,
stride
=
2
,
padding
=
1
,
if_act
=
True
,
name
=
'conv1_1'
)
# bottleneck sequences
i
=
1
in_c
=
int
(
32
*
scale
)
for
layer_setting
in
bottleneck_params_list
:
t
,
c
,
n
,
s
=
layer_setting
i
+=
1
input
=
self
.
invresi_blocks
(
input
=
input
,
in_c
=
in_c
,
t
=
t
,
c
=
int
(
c
*
scale
),
n
=
n
,
s
=
s
,
name
=
'conv'
+
str
(
i
))
in_c
=
int
(
c
*
scale
)
#last_conv
input
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
int
(
1280
*
scale
)
if
scale
>
1.0
else
1280
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
if_act
=
True
,
name
=
'conv9'
)
input
=
fluid
.
layers
.
pool2d
(
input
=
input
,
pool_type
=
'avg'
,
global_pooling
=
True
)
output
=
fluid
.
layers
.
fc
(
input
=
input
,
size
=
class_dim
,
param_attr
=
ParamAttr
(
name
=
'fc10_weights'
),
bias_attr
=
ParamAttr
(
name
=
'fc10_offset'
))
return
output
def
conv_bn_layer
(
self
,
input
,
filter_size
,
num_filters
,
stride
,
padding
,
channels
=
None
,
num_groups
=
1
,
if_act
=
True
,
name
=
None
,
use_cudnn
=
True
):
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
...
@@ -106,125 +53,197 @@ class MobileNetV2():
...
@@ -106,125 +53,197 @@ class MobileNetV2():
groups
=
num_groups
,
groups
=
num_groups
,
act
=
None
,
act
=
None
,
use_cudnn
=
use_cudnn
,
use_cudnn
=
use_cudnn
,
param_attr
=
ParamAttr
(
name
=
name
+
'_weights'
),
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
bias_attr
=
False
)
bn_name
=
name
+
'_bn'
bn
=
fluid
.
layers
.
batch_norm
(
self
.
_batch_norm
=
BatchNorm
(
input
=
conv
,
num_filters
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
"_scale"
),
param_attr
=
ParamAttr
(
name
=
name
+
"_bn_scale"
),
bias_attr
=
ParamAttr
(
name
=
bn_name
+
"_offset"
),
bias_attr
=
ParamAttr
(
name
=
name
+
"_bn_offset"
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_mean_name
=
name
+
"_bn_mean"
,
moving_variance_name
=
bn_name
+
'_variance'
)
moving_variance_name
=
name
+
"_bn_variance"
)
def
forward
(
self
,
inputs
,
if_act
=
True
):
y
=
self
.
_conv
(
inputs
)
y
=
self
.
_batch_norm
(
y
)
if
if_act
:
if
if_act
:
return
fluid
.
layers
.
relu6
(
bn
)
y
=
fluid
.
layers
.
relu6
(
y
)
else
:
return
y
return
bn
def
shortcut
(
self
,
input
,
data_residual
):
return
fluid
.
layers
.
elementwise_add
(
input
,
data_residual
)
def
inverted_residual_unit
(
self
,
input
,
num_in_filter
,
num_filters
,
ifshortcut
,
stride
,
filter_size
,
padding
,
expansion_factor
,
name
=
None
):
num_expfilter
=
int
(
round
(
num_in_filter
*
expansion_factor
))
channel_expand
=
self
.
conv_bn_layer
(
input
=
input
,
class
InvertedResidualUnit
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels
,
num_in_filter
,
num_filters
,
stride
,
filter_size
,
padding
,
expansion_factor
,
name
):
super
(
InvertedResidualUnit
,
self
).
__init__
()
num_expfilter
=
int
(
round
(
num_in_filter
*
expansion_factor
))
self
.
_expand_conv
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_expfilter
,
num_filters
=
num_expfilter
,
filter_size
=
1
,
filter_size
=
1
,
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
num_groups
=
1
,
num_groups
=
1
,
if_act
=
True
,
name
=
name
+
"_expand"
)
name
=
name
+
'_expand'
)
bottleneck_conv
=
self
.
conv_bn_l
ayer
(
self
.
_bottleneck_conv
=
ConvBNL
ayer
(
input
=
channel_expand
,
num_channels
=
num_expfilter
,
num_filters
=
num_expfilter
,
num_filters
=
num_expfilter
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
padding
=
padding
,
padding
=
padding
,
num_groups
=
num_expfilter
,
num_groups
=
num_expfilter
,
if_act
=
True
,
use_cudnn
=
False
,
name
=
name
+
'_dwise'
,
name
=
name
+
"_dwise"
)
use_cudnn
=
False
)
linear_out
=
self
.
conv_bn_l
ayer
(
self
.
_linear_conv
=
ConvBNL
ayer
(
input
=
bottleneck_conv
,
num_channels
=
num_expfilter
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
num_groups
=
1
,
num_groups
=
1
,
if_act
=
False
,
name
=
name
+
"_linear"
)
name
=
name
+
'_linear'
)
def
forward
(
self
,
inputs
,
ifshortcut
):
y
=
self
.
_expand_conv
(
inputs
,
if_act
=
True
)
y
=
self
.
_bottleneck_conv
(
y
,
if_act
=
True
)
y
=
self
.
_linear_conv
(
y
,
if_act
=
False
)
if
ifshortcut
:
if
ifshortcut
:
out
=
self
.
shortcut
(
input
=
input
,
data_residual
=
linear_out
)
y
=
fluid
.
layers
.
elementwise_add
(
inputs
,
y
)
return
out
return
y
else
:
return
linear_out
class
InvresiBlocks
(
fluid
.
dygraph
.
Layer
):
def
invresi_blocks
(
self
,
input
,
in_c
,
t
,
c
,
n
,
s
,
name
=
None
):
def
__init__
(
self
,
in_c
,
t
,
c
,
n
,
s
,
name
):
first_block
=
self
.
inverted_residual_unit
(
super
(
InvresiBlocks
,
self
).
__init__
()
input
=
input
,
self
.
_first_block
=
InvertedResidualUnit
(
num_channels
=
in_c
,
num_in_filter
=
in_c
,
num_in_filter
=
in_c
,
num_filters
=
c
,
num_filters
=
c
,
ifshortcut
=
False
,
stride
=
s
,
stride
=
s
,
filter_size
=
3
,
filter_size
=
3
,
padding
=
1
,
padding
=
1
,
expansion_factor
=
t
,
expansion_factor
=
t
,
name
=
name
+
'_1'
)
name
=
name
+
"_1"
)
last_residual_block
=
first_block
last_c
=
c
self
.
_block_list
=
[]
for
i
in
range
(
1
,
n
):
for
i
in
range
(
1
,
n
):
last_residual_block
=
self
.
inverted_residual_unit
(
block
=
self
.
add_sublayer
(
input
=
last_residual_block
,
name
+
"_"
+
str
(
i
+
1
),
num_in_filter
=
last_c
,
sublayer
=
InvertedResidualUnit
(
num_filters
=
c
,
num_channels
=
c
,
ifshortcut
=
True
,
num_in_filter
=
c
,
stride
=
1
,
num_filters
=
c
,
filter_size
=
3
,
stride
=
1
,
padding
=
1
,
filter_size
=
3
,
expansion_factor
=
t
,
padding
=
1
,
name
=
name
+
'_'
+
str
(
i
+
1
))
expansion_factor
=
t
,
return
last_residual_block
name
=
name
+
"_"
+
str
(
i
+
1
)))
self
.
_block_list
.
append
(
block
)
def
MobileNetV2_x0_25
():
def
forward
(
self
,
inputs
):
model
=
MobileNetV2
(
scale
=
0.25
)
y
=
self
.
_first_block
(
inputs
,
ifshortcut
=
False
)
for
block
in
self
.
_block_list
:
y
=
block
(
y
,
ifshortcut
=
True
)
return
y
class
MobileNet
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
class_dim
=
1000
,
scale
=
1.0
):
super
(
MobileNet
,
self
).
__init__
()
self
.
scale
=
scale
self
.
class_dim
=
class_dim
bottleneck_params_list
=
[
(
1
,
16
,
1
,
1
),
(
6
,
24
,
2
,
2
),
(
6
,
32
,
3
,
2
),
(
6
,
64
,
4
,
2
),
(
6
,
96
,
3
,
1
),
(
6
,
160
,
3
,
2
),
(
6
,
320
,
1
,
1
),
]
self
.
conv1
=
ConvBNLayer
(
num_channels
=
3
,
num_filters
=
int
(
32
*
scale
),
filter_size
=
3
,
stride
=
2
,
padding
=
1
,
name
=
"conv1_1"
)
self
.
block_list
=
[]
i
=
1
in_c
=
int
(
32
*
scale
)
for
layer_setting
in
bottleneck_params_list
:
t
,
c
,
n
,
s
=
layer_setting
i
+=
1
block
=
self
.
add_sublayer
(
"conv"
+
str
(
i
),
sublayer
=
InvresiBlocks
(
in_c
=
in_c
,
t
=
t
,
c
=
int
(
c
*
scale
),
n
=
n
,
s
=
s
,
name
=
"conv"
+
str
(
i
)))
self
.
block_list
.
append
(
block
)
in_c
=
int
(
c
*
scale
)
self
.
out_c
=
int
(
1280
*
scale
)
if
scale
>
1.0
else
1280
self
.
conv9
=
ConvBNLayer
(
num_channels
=
in_c
,
num_filters
=
self
.
out_c
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
name
=
"conv9"
)
self
.
pool2d_avg
=
Pool2D
(
pool_type
=
"avg"
,
global_pooling
=
True
)
self
.
out
=
Linear
(
self
.
out_c
,
class_dim
,
param_attr
=
ParamAttr
(
name
=
"fc10_weights"
),
bias_attr
=
ParamAttr
(
name
=
"fc10_offset"
))
def
forward
(
self
,
inputs
):
y
=
self
.
conv1
(
inputs
,
if_act
=
True
)
for
block
in
self
.
block_list
:
y
=
block
(
y
)
y
=
self
.
conv9
(
y
,
if_act
=
True
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
out_c
])
y
=
self
.
out
(
y
)
return
y
def
MobileNetV2_x0_25
(
**
args
):
model
=
MobileNet
(
scale
=
0.25
,
**
args
)
return
model
return
model
def
MobileNetV2_x0_5
():
def
MobileNetV2_x0_5
(
**
args
):
model
=
MobileNet
V2
(
scale
=
0.5
)
model
=
MobileNet
(
scale
=
0.5
,
**
args
)
return
model
return
model
def
MobileNetV2_x0_75
():
def
MobileNetV2_x0_75
(
**
args
):
model
=
MobileNet
V2
(
scale
=
0.75
)
model
=
MobileNet
(
scale
=
0.75
,
**
args
)
return
model
return
model
def
MobileNetV2
_x1_0
(
):
def
MobileNetV2
(
**
args
):
model
=
MobileNet
V2
(
scale
=
1.0
)
model
=
MobileNet
(
scale
=
1.0
,
**
args
)
return
model
return
model
def
MobileNetV2_x1_5
():
def
MobileNetV2_x1_5
(
**
args
):
model
=
MobileNet
V2
(
scale
=
1.5
)
model
=
MobileNet
(
scale
=
1.5
,
**
args
)
return
model
return
model
def
MobileNetV2_x2_0
():
def
MobileNetV2_x2_0
(
**
args
):
model
=
MobileNet
V2
(
scale
=
2.0
)
model
=
MobileNet
(
scale
=
2.0
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/mobilenet_v3.py
浏览文件 @
7f80e25c
...
@@ -16,320 +16,342 @@ from __future__ import absolute_import
...
@@ -16,320 +16,342 @@ from __future__ import absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
numpy
as
np
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
__all__
=
[
__all__
=
[
'MobileNetV3'
,
'MobileNetV3_small_x0_35'
,
'MobileNetV3_small_x0_5'
,
"MobileNetV3_small_x0_35"
,
"MobileNetV3_small_x0_5"
,
'MobileNetV3_small_x0_75'
,
'MobileNetV3_small_x1_0'
,
"MobileNetV3_small_x0_75"
,
"MobileNetV3_small_x1_0"
,
'MobileNetV3_small_x1_25'
,
'MobileNetV3_large_x0_35'
,
"MobileNetV3_small_x1_25"
,
"MobileNetV3_large_x0_35"
,
'MobileNetV3_large_x0_5'
,
'MobileNetV3_large_x0_75'
,
"MobileNetV3_large_x0_5"
,
"MobileNetV3_large_x0_75"
,
'MobileNetV3_large_x1_0'
,
'MobileNetV3_large_x1_25'
"MobileNetV3_large_x1_0"
,
"MobileNetV3_large_x1_25"
]
]
class
MobileNetV3
():
def
make_divisible
(
v
,
divisor
=
8
,
min_value
=
None
):
def
__init__
(
self
,
if
min_value
is
None
:
scale
=
1.0
,
min_value
=
divisor
model_name
=
'small'
,
new_v
=
max
(
min_value
,
int
(
v
+
divisor
/
2
)
//
divisor
*
divisor
)
lr_mult_list
=
[
1.0
,
1.0
,
1.0
,
1.0
,
1.0
]):
if
new_v
<
0.9
*
v
:
self
.
scale
=
scale
new_v
+=
divisor
self
.
inplanes
=
16
return
new_v
self
.
lr_mult_list
=
lr_mult_list
assert
len
(
self
.
lr_mult_list
)
==
5
,
\
"lr_mult_list length in MobileNetV3 must be 5 but got {}!!"
.
format
(
len
(
self
.
lr_mult_list
))
self
.
curr_stage
=
0
class
MobileNetV3
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
scale
=
1.0
,
model_name
=
"small"
,
class_dim
=
1000
):
super
(
MobileNetV3
,
self
).
__init__
()
inplanes
=
16
if
model_name
==
"large"
:
if
model_name
==
"large"
:
self
.
cfg
=
[
self
.
cfg
=
[
# k, exp, c, se, nl, s,
# k, exp, c, se, nl, s,
[
3
,
16
,
16
,
False
,
'relu'
,
1
],
[
3
,
16
,
16
,
False
,
"relu"
,
1
],
[
3
,
64
,
24
,
False
,
'relu'
,
2
],
[
3
,
64
,
24
,
False
,
"relu"
,
2
],
[
3
,
72
,
24
,
False
,
'relu'
,
1
],
[
3
,
72
,
24
,
False
,
"relu"
,
1
],
[
5
,
72
,
40
,
True
,
'relu'
,
2
],
[
5
,
72
,
40
,
True
,
"relu"
,
2
],
[
5
,
120
,
40
,
True
,
'relu'
,
1
],
[
5
,
120
,
40
,
True
,
"relu"
,
1
],
[
5
,
120
,
40
,
True
,
'relu'
,
1
],
[
5
,
120
,
40
,
True
,
"relu"
,
1
],
[
3
,
240
,
80
,
False
,
'hard_swish'
,
2
],
[
3
,
240
,
80
,
False
,
"hard_swish"
,
2
],
[
3
,
200
,
80
,
False
,
'hard_swish'
,
1
],
[
3
,
200
,
80
,
False
,
"hard_swish"
,
1
],
[
3
,
184
,
80
,
False
,
'hard_swish'
,
1
],
[
3
,
184
,
80
,
False
,
"hard_swish"
,
1
],
[
3
,
184
,
80
,
False
,
'hard_swish'
,
1
],
[
3
,
184
,
80
,
False
,
"hard_swish"
,
1
],
[
3
,
480
,
112
,
True
,
'hard_swish'
,
1
],
[
3
,
480
,
112
,
True
,
"hard_swish"
,
1
],
[
3
,
672
,
112
,
True
,
'hard_swish'
,
1
],
[
3
,
672
,
112
,
True
,
"hard_swish"
,
1
],
[
5
,
672
,
160
,
True
,
'hard_swish'
,
2
],
[
5
,
672
,
160
,
True
,
"hard_swish"
,
2
],
[
5
,
960
,
160
,
True
,
'hard_swish'
,
1
],
[
5
,
960
,
160
,
True
,
"hard_swish"
,
1
],
[
5
,
960
,
160
,
True
,
'hard_swish'
,
1
],
[
5
,
960
,
160
,
True
,
"hard_swish"
,
1
],
]
]
self
.
cls_ch_squeeze
=
960
self
.
cls_ch_squeeze
=
960
self
.
cls_ch_expand
=
1280
self
.
cls_ch_expand
=
1280
self
.
lr_interval
=
3
elif
model_name
==
"small"
:
elif
model_name
==
"small"
:
self
.
cfg
=
[
self
.
cfg
=
[
# k, exp, c, se, nl, s,
# k, exp, c, se, nl, s,
[
3
,
16
,
16
,
True
,
'relu'
,
2
],
[
3
,
16
,
16
,
True
,
"relu"
,
2
],
[
3
,
72
,
24
,
False
,
'relu'
,
2
],
[
3
,
72
,
24
,
False
,
"relu"
,
2
],
[
3
,
88
,
24
,
False
,
'relu'
,
1
],
[
3
,
88
,
24
,
False
,
"relu"
,
1
],
[
5
,
96
,
40
,
True
,
'hard_swish'
,
2
],
[
5
,
96
,
40
,
True
,
"hard_swish"
,
2
],
[
5
,
240
,
40
,
True
,
'hard_swish'
,
1
],
[
5
,
240
,
40
,
True
,
"hard_swish"
,
1
],
[
5
,
240
,
40
,
True
,
'hard_swish'
,
1
],
[
5
,
240
,
40
,
True
,
"hard_swish"
,
1
],
[
5
,
120
,
48
,
True
,
'hard_swish'
,
1
],
[
5
,
120
,
48
,
True
,
"hard_swish"
,
1
],
[
5
,
144
,
48
,
True
,
'hard_swish'
,
1
],
[
5
,
144
,
48
,
True
,
"hard_swish"
,
1
],
[
5
,
288
,
96
,
True
,
'hard_swish'
,
2
],
[
5
,
288
,
96
,
True
,
"hard_swish"
,
2
],
[
5
,
576
,
96
,
True
,
'hard_swish'
,
1
],
[
5
,
576
,
96
,
True
,
"hard_swish"
,
1
],
[
5
,
576
,
96
,
True
,
'hard_swish'
,
1
],
[
5
,
576
,
96
,
True
,
"hard_swish"
,
1
],
]
]
self
.
cls_ch_squeeze
=
576
self
.
cls_ch_squeeze
=
576
self
.
cls_ch_expand
=
1280
self
.
cls_ch_expand
=
1280
self
.
lr_interval
=
2
else
:
else
:
raise
NotImplementedError
(
raise
NotImplementedError
(
"mode[{}_model] is not implemented!"
.
format
(
model_name
))
"mode[{}_model] is not implemented!"
.
format
(
model_name
))
def
net
(
self
,
input
,
class_dim
=
1000
):
self
.
conv1
=
ConvBNLayer
(
scale
=
self
.
scale
in_c
=
3
,
inplanes
=
self
.
inplanes
out_c
=
make_divisible
(
inplanes
*
scale
),
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
,
filter_size
=
3
,
num_filters
=
self
.
make_divisible
(
inplanes
*
scale
),
stride
=
2
,
stride
=
2
,
padding
=
1
,
padding
=
1
,
num_groups
=
1
,
num_groups
=
1
,
if_act
=
True
,
if_act
=
True
,
act
=
'hard_swish'
,
act
=
"hard_swish"
,
name
=
'conv1'
)
name
=
"conv1"
)
self
.
block_list
=
[]
i
=
0
i
=
0
inplanes
=
self
.
make_divisible
(
inplanes
*
scale
)
inplanes
=
make_divisible
(
inplanes
*
scale
)
for
layer_cfg
in
cfg
:
for
(
k
,
exp
,
c
,
se
,
nl
,
s
)
in
self
.
cfg
:
conv
=
self
.
residual_unit
(
self
.
block_list
.
append
(
input
=
conv
,
ResidualUnit
(
num_in_filter
=
inplanes
,
in_c
=
inplanes
,
num_mid_filter
=
self
.
make_divisible
(
scale
*
layer_cfg
[
1
]),
mid_c
=
make_divisible
(
scale
*
exp
),
num_out_filter
=
self
.
make_divisible
(
scale
*
layer_cfg
[
2
]),
out_c
=
make_divisible
(
scale
*
c
),
act
=
layer_cfg
[
4
],
filter_size
=
k
,
stride
=
layer_cfg
[
5
],
stride
=
s
,
filter_size
=
layer_cfg
[
0
],
use_se
=
se
,
use_se
=
layer_cfg
[
3
],
act
=
nl
,
name
=
'conv'
+
str
(
i
+
2
))
name
=
"conv"
+
str
(
i
+
2
)))
inplanes
=
self
.
make_divisible
(
scale
*
layer_cfg
[
2
])
self
.
add_sublayer
(
sublayer
=
self
.
block_list
[
-
1
],
name
=
"conv"
+
str
(
i
+
2
))
inplanes
=
make_divisible
(
scale
*
c
)
i
+=
1
i
+=
1
self
.
curr_stage
=
i
conv
=
self
.
conv_bn_layer
(
self
.
last_second_conv
=
ConvBNLayer
(
input
=
conv
,
in_c
=
inplanes
,
out_c
=
make_divisible
(
scale
*
self
.
cls_ch_squeeze
),
filter_size
=
1
,
filter_size
=
1
,
num_filters
=
self
.
make_divisible
(
scale
*
cls_ch_squeeze
),
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
num_groups
=
1
,
num_groups
=
1
,
if_act
=
True
,
if_act
=
True
,
act
=
'hard_swish'
,
act
=
"hard_swish"
,
name
=
'conv_last'
)
name
=
"conv_last"
)
conv
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_type
=
'avg'
,
global_pooling
=
True
,
use_cudnn
=
False
)
self
.
pool
=
Pool2D
(
conv
=
fluid
.
layers
.
conv2d
(
pool_type
=
"avg"
,
global_pooling
=
True
,
use_cudnn
=
False
)
input
=
conv
,
num_filters
=
cls_ch_expand
,
self
.
last_conv
=
Conv2D
(
num_channels
=
make_divisible
(
scale
*
self
.
cls_ch_squeeze
),
num_filters
=
self
.
cls_ch_expand
,
filter_size
=
1
,
filter_size
=
1
,
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
act
=
None
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
'last_1x1_conv_weights'
),
param_attr
=
ParamAttr
(
name
=
"last_1x1_conv_weights"
),
bias_attr
=
False
)
bias_attr
=
False
)
conv
=
fluid
.
layers
.
hard_swish
(
conv
)
drop
=
fluid
.
layers
.
dropout
(
x
=
conv
,
dropout_prob
=
0.2
)
self
.
out
=
Linear
(
out
=
fluid
.
layers
.
fc
(
input
=
drop
,
input_dim
=
self
.
cls_ch_expand
,
size
=
class_dim
,
output_dim
=
class_dim
,
param_attr
=
ParamAttr
(
name
=
'fc_weights'
),
param_attr
=
ParamAttr
(
"fc_weights"
),
bias_attr
=
ParamAttr
(
name
=
'fc_offset'
))
bias_attr
=
ParamAttr
(
name
=
"fc_offset"
))
return
out
def
forward
(
self
,
inputs
,
label
=
None
,
dropout_prob
=
0.2
):
def
conv_bn_layer
(
self
,
x
=
self
.
conv1
(
inputs
)
input
,
for
block
in
self
.
block_list
:
filter_size
,
x
=
block
(
x
)
num_filters
,
x
=
self
.
last_second_conv
(
x
)
stride
,
x
=
self
.
pool
(
x
)
padding
,
x
=
self
.
last_conv
(
x
)
num_groups
=
1
,
x
=
fluid
.
layers
.
hard_swish
(
x
)
if_act
=
True
,
x
=
fluid
.
layers
.
dropout
(
x
=
x
,
dropout_prob
=
dropout_prob
)
act
=
None
,
x
=
fluid
.
layers
.
reshape
(
x
,
shape
=
[
x
.
shape
[
0
],
x
.
shape
[
1
]])
name
=
None
,
x
=
self
.
out
(
x
)
use_cudnn
=
True
,
res_last_bn_init
=
False
):
return
x
lr_idx
=
self
.
curr_stage
//
self
.
lr_interval
lr_idx
=
min
(
lr_idx
,
len
(
self
.
lr_mult_list
)
-
1
)
lr_mult
=
self
.
lr_mult_list
[
lr_idx
]
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
conv
=
fluid
.
layers
.
conv2d
(
in_c
,
input
=
input
,
out_c
,
num_filters
=
num_filters
,
filter_size
,
stride
,
padding
,
num_groups
=
1
,
if_act
=
True
,
act
=
None
,
use_cudnn
=
True
,
name
=
""
):
super
(
ConvBNLayer
,
self
).
__init__
()
self
.
if_act
=
if_act
self
.
act
=
act
self
.
conv
=
fluid
.
dygraph
.
Conv2D
(
num_channels
=
in_c
,
num_filters
=
out_c
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
padding
=
padding
,
padding
=
padding
,
groups
=
num_groups
,
groups
=
num_groups
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
,
use_cudnn
=
use_cudnn
,
use_cudnn
=
use_cudnn
,
act
=
None
)
self
.
bn
=
fluid
.
dygraph
.
BatchNorm
(
num_channels
=
out_c
,
act
=
None
,
param_attr
=
ParamAttr
(
param_attr
=
ParamAttr
(
name
=
name
+
'_weights'
,
learning_rate
=
lr_mult
),
name
=
name
+
"_bn_scale"
,
bias_attr
=
False
)
bn_name
=
name
+
'_bn'
bn
=
fluid
.
layers
.
batch_norm
(
input
=
conv
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
"_scale"
,
regularizer
=
fluid
.
regularizer
.
L2DecayRegularizer
(
regularizer
=
fluid
.
regularizer
.
L2DecayRegularizer
(
regularization_coeff
=
0.0
)),
regularization_coeff
=
0.0
)),
bias_attr
=
ParamAttr
(
bias_attr
=
ParamAttr
(
name
=
bn_name
+
"
_offset"
,
name
=
name
+
"_bn
_offset"
,
regularizer
=
fluid
.
regularizer
.
L2DecayRegularizer
(
regularizer
=
fluid
.
regularizer
.
L2DecayRegularizer
(
regularization_coeff
=
0.0
)),
regularization_coeff
=
0.0
)),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_mean_name
=
name
+
"_bn_mean"
,
moving_variance_name
=
bn_name
+
'_variance'
)
moving_variance_name
=
name
+
"_bn_variance"
)
if
if_act
:
if
act
==
'relu'
:
def
forward
(
self
,
x
):
bn
=
fluid
.
layers
.
relu
(
bn
)
x
=
self
.
conv
(
x
)
elif
act
==
'hard_swish'
:
x
=
self
.
bn
(
x
)
bn
=
fluid
.
layers
.
hard_swish
(
bn
)
if
self
.
if_act
:
return
bn
if
self
.
act
==
"relu"
:
x
=
fluid
.
layers
.
relu
(
x
)
def
make_divisible
(
self
,
v
,
divisor
=
8
,
min_value
=
None
):
elif
self
.
act
==
"hard_swish"
:
if
min_value
is
None
:
x
=
fluid
.
layers
.
hard_swish
(
x
)
min_value
=
divisor
else
:
new_v
=
max
(
min_value
,
int
(
v
+
divisor
/
2
)
//
divisor
*
divisor
)
print
(
"The activation function is selected incorrectly."
)
if
new_v
<
0.9
*
v
:
exit
()
new_v
+=
divisor
return
x
return
new_v
def
se_block
(
self
,
input
,
num_out_filter
,
ratio
=
4
,
name
=
None
):
class
ResidualUnit
(
fluid
.
dygraph
.
Layer
):
lr_idx
=
self
.
curr_stage
//
self
.
lr_interval
def
__init__
(
self
,
lr_idx
=
min
(
lr_idx
,
len
(
self
.
lr_mult_list
)
-
1
)
in_c
,
lr_mult
=
self
.
lr_mult_list
[
lr_idx
]
mid_c
,
out_c
,
num_mid_filter
=
num_out_filter
//
ratio
filter_size
,
pool
=
fluid
.
layers
.
pool2d
(
stride
,
input
=
input
,
pool_type
=
'avg'
,
global_pooling
=
True
,
use_cudnn
=
False
)
use_se
,
conv1
=
fluid
.
layers
.
conv2d
(
act
=
None
,
input
=
pool
,
name
=
''
):
filter_size
=
1
,
super
(
ResidualUnit
,
self
).
__init__
()
num_filters
=
num_mid_filter
,
self
.
if_shortcut
=
stride
==
1
and
in_c
==
out_c
act
=
'relu'
,
self
.
if_se
=
use_se
param_attr
=
ParamAttr
(
name
=
name
+
'_1_weights'
,
learning_rate
=
lr_mult
),
self
.
expand_conv
=
ConvBNLayer
(
bias_attr
=
ParamAttr
(
in_c
=
in_c
,
name
=
name
+
'_1_offset'
,
learning_rate
=
lr_mult
))
out_c
=
mid_c
,
conv2
=
fluid
.
layers
.
conv2d
(
input
=
conv1
,
filter_size
=
1
,
num_filters
=
num_out_filter
,
act
=
'hard_sigmoid'
,
param_attr
=
ParamAttr
(
name
=
name
+
'_2_weights'
,
learning_rate
=
lr_mult
),
bias_attr
=
ParamAttr
(
name
=
name
+
'_2_offset'
,
learning_rate
=
lr_mult
))
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
):
conv0
=
self
.
conv_bn_layer
(
input
=
input
,
filter_size
=
1
,
filter_size
=
1
,
num_filters
=
num_mid_filter
,
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
if_act
=
True
,
if_act
=
True
,
act
=
act
,
act
=
act
,
name
=
name
+
'_expand'
)
name
=
name
+
"_expand"
)
self
.
bottleneck_conv
=
ConvBNLayer
(
conv1
=
self
.
conv_bn_layer
(
in_c
=
mid_c
,
input
=
conv0
,
out_c
=
mid_c
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
num_filters
=
num_mid_filter
,
stride
=
stride
,
stride
=
stride
,
padding
=
int
((
filter_size
-
1
)
//
2
),
padding
=
int
((
filter_size
-
1
)
//
2
),
num_groups
=
mid_c
,
if_act
=
True
,
if_act
=
True
,
act
=
act
,
act
=
act
,
num_groups
=
num_mid_filter
,
name
=
name
+
"_depthwise"
)
use_cudnn
=
False
,
if
self
.
if_se
:
name
=
name
+
'_depthwise'
)
self
.
mid_se
=
SEModule
(
mid_c
,
name
=
name
+
"_se"
)
if
use_se
:
self
.
linear_conv
=
ConvBNLayer
(
conv1
=
self
.
se_block
(
in_c
=
mid_c
,
input
=
conv1
,
num_out_filter
=
num_mid_filter
,
name
=
name
+
'_se'
)
out_c
=
out_c
,
conv2
=
self
.
conv_bn_layer
(
input
=
conv1
,
filter_size
=
1
,
filter_size
=
1
,
num_filters
=
num_out_filter
,
stride
=
1
,
stride
=
1
,
padding
=
0
,
padding
=
0
,
if_act
=
False
,
if_act
=
False
,
name
=
name
+
'_linear'
,
act
=
None
,
res_last_bn_init
=
True
)
name
=
name
+
"_linear"
)
if
num_in_filter
!=
num_out_filter
or
stride
!=
1
:
return
conv2
def
forward
(
self
,
inputs
):
else
:
x
=
self
.
expand_conv
(
inputs
)
return
fluid
.
layers
.
elementwise_add
(
x
=
input
,
y
=
conv2
,
act
=
None
)
x
=
self
.
bottleneck_conv
(
x
)
if
self
.
if_se
:
x
=
self
.
mid_se
(
x
)
x
=
self
.
linear_conv
(
x
)
if
self
.
if_shortcut
:
x
=
fluid
.
layers
.
elementwise_add
(
inputs
,
x
)
return
x
class
SEModule
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
channel
,
reduction
=
4
,
name
=
""
):
super
(
SEModule
,
self
).
__init__
()
self
.
avg_pool
=
fluid
.
dygraph
.
Pool2D
(
pool_type
=
"avg"
,
global_pooling
=
True
,
use_cudnn
=
False
)
self
.
conv1
=
fluid
.
dygraph
.
Conv2D
(
num_channels
=
channel
,
num_filters
=
channel
//
reduction
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
act
=
"relu"
,
param_attr
=
ParamAttr
(
name
=
name
+
"_1_weights"
),
bias_attr
=
ParamAttr
(
name
=
name
+
"_1_offset"
))
self
.
conv2
=
fluid
.
dygraph
.
Conv2D
(
num_channels
=
channel
//
reduction
,
num_filters
=
channel
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
act
=
None
,
param_attr
=
ParamAttr
(
name
+
"_2_weights"
),
bias_attr
=
ParamAttr
(
name
=
name
+
"_2_offset"
))
def
forward
(
self
,
inputs
):
outputs
=
self
.
avg_pool
(
inputs
)
outputs
=
self
.
conv1
(
outputs
)
outputs
=
self
.
conv2
(
outputs
)
outputs
=
fluid
.
layers
.
hard_sigmoid
(
outputs
)
return
fluid
.
layers
.
elementwise_mul
(
x
=
inputs
,
y
=
outputs
,
axis
=
0
)
def
MobileNetV3_small_x0_35
():
def
MobileNetV3_small_x0_35
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'small'
,
scale
=
0.35
)
model
=
MobileNetV3
(
model_name
=
"small"
,
scale
=
0.35
,
**
args
)
return
model
return
model
def
MobileNetV3_small_x0_5
():
def
MobileNetV3_small_x0_5
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'small'
,
scale
=
0.5
)
model
=
MobileNetV3
(
model_name
=
"small"
,
scale
=
0.5
,
**
args
)
return
model
return
model
def
MobileNetV3_small_x0_75
():
def
MobileNetV3_small_x0_75
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'small'
,
scale
=
0.75
)
model
=
MobileNetV3
(
model_name
=
"small"
,
scale
=
0.75
,
**
args
)
return
model
return
model
def
MobileNetV3_small_x1_0
(
**
args
):
def
MobileNetV3_small_x1_0
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'small'
,
scale
=
1.0
,
**
args
)
model
=
MobileNetV3
(
model_name
=
"small"
,
scale
=
1.0
,
**
args
)
return
model
return
model
def
MobileNetV3_small_x1_25
():
def
MobileNetV3_small_x1_25
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'small'
,
scale
=
1.25
)
model
=
MobileNetV3
(
model_name
=
"small"
,
scale
=
1.25
,
**
args
)
return
model
return
model
def
MobileNetV3_large_x0_35
():
def
MobileNetV3_large_x0_35
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'large'
,
scale
=
0.35
)
model
=
MobileNetV3
(
model_name
=
"large"
,
scale
=
0.35
,
**
args
)
return
model
return
model
def
MobileNetV3_large_x0_5
():
def
MobileNetV3_large_x0_5
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'large'
,
scale
=
0.5
)
model
=
MobileNetV3
(
model_name
=
"large"
,
scale
=
0.5
,
**
args
)
return
model
return
model
def
MobileNetV3_large_x0_75
():
def
MobileNetV3_large_x0_75
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'large'
,
scale
=
0.75
)
model
=
MobileNetV3
(
model_name
=
"large"
,
scale
=
0.75
,
**
args
)
return
model
return
model
def
MobileNetV3_large_x1_0
(
**
args
):
def
MobileNetV3_large_x1_0
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'large'
,
scale
=
1.0
,
**
args
)
model
=
MobileNetV3
(
model_name
=
"large"
,
scale
=
1.0
,
**
args
)
return
model
return
model
def
MobileNetV3_large_x1_25
():
def
MobileNetV3_large_x1_25
(
**
args
):
model
=
MobileNetV3
(
model_name
=
'large'
,
scale
=
1.25
)
model
=
MobileNetV3
(
model_name
=
"large"
,
scale
=
1.25
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/res2net.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
numpy
as
np
import
paddle
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
import
math
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
__all__
=
[
__all__
=
[
"Res2Net
"
,
"Res2Net
50_48w_2s"
,
"Res2Net50_26w_4s"
,
"Res2Net50_14w_8s"
,
"Res2Net50_48w_2s"
,
"Res2Net50_26w_4s"
,
"Res2Net50_14w_8s"
,
"Res2Net50_
26w_6s"
,
"Res2Net50_26w_8s"
,
"Res2Net101_26w_4
s"
,
"Res2Net50_
48w_2s"
,
"Res2Net50_26w_6s"
,
"Res2Net50_26w_8
s"
,
"Res2Net1
52
_26w_4s"
"Res2Net1
01_26w_4s"
,
"Res2Net152_26w_4s"
,
"Res2Net200
_26w_4s"
]
]
class
Res2Net
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
scales
=
4
,
width
=
26
):
def
__init__
(
self
,
num_channels
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
,
):
super
(
ConvBNLayer
,
self
).
__init__
()
self
.
_conv
=
Conv2D
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
stride
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
self
.
_batch_norm
=
BatchNorm
(
num_filters
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
def
forward
(
self
,
inputs
):
y
=
self
.
_conv
(
inputs
)
y
=
self
.
_batch_norm
(
y
)
return
y
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels1
,
num_channels2
,
num_filters
,
stride
,
scales
,
shortcut
=
True
,
if_first
=
False
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
self
.
stride
=
stride
self
.
scales
=
scales
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels1
,
num_filters
=
num_filters
,
filter_size
=
1
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
self
.
conv1_list
=
[]
for
s
in
range
(
scales
-
1
):
conv1
=
self
.
add_sublayer
(
name
+
'_branch2b_'
+
str
(
s
+
1
),
ConvBNLayer
(
num_channels
=
num_filters
//
scales
,
num_filters
=
num_filters
//
scales
,
filter_size
=
3
,
stride
=
stride
,
act
=
'relu'
,
name
=
name
+
'_branch2b_'
+
str
(
s
+
1
)))
self
.
conv1_list
.
append
(
conv1
)
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
stride
,
pool_padding
=
1
,
pool_type
=
'avg'
)
self
.
conv2
=
ConvBNLayer
(
num_channels
=
num_filters
,
num_filters
=
num_channels2
,
filter_size
=
1
,
act
=
None
,
name
=
name
+
"_branch2c"
)
if
not
shortcut
:
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels1
,
num_filters
=
num_channels2
,
filter_size
=
1
,
stride
=
stride
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
xs
=
fluid
.
layers
.
split
(
y
,
self
.
scales
,
1
)
ys
=
[]
for
s
,
conv1
in
enumerate
(
self
.
conv1_list
):
if
s
==
0
or
self
.
stride
==
2
:
ys
.
append
(
conv1
(
xs
[
s
]))
else
:
ys
.
append
(
conv1
(
xs
[
s
]
+
ys
[
-
1
]))
if
self
.
stride
==
1
:
ys
.
append
(
xs
[
-
1
])
else
:
ys
.
append
(
self
.
pool2d_avg
(
xs
[
-
1
]))
conv1
=
fluid
.
layers
.
concat
(
ys
,
axis
=
1
)
conv2
=
self
.
conv2
(
conv1
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
class
Res2Net
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
scales
=
4
,
width
=
26
,
class_dim
=
1000
):
super
(
Res2Net
,
self
).
__init__
()
self
.
layers
=
layers
self
.
layers
=
layers
self
.
scales
=
scales
self
.
scales
=
scales
self
.
width
=
width
self
.
width
=
width
def
net
(
self
,
input
,
class_dim
=
1000
):
layers
=
self
.
layers
supported_layers
=
[
50
,
101
,
152
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
basic_width
=
self
.
width
*
self
.
scales
basic_width
=
self
.
width
*
self
.
scales
num_filters1
=
[
basic_width
*
t
for
t
in
[
1
,
2
,
4
,
8
]]
supported_layers
=
[
50
,
101
,
152
,
200
]
num_filters2
=
[
256
*
t
for
t
in
[
1
,
2
,
4
,
8
]]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
50
:
if
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
depth
=
[
3
,
4
,
6
,
3
]
...
@@ -49,22 +167,25 @@ class Res2Net():
...
@@ -49,22 +167,25 @@ class Res2Net():
depth
=
[
3
,
4
,
23
,
3
]
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
depth
=
[
3
,
8
,
36
,
3
]
conv
=
self
.
conv_bn_layer
(
elif
layers
==
200
:
input
=
input
,
depth
=
[
3
,
12
,
48
,
3
]
num_channels
=
[
64
,
256
,
512
,
1024
]
num_channels2
=
[
256
,
512
,
1024
,
2048
]
num_filters
=
[
basic_width
*
t
for
t
in
[
1
,
2
,
4
,
8
]]
self
.
conv1
=
ConvBNLayer
(
num_channels
=
3
,
num_filters
=
64
,
num_filters
=
64
,
filter_size
=
7
,
filter_size
=
7
,
stride
=
2
,
stride
=
2
,
act
=
'relu'
,
act
=
'relu'
,
name
=
"conv1"
)
name
=
"conv1"
)
self
.
pool2d_max
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
conv
=
fluid
.
layers
.
pool2d
(
self
.
block_list
=
[]
input
=
conv
,
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
for
block
in
range
(
len
(
depth
)):
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
if
i
==
0
:
...
@@ -73,153 +194,87 @@ class Res2Net():
...
@@ -73,153 +194,87 @@ class Res2Net():
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
bottleneck_block
(
bottleneck_block
=
self
.
add_sublayer
(
input
=
conv
,
'bb_%d_%d'
%
(
block
,
i
),
num_filters1
=
num_filters1
[
block
],
BottleneckBlock
(
num_filters2
=
num_filters2
[
block
],
num_channels1
=
num_channels
[
block
]
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
if
i
==
0
else
num_channels2
[
block
],
name
=
conv_name
)
num_channels2
=
num_channels2
[
block
],
pool
=
fluid
.
layers
.
pool2d
(
num_filters
=
num_filters
[
block
],
input
=
conv
,
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
pool_size
=
7
,
scales
=
scales
,
pool_stride
=
1
,
shortcut
=
shortcut
,
pool_type
=
'avg'
,
if_first
=
block
==
i
==
0
,
global_pooling
=
True
)
name
=
conv_name
))
self
.
block_list
.
append
(
bottleneck_block
)
stdv
=
1.0
/
math
.
sqrt
(
pool
.
shape
[
1
]
*
1.0
)
shortcut
=
True
out
=
fluid
.
layers
.
fc
(
input
=
pool
,
self
.
pool2d_avg
=
Pool2D
(
size
=
class_dim
,
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
self
.
pool2d_avg_channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
pool2d_avg_channels
,
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
'fc_weights'
),
name
=
"fc_weights"
),
bias_attr
=
fluid
.
param_attr
.
ParamAttr
(
name
=
'fc_offset'
))
bias_attr
=
ParamAttr
(
name
=
"fc_offset"
))
return
out
def
forward
(
self
,
inputs
):
def
conv_bn_layer
(
self
,
y
=
self
.
conv1
(
inputs
)
input
,
y
=
self
.
pool2d_max
(
y
)
num_filters
,
for
block
in
self
.
block_list
:
filter_size
,
y
=
block
(
y
)
stride
=
1
,
y
=
self
.
pool2d_avg
(
y
)
groups
=
1
,
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_channels
])
act
=
None
,
y
=
self
.
out
(
y
)
name
=
None
):
return
y
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
def
Res2Net50_48w_2s
(
**
args
):
filter_size
=
filter_size
,
model
=
Res2Net
(
layers
=
50
,
scales
=
2
,
width
=
48
,
**
args
)
stride
=
stride
,
return
model
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_norm
(
input
=
conv
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
def
shortcut
(
self
,
input
,
ch_out
,
stride
,
name
):
ch_in
=
input
.
shape
[
1
]
if
ch_in
!=
ch_out
or
stride
!=
1
:
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
input
def
bottleneck_block
(
self
,
input
,
num_filters1
,
num_filters2
,
stride
,
name
):
conv0
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
num_filters1
,
filter_size
=
1
,
stride
=
1
,
act
=
'relu'
,
name
=
name
+
'_branch2a'
)
xs
=
fluid
.
layers
.
split
(
conv0
,
self
.
scales
,
1
)
ys
=
[]
for
s
in
range
(
self
.
scales
-
1
):
if
s
==
0
or
stride
==
2
:
ys
.
append
(
self
.
conv_bn_layer
(
input
=
xs
[
s
],
num_filters
=
num_filters1
//
self
.
scales
,
stride
=
stride
,
filter_size
=
3
,
act
=
'relu'
,
name
=
name
+
'_branch2b_'
+
str
(
s
+
1
)))
else
:
ys
.
append
(
self
.
conv_bn_layer
(
input
=
xs
[
s
]
+
ys
[
-
1
],
num_filters
=
num_filters1
//
self
.
scales
,
stride
=
stride
,
filter_size
=
3
,
act
=
'relu'
,
name
=
name
+
'_branch2b_'
+
str
(
s
+
1
)))
if
stride
==
1
:
ys
.
append
(
xs
[
-
1
])
else
:
ys
.
append
(
fluid
.
layers
.
pool2d
(
input
=
xs
[
-
1
],
pool_size
=
3
,
pool_stride
=
stride
,
pool_padding
=
1
,
pool_type
=
'avg'
))
conv1
=
fluid
.
layers
.
concat
(
ys
,
axis
=
1
)
conv2
=
self
.
conv_bn_layer
(
input
=
conv1
,
num_filters
=
num_filters2
,
filter_size
=
1
,
act
=
None
,
name
=
name
+
"_branch2c"
)
short
=
self
.
shortcut
(
input
,
num_filters2
,
stride
,
name
=
name
+
"_branch1"
)
return
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
,
act
=
'relu'
)
def
Res2Net50_26w_4s
(
**
args
):
model
=
Res2Net
(
layers
=
50
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
def
Res2Net50_
48w_2s
(
):
def
Res2Net50_
14w_8s
(
**
args
):
model
=
Res2Net
(
layers
=
50
,
scales
=
2
,
width
=
48
)
model
=
Res2Net
(
layers
=
50
,
scales
=
8
,
width
=
14
,
**
args
)
return
model
return
model
def
Res2Net50_
26w_4s
(
):
def
Res2Net50_
48w_2s
(
**
args
):
model
=
Res2Net
(
layers
=
50
,
scales
=
4
,
width
=
26
)
model
=
Res2Net
(
layers
=
50
,
scales
=
2
,
width
=
48
,
**
args
)
return
model
return
model
def
Res2Net50_
14w_8s
(
):
def
Res2Net50_
26w_6s
(
**
args
):
model
=
Res2Net
(
layers
=
50
,
scales
=
8
,
width
=
14
)
model
=
Res2Net
(
layers
=
50
,
scales
=
6
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net50_26w_
6s
(
):
def
Res2Net50_26w_
8s
(
**
args
):
model
=
Res2Net
(
layers
=
50
,
scales
=
6
,
width
=
26
)
model
=
Res2Net
(
layers
=
50
,
scales
=
8
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net
50_26w_8s
(
):
def
Res2Net
101_26w_4s
(
**
args
):
model
=
Res2Net
(
layers
=
50
,
scales
=
8
,
width
=
26
)
model
=
Res2Net
(
layers
=
101
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net1
01_26w_4s
(
):
def
Res2Net1
52_26w_4s
(
**
args
):
model
=
Res2Net
(
layers
=
1
01
,
scales
=
4
,
width
=
26
)
model
=
Res2Net
(
layers
=
1
52
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net
152_26w_4s
(
):
def
Res2Net
200_26w_4s
(
**
args
):
model
=
Res2Net
(
layers
=
152
,
scales
=
4
,
width
=
26
)
model
=
Res2Net
(
layers
=
200
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/res2net_vd.py
浏览文件 @
7f80e25c
...
@@ -16,33 +16,158 @@ from __future__ import absolute_import
...
@@ -16,33 +16,158 @@ from __future__ import absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
math
import
numpy
as
np
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
__all__
=
[
__all__
=
[
"Res2Net
_vd"
,
"Res2Net50_vd_48w_2s"
,
"Res2Net50_vd_26w_4
s"
,
"Res2Net
50_vd_48w_2s"
,
"Res2Net50_vd_26w_4s"
,
"Res2Net50_vd_14w_8
s"
,
"Res2Net50_vd_
14w_8
s"
,
"Res2Net50_vd_26w_6s"
,
"Res2Net50_vd_26w_8s"
,
"Res2Net50_vd_
48w_2
s"
,
"Res2Net50_vd_26w_6s"
,
"Res2Net50_vd_26w_8s"
,
"Res2Net101_vd_26w_4s"
,
"Res2Net152_vd_26w_4s"
,
"Res2Net200_vd_26w_4s"
"Res2Net101_vd_26w_4s"
,
"Res2Net152_vd_26w_4s"
,
"Res2Net200_vd_26w_4s"
]
]
class
Res2Net_vd
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
scales
=
4
,
width
=
26
):
def
__init__
(
self
,
num_channels
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
is_vd_mode
=
False
,
act
=
None
,
name
=
None
,
):
super
(
ConvBNLayer
,
self
).
__init__
()
self
.
is_vd_mode
=
is_vd_mode
self
.
_pool2d_avg
=
Pool2D
(
pool_size
=
2
,
pool_stride
=
2
,
pool_padding
=
0
,
pool_type
=
'avg'
)
self
.
_conv
=
Conv2D
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
stride
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
self
.
_batch_norm
=
BatchNorm
(
num_filters
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
def
forward
(
self
,
inputs
):
if
self
.
is_vd_mode
:
inputs
=
self
.
_pool2d_avg
(
inputs
)
y
=
self
.
_conv
(
inputs
)
y
=
self
.
_batch_norm
(
y
)
return
y
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels1
,
num_channels2
,
num_filters
,
stride
,
scales
,
shortcut
=
True
,
if_first
=
False
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
self
.
stride
=
stride
self
.
scales
=
scales
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels1
,
num_filters
=
num_filters
,
filter_size
=
1
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
self
.
conv1_list
=
[]
for
s
in
range
(
scales
-
1
):
conv1
=
self
.
add_sublayer
(
name
+
'_branch2b_'
+
str
(
s
+
1
),
ConvBNLayer
(
num_channels
=
num_filters
//
scales
,
num_filters
=
num_filters
//
scales
,
filter_size
=
3
,
stride
=
stride
,
act
=
'relu'
,
name
=
name
+
'_branch2b_'
+
str
(
s
+
1
)))
self
.
conv1_list
.
append
(
conv1
)
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
stride
,
pool_padding
=
1
,
pool_type
=
'avg'
)
self
.
conv2
=
ConvBNLayer
(
num_channels
=
num_filters
,
num_filters
=
num_channels2
,
filter_size
=
1
,
act
=
None
,
name
=
name
+
"_branch2c"
)
if
not
shortcut
:
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels1
,
num_filters
=
num_channels2
,
filter_size
=
1
,
stride
=
1
,
is_vd_mode
=
False
if
if_first
else
True
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
xs
=
fluid
.
layers
.
split
(
y
,
self
.
scales
,
1
)
ys
=
[]
for
s
,
conv1
in
enumerate
(
self
.
conv1_list
):
if
s
==
0
or
self
.
stride
==
2
:
ys
.
append
(
conv1
(
xs
[
s
]))
else
:
ys
.
append
(
conv1
(
xs
[
s
]
+
ys
[
-
1
]))
if
self
.
stride
==
1
:
ys
.
append
(
xs
[
-
1
])
else
:
ys
.
append
(
self
.
pool2d_avg
(
xs
[
-
1
]))
conv1
=
fluid
.
layers
.
concat
(
ys
,
axis
=
1
)
conv2
=
self
.
conv2
(
conv1
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
class
Res2Net_vd
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
scales
=
4
,
width
=
26
,
class_dim
=
1000
):
super
(
Res2Net_vd
,
self
).
__init__
()
self
.
layers
=
layers
self
.
layers
=
layers
self
.
scales
=
scales
self
.
scales
=
scales
self
.
width
=
width
self
.
width
=
width
basic_width
=
self
.
width
*
self
.
scales
def
net
(
self
,
input
,
class_dim
=
1000
):
layers
=
self
.
layers
supported_layers
=
[
50
,
101
,
152
,
200
]
supported_layers
=
[
50
,
101
,
152
,
200
]
assert
layers
in
supported_layers
,
\
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
supported_layers
,
layers
)
basic_width
=
self
.
width
*
self
.
scales
num_filters1
=
[
basic_width
*
t
for
t
in
[
1
,
2
,
4
,
8
]]
num_filters2
=
[
256
*
t
for
t
in
[
1
,
2
,
4
,
8
]]
if
layers
==
50
:
if
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
elif
layers
==
101
:
...
@@ -51,35 +176,37 @@ class Res2Net_vd():
...
@@ -51,35 +176,37 @@ class Res2Net_vd():
depth
=
[
3
,
8
,
36
,
3
]
depth
=
[
3
,
8
,
36
,
3
]
elif
layers
==
200
:
elif
layers
==
200
:
depth
=
[
3
,
12
,
48
,
3
]
depth
=
[
3
,
12
,
48
,
3
]
conv
=
self
.
conv_bn_layer
(
num_channels
=
[
64
,
256
,
512
,
1024
]
input
=
input
,
num_channels2
=
[
256
,
512
,
1024
,
2048
]
num_filters
=
[
basic_width
*
t
for
t
in
[
1
,
2
,
4
,
8
]]
self
.
conv1_1
=
ConvBNLayer
(
num_channels
=
3
,
num_filters
=
32
,
num_filters
=
32
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
2
,
stride
=
2
,
act
=
'relu'
,
act
=
'relu'
,
name
=
'conv1_1'
)
name
=
"conv1_1"
)
conv
=
self
.
conv_bn_l
ayer
(
self
.
conv1_2
=
ConvBNL
ayer
(
input
=
conv
,
num_channels
=
32
,
num_filters
=
32
,
num_filters
=
32
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
1
,
stride
=
1
,
act
=
'relu'
,
act
=
'relu'
,
name
=
'conv1_2'
)
name
=
"conv1_2"
)
conv
=
self
.
conv_bn_l
ayer
(
self
.
conv1_3
=
ConvBNL
ayer
(
input
=
conv
,
num_channels
=
32
,
num_filters
=
64
,
num_filters
=
64
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
1
,
stride
=
1
,
act
=
'relu'
,
act
=
'relu'
,
name
=
'conv1_3'
)
name
=
"conv1_3"
)
self
.
pool2d_max
=
Pool2D
(
conv
=
fluid
.
layers
.
pool2d
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
input
=
conv
,
pool_size
=
3
,
self
.
block_list
=
[]
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
for
block
in
range
(
len
(
depth
)):
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
,
200
]
and
block
==
2
:
if
layers
in
[
101
,
152
,
200
]
and
block
==
2
:
if
i
==
0
:
if
i
==
0
:
...
@@ -88,207 +215,89 @@ class Res2Net_vd():
...
@@ -88,207 +215,89 @@ class Res2Net_vd():
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
bottleneck_block
(
bottleneck_block
=
self
.
add_sublayer
(
input
=
conv
,
'bb_%d_%d'
%
(
block
,
i
),
num_filters1
=
num_filters1
[
block
],
BottleneckBlock
(
num_filters2
=
num_filters2
[
block
],
num_channels1
=
num_channels
[
block
]
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
if
i
==
0
else
num_channels2
[
block
],
if_first
=
block
==
i
==
0
,
num_channels2
=
num_channels2
[
block
],
name
=
conv_name
)
num_filters
=
num_filters
[
block
],
pool
=
fluid
.
layers
.
pool2d
(
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
input
=
conv
,
scales
=
scales
,
pool_size
=
7
,
shortcut
=
shortcut
,
pool_stride
=
1
,
if_first
=
block
==
i
==
0
,
pool_type
=
'avg'
,
name
=
conv_name
))
global_pooling
=
True
)
self
.
block_list
.
append
(
bottleneck_block
)
shortcut
=
True
stdv
=
1.0
/
math
.
sqrt
(
pool
.
shape
[
1
]
*
1.0
)
out
=
fluid
.
layers
.
fc
(
self
.
pool2d_avg
=
Pool2D
(
input
=
pool
,
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
size
=
class_dim
,
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
self
.
pool2d_avg_channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
pool2d_avg_channels
,
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
'fc_weights'
),
name
=
"fc_weights"
),
bias_attr
=
fluid
.
param_attr
.
ParamAttr
(
name
=
'fc_offset'
))
bias_attr
=
ParamAttr
(
name
=
"fc_offset"
))
return
out
def
forward
(
self
,
inputs
):
def
conv_bn_layer
(
self
,
y
=
self
.
conv1_1
(
inputs
)
input
,
y
=
self
.
conv1_2
(
y
)
num_filters
,
y
=
self
.
conv1_3
(
y
)
filter_size
,
y
=
self
.
pool2d_max
(
y
)
stride
=
1
,
for
block
in
self
.
block_list
:
groups
=
1
,
y
=
block
(
y
)
act
=
None
,
y
=
self
.
pool2d_avg
(
y
)
name
=
None
):
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_channels
])
conv
=
fluid
.
layers
.
conv2d
(
y
=
self
.
out
(
y
)
input
=
input
,
return
y
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
stride
,
def
Res2Net50_vd_48w_2s
(
**
args
):
padding
=
(
filter_size
-
1
)
//
2
,
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
2
,
width
=
48
,
**
args
)
groups
=
groups
,
return
model
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_norm
(
input
=
conv
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
def
conv_bn_layer_new
(
self
,
input
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
):
pool
=
fluid
.
layers
.
pool2d
(
input
=
input
,
pool_size
=
2
,
pool_stride
=
2
,
pool_padding
=
0
,
pool_type
=
'avg'
,
ceil_mode
=
True
)
conv
=
fluid
.
layers
.
conv2d
(
input
=
pool
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
1
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_norm
(
input
=
conv
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
def
shortcut
(
self
,
input
,
ch_out
,
stride
,
name
,
if_first
=
False
):
ch_in
=
input
.
shape
[
1
]
if
ch_in
!=
ch_out
or
stride
!=
1
:
if
if_first
:
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
self
.
conv_bn_layer_new
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
elif
if_first
:
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
input
def
bottleneck_block
(
self
,
input
,
num_filters1
,
num_filters2
,
stride
,
name
,
if_first
):
conv0
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
num_filters1
,
filter_size
=
1
,
stride
=
1
,
act
=
'relu'
,
name
=
name
+
'_branch2a'
)
xs
=
fluid
.
layers
.
split
(
conv0
,
self
.
scales
,
1
)
ys
=
[]
for
s
in
range
(
self
.
scales
-
1
):
if
s
==
0
or
stride
==
2
:
ys
.
append
(
self
.
conv_bn_layer
(
input
=
xs
[
s
],
num_filters
=
num_filters1
//
self
.
scales
,
stride
=
stride
,
filter_size
=
3
,
act
=
'relu'
,
name
=
name
+
'_branch2b_'
+
str
(
s
+
1
)))
else
:
ys
.
append
(
self
.
conv_bn_layer
(
input
=
xs
[
s
]
+
ys
[
-
1
],
num_filters
=
num_filters1
//
self
.
scales
,
stride
=
stride
,
filter_size
=
3
,
act
=
'relu'
,
name
=
name
+
'_branch2b_'
+
str
(
s
+
1
)))
if
stride
==
1
:
ys
.
append
(
xs
[
-
1
])
else
:
ys
.
append
(
fluid
.
layers
.
pool2d
(
input
=
xs
[
-
1
],
pool_size
=
3
,
pool_stride
=
stride
,
pool_padding
=
1
,
pool_type
=
'avg'
))
conv1
=
fluid
.
layers
.
concat
(
ys
,
axis
=
1
)
conv2
=
self
.
conv_bn_layer
(
input
=
conv1
,
num_filters
=
num_filters2
,
filter_size
=
1
,
act
=
None
,
name
=
name
+
"_branch2c"
)
short
=
self
.
shortcut
(
input
,
num_filters2
,
stride
,
if_first
=
if_first
,
name
=
name
+
"_branch1"
)
return
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
,
act
=
'relu'
)
def
Res2Net50_vd_
48w_2s
(
):
def
Res2Net50_vd_
26w_4s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
2
,
width
=
48
)
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net50_vd_
26w_4s
(
):
def
Res2Net50_vd_
14w_8s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
4
,
width
=
26
)
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
8
,
width
=
14
,
**
args
)
return
model
return
model
def
Res2Net50_vd_
14w_8s
(
):
def
Res2Net50_vd_
48w_2s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
8
,
width
=
14
)
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
2
,
width
=
48
,
**
args
)
return
model
return
model
def
Res2Net50_vd_26w_6s
():
def
Res2Net50_vd_26w_6s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
6
,
width
=
26
)
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
6
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net50_vd_26w_8s
():
def
Res2Net50_vd_26w_8s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
8
,
width
=
26
)
model
=
Res2Net_vd
(
layers
=
50
,
scales
=
8
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net101_vd_26w_4s
():
def
Res2Net101_vd_26w_4s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
101
,
scales
=
4
,
width
=
26
)
model
=
Res2Net_vd
(
layers
=
101
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net152_vd_26w_4s
():
def
Res2Net152_vd_26w_4s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
152
,
scales
=
4
,
width
=
26
)
model
=
Res2Net_vd
(
layers
=
152
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
def
Res2Net200_vd_26w_4s
():
def
Res2Net200_vd_26w_4s
(
**
args
):
model
=
Res2Net_vd
(
layers
=
200
,
scales
=
4
,
width
=
26
)
model
=
Res2Net_vd
(
layers
=
200
,
scales
=
4
,
width
=
26
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/resnet.py
浏览文件 @
7f80e25c
...
@@ -12,19 +12,20 @@
...
@@ -12,19 +12,20 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
print_function
import
numpy
as
np
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
import
math
__all__
=
[
__all__
=
[
"ResNet18"
,
"ResNet34"
,
"ResNet50"
,
"ResNet101"
,
"ResNet152"
]
"ResNet18"
,
"ResNet34"
,
"ResNet50"
,
"ResNet101"
,
"ResNet152"
,
]
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
...
@@ -34,7 +35,8 @@ class ConvBNLayer(fluid.dygraph.Layer):
...
@@ -34,7 +35,8 @@ class ConvBNLayer(fluid.dygraph.Layer):
filter_size
,
filter_size
,
stride
=
1
,
stride
=
1
,
groups
=
1
,
groups
=
1
,
act
=
None
):
act
=
None
,
name
=
None
):
super
(
ConvBNLayer
,
self
).
__init__
()
super
(
ConvBNLayer
,
self
).
__init__
()
self
.
_conv
=
Conv2D
(
self
.
_conv
=
Conv2D
(
...
@@ -45,44 +47,62 @@ class ConvBNLayer(fluid.dygraph.Layer):
...
@@ -45,44 +47,62 @@ class ConvBNLayer(fluid.dygraph.Layer):
padding
=
(
filter_size
-
1
)
//
2
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
groups
=
groups
,
act
=
None
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
bias_attr
=
False
)
if
name
==
"conv1"
:
self
.
_batch_norm
=
BatchNorm
(
num_filters
,
act
=
act
)
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
self
.
_batch_norm
=
BatchNorm
(
num_filters
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
"_scale"
),
bias_attr
=
ParamAttr
(
bn_name
+
"_offset"
),
moving_mean_name
=
bn_name
+
"_mean"
,
moving_variance_name
=
bn_name
+
"_variance"
)
def
forward
(
self
,
inputs
):
def
forward
(
self
,
inputs
):
y
=
self
.
_conv
(
inputs
)
y
=
self
.
_conv
(
inputs
)
y
=
self
.
_batch_norm
(
y
)
y
=
self
.
_batch_norm
(
y
)
return
y
return
y
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
):
def
__init__
(
self
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
super
(
BottleneckBlock
,
self
).
__init__
()
self
.
conv0
=
ConvBNLayer
(
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_channels
=
num_channels
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
'relu'
)
act
=
"relu"
,
name
=
name
+
"_branch2a"
)
self
.
conv1
=
ConvBNLayer
(
self
.
conv1
=
ConvBNLayer
(
num_channels
=
num_filters
,
num_channels
=
num_filters
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
stride
,
stride
=
stride
,
act
=
'relu'
)
act
=
"relu"
,
name
=
name
+
"_branch2b"
)
self
.
conv2
=
ConvBNLayer
(
self
.
conv2
=
ConvBNLayer
(
num_channels
=
num_filters
,
num_channels
=
num_filters
,
num_filters
=
num_filters
*
4
,
num_filters
=
num_filters
*
4
,
filter_size
=
1
,
filter_size
=
1
,
act
=
None
)
act
=
None
,
name
=
name
+
"_branch2c"
)
if
not
shortcut
:
if
not
shortcut
:
self
.
short
=
ConvBNLayer
(
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_channels
=
num_channels
,
num_filters
=
num_filters
*
4
,
num_filters
=
num_filters
*
4
,
filter_size
=
1
,
filter_size
=
1
,
stride
=
stride
)
stride
=
stride
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
self
.
shortcut
=
shortcut
...
@@ -100,7 +120,54 @@ class BottleneckBlock(fluid.dygraph.Layer):
...
@@ -100,7 +120,54 @@ class BottleneckBlock(fluid.dygraph.Layer):
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
"relu"
)
return
layer_helper
.
append_activation
(
y
)
class
BisicBlock
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
,
name
=
None
):
super
(
BisicBlock
,
self
).
__init__
()
self
.
stride
=
stride
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
3
,
stride
=
stride
,
act
=
"relu"
,
name
=
name
+
"_branch2a"
)
self
.
conv1
=
ConvBNLayer
(
num_channels
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
act
=
None
,
name
=
name
+
"_branch2b"
)
if
not
shortcut
:
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
1
,
stride
=
stride
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv1
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
"relu"
)
return
layer_helper
.
append_activation
(
y
)
return
layer_helper
.
append_activation
(
y
)
...
@@ -109,18 +176,21 @@ class ResNet(fluid.dygraph.Layer):
...
@@ -109,18 +176,21 @@ class ResNet(fluid.dygraph.Layer):
super
(
ResNet
,
self
).
__init__
()
super
(
ResNet
,
self
).
__init__
()
self
.
layers
=
layers
self
.
layers
=
layers
supported_layers
=
[
50
,
101
,
152
]
supported_layers
=
[
18
,
34
,
50
,
101
,
152
]
assert
layers
in
supported_layers
,
\
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
supported_layers
,
layers
)
if
layers
==
50
:
if
layers
==
18
:
depth
=
[
2
,
2
,
2
,
2
]
elif
layers
==
34
or
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
depth
=
[
3
,
8
,
36
,
3
]
num_channels
=
[
64
,
256
,
512
,
1024
]
num_channels
=
[
64
,
256
,
512
,
1024
]
if
layers
>=
50
else
[
64
,
64
,
128
,
256
]
num_filters
=
[
64
,
128
,
256
,
512
]
num_filters
=
[
64
,
128
,
256
,
512
]
self
.
conv
=
ConvBNLayer
(
self
.
conv
=
ConvBNLayer
(
...
@@ -128,69 +198,97 @@ class ResNet(fluid.dygraph.Layer):
...
@@ -128,69 +198,97 @@ class ResNet(fluid.dygraph.Layer):
num_filters
=
64
,
num_filters
=
64
,
filter_size
=
7
,
filter_size
=
7
,
stride
=
2
,
stride
=
2
,
act
=
'relu'
)
act
=
"relu"
,
name
=
"conv1"
)
self
.
pool2d_max
=
Pool2D
(
self
.
pool2d_max
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
"max"
)
self
.
bottleneck_block_list
=
[]
self
.
block_list
=
[]
for
block
in
range
(
len
(
depth
)):
if
layers
>=
50
:
shortcut
=
False
for
block
in
range
(
len
(
depth
)):
for
i
in
range
(
depth
[
block
]):
shortcut
=
False
bottleneck_block
=
self
.
add_sublayer
(
for
i
in
range
(
depth
[
block
]):
'bb_%d_%d'
%
(
block
,
i
),
if
layers
in
[
101
,
152
]
and
block
==
2
:
BottleneckBlock
(
if
i
==
0
:
num_channels
=
num_channels
[
block
]
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
if
i
==
0
else
num_filters
[
block
]
*
4
,
else
:
num_filters
=
num_filters
[
block
],
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
else
:
shortcut
=
shortcut
))
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
self
.
bottleneck_block_list
.
append
(
bottleneck_block
)
bottleneck_block
=
self
.
add_sublayer
(
shortcut
=
True
conv_name
,
BottleneckBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
]
*
4
,
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
shortcut
=
shortcut
,
name
=
conv_name
))
self
.
block_list
.
append
(
bottleneck_block
)
shortcut
=
True
else
:
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bisic_block
=
self
.
add_sublayer
(
conv_name
,
BisicBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
],
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
shortcut
=
shortcut
,
name
=
conv_name
))
self
.
block_list
.
append
(
bisic_block
)
shortcut
=
True
self
.
pool2d_avg
=
Pool2D
(
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
self
.
pool2d_avg_
output
=
num_filters
[
len
(
num_filters
)
-
1
]
*
4
*
1
*
1
self
.
pool2d_avg_
channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
2048
*
1.0
)
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
out
=
Linear
(
self
.
pool2d_avg_
output
,
self
.
pool2d_avg_
channels
,
class_dim
,
class_dim
,
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
)))
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
"fc_0.w_0"
),
bias_attr
=
ParamAttr
(
name
=
"fc_0.b_0"
))
def
forward
(
self
,
inputs
):
def
forward
(
self
,
inputs
):
y
=
self
.
conv
(
inputs
)
y
=
self
.
conv
(
inputs
)
y
=
self
.
pool2d_max
(
y
)
y
=
self
.
pool2d_max
(
y
)
for
b
ottleneck_block
in
self
.
bottleneck_
block_list
:
for
b
lock
in
self
.
block_list
:
y
=
b
ottleneck_b
lock
(
y
)
y
=
block
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_
output
])
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_
channels
])
y
=
self
.
out
(
y
)
y
=
self
.
out
(
y
)
return
y
return
y
def
ResNet18
(
**
kw
args
):
def
ResNet18
(
**
args
):
model
=
ResNet
(
layers
=
18
,
**
kw
args
)
model
=
ResNet
(
layers
=
18
,
**
args
)
return
model
return
model
def
ResNet34
(
**
kw
args
):
def
ResNet34
(
**
args
):
model
=
ResNet
(
layers
=
34
,
**
kw
args
)
model
=
ResNet
(
layers
=
34
,
**
args
)
return
model
return
model
def
ResNet50
(
**
kw
args
):
def
ResNet50
(
**
args
):
model
=
ResNet
(
layers
=
50
,
**
kw
args
)
model
=
ResNet
(
layers
=
50
,
**
args
)
return
model
return
model
def
ResNet101
(
**
kw
args
):
def
ResNet101
(
**
args
):
model
=
ResNet
(
layers
=
101
,
**
kw
args
)
model
=
ResNet
(
layers
=
101
,
**
args
)
return
model
return
model
def
ResNet152
(
class_dim
=
1000
):
def
ResNet152
(
**
args
):
model
=
ResNet
(
layers
=
152
,
class_dim
=
class_dim
)
model
=
ResNet
(
layers
=
152
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/resnet_vc.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
math
import
numpy
as
np
import
paddle
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
__all__
=
[
"ResNet"
,
"ResNet50_vc"
,
"ResNet101_vc"
,
"ResNet152_vc"
]
import
math
train_parameters
=
{
"input_size"
:
[
3
,
224
,
224
],
"input_mean"
:
[
0.485
,
0.456
,
0.406
],
"input_std"
:
[
0.229
,
0.224
,
0.225
],
"learning_strategy"
:
{
"name"
:
"piecewise_decay"
,
"batch_size"
:
256
,
"epochs"
:
[
30
,
60
,
90
],
"steps"
:
[
0.1
,
0.01
,
0.001
,
0.0001
]
}
}
class
ResNet
():
__all__
=
[
def
__init__
(
self
,
layers
=
50
):
"ResNet18_vc"
,
"ResNet34_vc"
,
"ResNet50_vc"
,
"ResNet101_vc"
,
"ResNet152_vc"
self
.
params
=
train_parameters
]
self
.
layers
=
layers
def
net
(
self
,
input
,
class_dim
=
1000
):
layers
=
self
.
layers
supported_layers
=
[
50
,
101
,
152
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
50
:
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
depth
=
[
3
,
4
,
6
,
3
]
def
__init__
(
self
,
elif
layers
==
101
:
num_channels
,
depth
=
[
3
,
4
,
23
,
3
]
num_filters
,
elif
layers
==
152
:
filter_size
,
depth
=
[
3
,
8
,
36
,
3
]
stride
=
1
,
num_filters
=
[
64
,
128
,
256
,
512
]
groups
=
1
,
act
=
None
,
name
=
None
):
super
(
ConvBNLayer
,
self
).
__init__
()
conv
=
self
.
conv_bn_layer
(
self
.
_conv
=
Conv2D
(
input
=
input
,
num_channels
=
num_channels
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
2
,
act
=
'relu'
,
name
=
'conv1_1'
)
conv
=
self
.
conv_bn_layer
(
input
=
conv
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
'conv1_2'
)
conv
=
self
.
conv_bn_layer
(
input
=
conv
,
num_filters
=
64
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
'conv1_3'
)
conv
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
for
block
in
range
(
len
(
depth
)):
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
bottleneck_block
(
input
=
conv
,
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
name
=
conv_name
)
pool
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_type
=
'avg'
,
global_pooling
=
True
)
stdv
=
1.0
/
math
.
sqrt
(
pool
.
shape
[
1
]
*
1.0
)
out
=
fluid
.
layers
.
fc
(
input
=
pool
,
size
=
class_dim
,
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
name
=
"fc_0.w_0"
,
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
)),
bias_attr
=
ParamAttr
(
name
=
"fc_0.b_0"
))
return
out
def
conv_bn_layer
(
self
,
input
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
):
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
...
@@ -129,66 +50,264 @@ class ResNet():
...
@@ -129,66 +50,264 @@ class ResNet():
groups
=
groups
,
groups
=
groups
,
act
=
None
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
,
bias_attr
=
False
)
name
=
name
+
'.conv2d.output.1'
)
if
name
==
"conv1"
:
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
bn_name
=
"bn_"
+
name
else
:
else
:
bn_name
=
"bn"
+
name
[
3
:]
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_n
orm
(
self
.
_batch_norm
=
BatchN
orm
(
input
=
conv
,
num_filters
,
act
=
act
,
act
=
act
,
name
=
bn_name
+
'.output.1'
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
,
)
moving_variance_name
=
bn_name
+
'_variance'
)
def
shortcut
(
self
,
input
,
ch_out
,
stride
,
name
):
def
forward
(
self
,
inputs
):
ch_in
=
input
.
shape
[
1
]
y
=
self
.
_conv
(
inputs
)
if
ch_in
!=
ch_out
or
stride
!=
1
:
y
=
self
.
_batch_norm
(
y
)
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
return
y
else
:
return
input
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
def
bottleneck_block
(
self
,
input
,
num_filters
,
stride
,
name
):
self
.
conv0
=
ConvBNLayer
(
conv0
=
self
.
conv_bn_layer
(
num_channels
=
num_channels
,
input
=
input
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
name
=
name
+
"_branch2a"
)
conv1
=
self
.
conv_bn_l
ayer
(
self
.
conv1
=
ConvBNL
ayer
(
input
=
conv0
,
num_channels
=
num_filters
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
stride
,
stride
=
stride
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2b"
)
name
=
name
+
"_branch2b"
)
conv2
=
self
.
conv_bn_l
ayer
(
self
.
conv2
=
ConvBNL
ayer
(
input
=
conv1
,
num_channels
=
num_filters
,
num_filters
=
num_filters
*
4
,
num_filters
=
num_filters
*
4
,
filter_size
=
1
,
filter_size
=
1
,
act
=
None
,
act
=
None
,
name
=
name
+
"_branch2c"
)
name
=
name
+
"_branch2c"
)
short
=
self
.
shortcut
(
if
not
shortcut
:
input
,
num_filters
*
4
,
stride
,
name
=
name
+
"_branch1"
)
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
*
4
,
filter_size
=
1
,
stride
=
stride
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
self
.
_num_channels_out
=
num_filters
*
4
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
conv2
=
self
.
conv2
(
conv1
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
class
BisicBlock
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
,
name
=
None
):
super
(
BisicBlock
,
self
).
__init__
()
self
.
stride
=
stride
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
3
,
stride
=
stride
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
self
.
conv1
=
ConvBNLayer
(
num_channels
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
act
=
None
,
name
=
name
+
"_branch2b"
)
if
not
shortcut
:
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
1
,
stride
=
stride
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv1
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
class
ResNet_vc
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
class_dim
=
1000
):
super
(
ResNet_vc
,
self
).
__init__
()
self
.
layers
=
layers
supported_layers
=
[
18
,
34
,
50
,
101
,
152
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
18
:
depth
=
[
2
,
2
,
2
,
2
]
elif
layers
==
34
or
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
num_channels
=
[
64
,
256
,
512
,
1024
]
if
layers
>=
50
else
[
64
,
64
,
128
,
256
]
num_filters
=
[
64
,
128
,
256
,
512
]
return
fluid
.
layers
.
elementwise_add
(
self
.
conv1_1
=
ConvBNLayer
(
x
=
short
,
y
=
conv2
,
act
=
'relu'
,
name
=
name
+
".add.output.5"
)
num_channels
=
3
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
2
,
act
=
'relu'
,
name
=
"conv1_1"
)
self
.
conv1_2
=
ConvBNLayer
(
num_channels
=
32
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
"conv1_2"
)
self
.
conv1_3
=
ConvBNLayer
(
num_channels
=
32
,
num_filters
=
64
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
"conv1_3"
)
self
.
pool2d_max
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
self
.
block_list
=
[]
if
layers
>=
50
:
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bottleneck_block
=
self
.
add_sublayer
(
'bb_%d_%d'
%
(
block
,
i
),
BottleneckBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
]
*
4
,
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
shortcut
=
shortcut
,
name
=
conv_name
))
self
.
block_list
.
append
(
bottleneck_block
)
shortcut
=
True
else
:
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bisic_block
=
self
.
add_sublayer
(
'bb_%d_%d'
%
(
block
,
i
),
BisicBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
],
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
shortcut
=
shortcut
,
name
=
conv_name
))
self
.
block_list
.
append
(
bisic_block
)
shortcut
=
True
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
self
.
pool2d_avg_channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
pool2d_avg_channels
,
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
"fc_0.w_0"
),
bias_attr
=
ParamAttr
(
name
=
"fc_0.b_0"
))
def
forward
(
self
,
inputs
):
y
=
self
.
conv1_1
(
inputs
)
y
=
self
.
conv1_2
(
y
)
y
=
self
.
conv1_3
(
y
)
y
=
self
.
pool2d_max
(
y
)
for
block
in
self
.
block_list
:
y
=
block
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_channels
])
y
=
self
.
out
(
y
)
return
y
def
ResNet18_vc
(
**
args
):
model
=
ResNet_vc
(
layers
=
18
,
**
args
)
return
model
def
ResNet34_vc
(
**
args
):
model
=
ResNet_vc
(
layers
=
34
,
**
args
)
return
model
def
ResNet50_vc
():
def
ResNet50_vc
(
**
args
):
model
=
ResNet
(
layers
=
50
)
model
=
ResNet
_vc
(
layers
=
50
,
**
args
)
return
model
return
model
def
ResNet101_vc
():
def
ResNet101_vc
(
**
args
):
model
=
ResNet
(
layers
=
101
)
model
=
ResNet
_vc
(
layers
=
101
,
**
args
)
return
model
return
model
def
ResNet152_vc
():
def
ResNet152_vc
(
**
args
):
model
=
ResNet
(
layers
=
152
)
model
=
ResNet
_vc
(
layers
=
152
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/resnet_vd.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
math
import
numpy
as
np
import
paddle
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
__all__
=
[
__all__
=
[
"ResNet"
,
"ResNet18_vd"
,
"ResNet34_vd"
,
"ResNet50_vd"
,
"ResNet101_vd"
,
"ResNet18_vd"
,
"ResNet34_vd"
,
"ResNet50_vd"
,
"ResNet101_vd"
,
"ResNet152_vd"
"ResNet152_vd"
,
"ResNet200_vd"
]
]
class
ResNet
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
def
__init__
(
layers
=
50
,
self
,
is_3x3
=
False
,
num_channels
,
postfix_name
=
""
,
num_filters
,
lr_mult_list
=
[
1.0
,
1.0
,
1.0
,
1.0
,
1.0
]):
filter_size
,
self
.
layers
=
layers
stride
=
1
,
self
.
is_3x3
=
is_3x3
groups
=
1
,
self
.
postfix_name
=
""
if
postfix_name
is
None
else
postfix_name
is_vd_mode
=
False
,
self
.
lr_mult_list
=
lr_mult_list
assert
len
(
self
.
lr_mult_list
)
==
5
,
"lr_mult_list length in ResNet must be 5 but got {}!!"
.
format
(
len
(
self
.
lr_mult_list
))
self
.
curr_stage
=
0
def
net
(
self
,
input
,
class_dim
=
1000
):
is_3x3
=
self
.
is_3x3
layers
=
self
.
layers
supported_layers
=
[
18
,
34
,
50
,
101
,
152
,
200
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
18
:
depth
=
[
2
,
2
,
2
,
2
]
elif
layers
==
34
or
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
elif
layers
==
200
:
depth
=
[
3
,
12
,
48
,
3
]
num_filters
=
[
64
,
128
,
256
,
512
]
if
is_3x3
==
False
:
conv
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
64
,
filter_size
=
7
,
stride
=
2
,
act
=
'relu'
)
else
:
conv
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
2
,
act
=
'relu'
,
name
=
'conv1_1'
)
conv
=
self
.
conv_bn_layer
(
input
=
conv
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
'conv1_2'
)
conv
=
self
.
conv_bn_layer
(
input
=
conv
,
num_filters
=
64
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
'conv1_3'
)
conv
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
if
layers
>=
50
:
for
block
in
range
(
len
(
depth
)):
self
.
curr_stage
+=
1
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
,
200
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
bottleneck_block
(
input
=
conv
,
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
if_first
=
block
==
i
==
0
,
name
=
conv_name
)
else
:
for
block
in
range
(
len
(
depth
)):
self
.
curr_stage
+=
1
for
i
in
range
(
depth
[
block
]):
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
basic_block
(
input
=
conv
,
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
if_first
=
block
==
i
==
0
,
name
=
conv_name
)
pool
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_type
=
'avg'
,
global_pooling
=
True
)
stdv
=
1.0
/
math
.
sqrt
(
pool
.
shape
[
1
]
*
1.0
)
out
=
fluid
.
layers
.
fc
(
input
=
pool
,
size
=
class_dim
,
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
name
=
"fc_0.w_0"
+
self
.
postfix_name
,
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
)),
bias_attr
=
ParamAttr
(
name
=
"fc_0.b_0"
+
self
.
postfix_name
))
return
out
def
conv_bn_layer
(
self
,
input
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
):
lr_mult
=
self
.
lr_mult_list
[
self
.
curr_stage
]
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
stride
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
act
=
None
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
+
self
.
postfix_name
),
name
=
None
,
):
bias_attr
=
False
)
super
(
ConvBNLayer
,
self
).
__init__
()
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
self
.
is_vd_mode
=
is_vd_mode
else
:
self
.
_pool2d_avg
=
Pool2D
(
bn_name
=
"bn"
+
name
[
3
:]
pool_size
=
2
,
pool_stride
=
2
,
pool_padding
=
0
,
pool_type
=
'avg'
)
return
fluid
.
layers
.
batch_norm
(
self
.
_conv
=
Conv2D
(
input
=
conv
,
num_channels
=
num_channels
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
+
self
.
postfix_name
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
+
self
.
postfix_name
),
moving_mean_name
=
bn_name
+
'_mean'
+
self
.
postfix_name
,
moving_variance_name
=
bn_name
+
'_variance'
+
self
.
postfix_name
)
def
conv_bn_layer_new
(
self
,
input
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
):
lr_mult
=
self
.
lr_mult_list
[
self
.
curr_stage
]
pool
=
fluid
.
layers
.
pool2d
(
input
=
input
,
pool_size
=
2
,
pool_stride
=
2
,
pool_padding
=
0
,
pool_type
=
'avg'
,
ceil_mode
=
True
)
conv
=
fluid
.
layers
.
conv2d
(
input
=
pool
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
1
,
stride
=
stride
,
padding
=
(
filter_size
-
1
)
//
2
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
groups
=
groups
,
act
=
None
,
act
=
None
,
param_attr
=
ParamAttr
(
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
name
=
name
+
"_weights"
+
self
.
postfix_name
,
learning_rate
=
lr_mult
),
bias_attr
=
False
)
bias_attr
=
False
)
if
name
==
"conv1"
:
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
bn_name
=
"bn_"
+
name
else
:
else
:
bn_name
=
"bn"
+
name
[
3
:]
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_n
orm
(
self
.
_batch_norm
=
BatchN
orm
(
input
=
conv
,
num_filters
,
act
=
act
,
act
=
act
,
param_attr
=
ParamAttr
(
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
name
=
bn_name
+
'_scale'
+
self
.
postfix_name
,
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
learning_rate
=
lr_mult
),
moving_mean_name
=
bn_name
+
'_mean'
,
bias_attr
=
ParamAttr
(
moving_variance_name
=
bn_name
+
'_variance'
)
bn_name
+
'_offset'
+
self
.
postfix_name
,
learning_rate
=
lr_mult
),
def
forward
(
self
,
inputs
):
moving_mean_name
=
bn_name
+
'_mean'
+
self
.
postfix_name
,
if
self
.
is_vd_mode
:
moving_variance_name
=
bn_name
+
'_variance'
+
self
.
postfix_name
)
inputs
=
self
.
_pool2d_avg
(
inputs
)
y
=
self
.
_conv
(
inputs
)
def
shortcut
(
self
,
input
,
ch_out
,
stride
,
name
,
if_first
=
False
):
y
=
self
.
_batch_norm
(
y
)
ch_in
=
input
.
shape
[
1
]
return
y
if
ch_in
!=
ch_out
or
stride
!=
1
:
if
if_first
:
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
self
.
conv_bn_layer_new
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
elif
if_first
:
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
input
def
bottleneck_block
(
self
,
input
,
num_filters
,
stride
,
name
,
if_first
):
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
conv0
=
self
.
conv_bn_layer
(
def
__init__
(
self
,
input
=
input
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
,
if_first
=
False
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
name
=
name
+
"_branch2a"
)
conv1
=
self
.
conv_bn_l
ayer
(
self
.
conv1
=
ConvBNL
ayer
(
input
=
conv0
,
num_channels
=
num_filters
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
stride
,
stride
=
stride
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2b"
)
name
=
name
+
"_branch2b"
)
conv2
=
self
.
conv_bn_l
ayer
(
self
.
conv2
=
ConvBNL
ayer
(
input
=
conv1
,
num_channels
=
num_filters
,
num_filters
=
num_filters
*
4
,
num_filters
=
num_filters
*
4
,
filter_size
=
1
,
filter_size
=
1
,
act
=
None
,
act
=
None
,
name
=
name
+
"_branch2c"
)
name
=
name
+
"_branch2c"
)
short
=
self
.
shortcut
(
if
not
shortcut
:
input
,
self
.
short
=
ConvBNLayer
(
num_filters
*
4
,
num_channels
=
num_channels
,
stride
,
num_filters
=
num_filters
*
4
,
if_first
=
if_first
,
filter_size
=
1
,
name
=
name
+
"_branch1"
)
stride
=
1
,
is_vd_mode
=
False
if
if_first
else
True
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
conv2
=
self
.
conv2
(
conv1
)
return
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
,
act
=
'relu'
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
def
basic_block
(
self
,
input
,
num_filters
,
stride
,
name
,
if_first
):
conv0
=
self
.
conv_bn_layer
(
class
BisicBlock
(
fluid
.
dygraph
.
Layer
):
input
=
input
,
def
__init__
(
self
,
num_channels
,
num_filters
,
stride
,
shortcut
=
True
,
if_first
=
False
,
name
=
None
):
super
(
BisicBlock
,
self
).
__init__
()
self
.
stride
=
stride
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
act
=
'relu'
,
stride
=
stride
,
stride
=
stride
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
name
=
name
+
"_branch2a"
)
conv1
=
self
.
conv_bn_l
ayer
(
self
.
conv1
=
ConvBNL
ayer
(
input
=
conv0
,
num_channels
=
num_filters
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
act
=
None
,
act
=
None
,
name
=
name
+
"_branch2b"
)
name
=
name
+
"_branch2b"
)
short
=
self
.
shortcut
(
input
,
num_filters
,
stride
,
if_first
=
if_first
,
name
=
name
+
"_branch1"
)
return
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv1
,
act
=
'relu'
)
if
not
shortcut
:
self
.
short
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
filter_size
=
1
,
stride
=
1
,
is_vd_mode
=
False
if
if_first
else
True
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv1
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
class
ResNet_vd
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
class_dim
=
1000
):
super
(
ResNet_vd
,
self
).
__init__
()
self
.
layers
=
layers
supported_layers
=
[
18
,
34
,
50
,
101
,
152
,
200
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
18
:
depth
=
[
2
,
2
,
2
,
2
]
elif
layers
==
34
or
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
elif
layers
==
200
:
depth
=
[
3
,
12
,
48
,
3
]
num_channels
=
[
64
,
256
,
512
,
1024
]
if
layers
>=
50
else
[
64
,
64
,
128
,
256
]
num_filters
=
[
64
,
128
,
256
,
512
]
self
.
conv1_1
=
ConvBNLayer
(
num_channels
=
3
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
2
,
act
=
'relu'
,
name
=
"conv1_1"
)
self
.
conv1_2
=
ConvBNLayer
(
num_channels
=
32
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
"conv1_2"
)
self
.
conv1_3
=
ConvBNLayer
(
num_channels
=
32
,
num_filters
=
64
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
"conv1_3"
)
self
.
pool2d_max
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
def
ResNet18_vd
():
self
.
block_list
=
[]
model
=
ResNet
(
layers
=
18
,
is_3x3
=
True
)
if
layers
>=
50
:
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bottleneck_block
=
self
.
add_sublayer
(
'bb_%d_%d'
%
(
block
,
i
),
BottleneckBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
]
*
4
,
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
shortcut
=
shortcut
,
if_first
=
block
==
i
==
0
,
name
=
conv_name
))
self
.
block_list
.
append
(
bottleneck_block
)
shortcut
=
True
else
:
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bisic_block
=
self
.
add_sublayer
(
'bb_%d_%d'
%
(
block
,
i
),
BisicBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
],
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
shortcut
=
shortcut
,
if_first
=
block
==
i
==
0
,
name
=
conv_name
))
self
.
block_list
.
append
(
bisic_block
)
shortcut
=
True
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
self
.
pool2d_avg_channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
pool2d_avg_channels
,
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
"fc_0.w_0"
),
bias_attr
=
ParamAttr
(
name
=
"fc_0.b_0"
))
def
forward
(
self
,
inputs
):
y
=
self
.
conv1_1
(
inputs
)
y
=
self
.
conv1_2
(
y
)
y
=
self
.
conv1_3
(
y
)
y
=
self
.
pool2d_max
(
y
)
for
block
in
self
.
block_list
:
y
=
block
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_channels
])
y
=
self
.
out
(
y
)
return
y
def
ResNet18_vd
(
**
args
):
model
=
ResNet_vd
(
layers
=
18
,
**
args
)
return
model
return
model
def
ResNet34_vd
():
def
ResNet34_vd
(
**
args
):
model
=
ResNet
(
layers
=
34
,
is_3x3
=
True
)
model
=
ResNet
_vd
(
layers
=
34
,
**
args
)
return
model
return
model
def
ResNet50_vd
(
**
args
):
def
ResNet50_vd
(
**
args
):
model
=
ResNet
(
layers
=
50
,
is_3x3
=
True
,
**
args
)
model
=
ResNet
_vd
(
layers
=
50
,
**
args
)
return
model
return
model
def
ResNet101_vd
():
def
ResNet101_vd
(
**
args
):
model
=
ResNet
(
layers
=
101
,
is_3x3
=
True
)
model
=
ResNet
_vd
(
layers
=
101
,
**
args
)
return
model
return
model
def
ResNet152_vd
():
def
ResNet152_vd
(
**
args
):
model
=
ResNet
(
layers
=
152
,
is_3x3
=
True
)
model
=
ResNet
_vd
(
layers
=
152
,
**
args
)
return
model
return
model
def
ResNet200_vd
():
def
ResNet200_vd
(
**
args
):
model
=
ResNet
(
layers
=
200
,
is_3x3
=
True
)
model
=
ResNet
_vd
(
layers
=
200
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/resnext.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
division
from
__future__
import
print_function
from
__future__
import
print_function
import
math
import
numpy
as
np
import
paddle
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
__all__
=
[
__all__
=
[
"ResNeXt
"
,
"ResNeXt50_64x4d"
,
"ResNeXt101_64x4d"
,
"ResNeXt152_64
x4d"
,
"ResNeXt
50_32x4d"
,
"ResNeXt50_64x4d"
,
"ResNeXt101_32
x4d"
,
"ResNeXt
50_32x4d"
,
"ResNeXt101_32x4d"
,
"ResNeXt152_32
x4d"
"ResNeXt
101_64x4d"
,
"ResNeXt152_32x4d"
,
"ResNeXt152_64
x4d"
]
]
class
ResNeXt
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
cardinality
=
64
):
def
__init__
(
self
,
self
.
layers
=
layers
num_channels
,
self
.
cardinality
=
cardinality
num_filters
,
filter_size
,
def
net
(
self
,
input
,
class_dim
=
1000
):
stride
=
1
,
layers
=
self
.
layers
groups
=
1
,
cardinality
=
self
.
cardinality
act
=
None
,
supported_layers
=
[
50
,
101
,
152
]
name
=
None
):
assert
layers
in
supported_layers
,
\
super
(
ConvBNLayer
,
self
).
__init__
()
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
num_filters1
=
[
256
,
512
,
1024
,
2048
]
num_filters2
=
[
128
,
256
,
512
,
1024
]
conv
=
self
.
conv_bn_layer
(
self
.
_conv
=
Conv2D
(
input
=
input
,
num_channels
=
num_channels
,
num_filters
=
64
,
filter_size
=
7
,
stride
=
2
,
act
=
'relu'
,
name
=
"res_conv1"
)
#debug
conv
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
for
block
in
range
(
len
(
depth
)):
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
bottleneck_block
(
input
=
conv
,
num_filters
=
num_filters1
[
block
]
if
cardinality
==
64
else
num_filters2
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
cardinality
=
cardinality
,
name
=
conv_name
)
pool
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_type
=
'avg'
,
global_pooling
=
True
)
stdv
=
1.0
/
math
.
sqrt
(
pool
.
shape
[
1
]
*
1.0
)
out
=
fluid
.
layers
.
fc
(
input
=
pool
,
size
=
class_dim
,
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
'fc_weights'
),
bias_attr
=
fluid
.
param_attr
.
ParamAttr
(
name
=
'fc_offset'
))
return
out
def
conv_bn_layer
(
self
,
input
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
):
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
...
@@ -110,86 +51,192 @@ class ResNeXt():
...
@@ -110,86 +51,192 @@ class ResNeXt():
groups
=
groups
,
groups
=
groups
,
act
=
None
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
,
bias_attr
=
False
)
name
=
name
+
'.conv2d.output.1'
)
if
name
==
"conv1"
:
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
bn_name
=
"bn_"
+
name
else
:
else
:
bn_name
=
"bn"
+
name
[
3
:]
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_n
orm
(
self
.
_batch_norm
=
BatchN
orm
(
input
=
conv
,
num_filters
,
act
=
act
,
act
=
act
,
name
=
bn_name
+
'.output.1'
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
,
)
moving_variance_name
=
bn_name
+
'_variance'
)
def
shortcut
(
self
,
input
,
ch_out
,
stride
,
name
):
def
forward
(
self
,
inputs
):
ch_in
=
input
.
shape
[
1
]
y
=
self
.
_conv
(
inputs
)
if
ch_in
!=
ch_out
or
stride
!=
1
:
y
=
self
.
_batch_norm
(
y
)
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
return
y
else
:
return
input
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
def
bottleneck_block
(
self
,
input
,
num_filters
,
stride
,
cardinality
,
name
):
def
__init__
(
self
,
cardinality
=
self
.
cardinality
num_channels
,
conv0
=
self
.
conv_bn_layer
(
num_filters
,
input
=
input
,
stride
,
cardinality
,
shortcut
=
True
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
name
=
name
+
"_branch2a"
)
conv1
=
self
.
conv_bn_l
ayer
(
self
.
conv1
=
ConvBNL
ayer
(
input
=
conv0
,
num_channels
=
num_filters
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
stride
=
stride
,
groups
=
cardinality
,
groups
=
cardinality
,
stride
=
stride
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2b"
)
name
=
name
+
"_branch2b"
)
conv2
=
self
.
conv_bn_l
ayer
(
self
.
conv2
=
ConvBNL
ayer
(
input
=
conv1
,
num_channels
=
num_filters
,
num_filters
=
num_filters
if
cardinality
==
64
else
num_filters
*
2
,
num_filters
=
num_filters
*
2
if
cardinality
==
32
else
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
None
,
act
=
None
,
name
=
name
+
"_branch2c"
)
name
=
name
+
"_branch2c"
)
short
=
self
.
shortcut
(
if
not
shortcut
:
input
,
self
.
short
=
ConvBNLayer
(
num_filters
if
cardinality
==
64
else
num_filters
*
2
,
num_channels
=
num_channels
,
stride
,
num_filters
=
num_filters
*
2
name
=
name
+
"_branch1"
)
if
cardinality
==
32
else
num_filters
,
filter_size
=
1
,
stride
=
stride
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
conv2
=
self
.
conv2
(
conv1
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
return
fluid
.
layers
.
elementwise_add
(
class
ResNeXt
(
fluid
.
dygraph
.
Layer
):
x
=
short
,
y
=
conv2
,
act
=
'relu'
,
name
=
name
+
".add.output.5"
)
def
__init__
(
self
,
layers
=
50
,
class_dim
=
1000
,
cardinality
=
32
):
super
(
ResNeXt
,
self
).
__init__
()
self
.
layers
=
layers
self
.
cardinality
=
cardinality
supported_layers
=
[
50
,
101
,
152
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
supported_cardinality
=
[
32
,
64
]
assert
cardinality
in
supported_cardinality
,
\
"supported cardinality is {} but input cardinality is {}"
\
.
format
(
supported_cardinality
,
cardinality
)
if
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
num_channels
=
[
64
,
256
,
512
,
1024
]
num_filters
=
[
128
,
256
,
512
,
1024
]
if
cardinality
==
32
else
[
256
,
512
,
1024
,
2048
]
self
.
conv
=
ConvBNLayer
(
num_channels
=
3
,
num_filters
=
64
,
filter_size
=
7
,
stride
=
2
,
act
=
'relu'
,
name
=
"res_conv1"
)
self
.
pool2d_max
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
def
ResNeXt50_64x4d
():
self
.
block_list
=
[]
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
64
)
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bottleneck_block
=
self
.
add_sublayer
(
'bb_%d_%d'
%
(
block
,
i
),
BottleneckBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
]
*
int
(
64
//
self
.
cardinality
),
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
cardinality
=
self
.
cardinality
,
shortcut
=
shortcut
,
name
=
conv_name
))
self
.
block_list
.
append
(
bottleneck_block
)
shortcut
=
True
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
self
.
pool2d_avg_channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
pool2d_avg_channels
,
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
"fc_weights"
),
bias_attr
=
ParamAttr
(
name
=
"fc_offset"
))
def
forward
(
self
,
inputs
):
y
=
self
.
conv
(
inputs
)
y
=
self
.
pool2d_max
(
y
)
for
block
in
self
.
block_list
:
y
=
block
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_channels
])
y
=
self
.
out
(
y
)
return
y
def
ResNeXt50_32x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
32
,
**
args
)
return
model
return
model
def
ResNeXt50_
32x4d
(
):
def
ResNeXt50_
64x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
32
)
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
64
,
**
args
)
return
model
return
model
def
ResNeXt101_
64x4d
(
):
def
ResNeXt101_
32x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
64
)
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
32
,
**
args
)
return
model
return
model
def
ResNeXt101_
32x4d
(
):
def
ResNeXt101_
64x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
32
)
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
64
,
**
args
)
return
model
return
model
def
ResNeXt152_
64x4d
(
):
def
ResNeXt152_
32x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
64
)
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
32
,
**
args
)
return
model
return
model
def
ResNeXt152_
32x4d
(
):
def
ResNeXt152_
64x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
32
)
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
64
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/resnext_vd.py
浏览文件 @
7f80e25c
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#
#Licensed under the Apache License, Version 2.0 (the "License");
#
Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#
you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
#
#Unless required by applicable law or agreed to in writing, software
#
Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#
distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
See the License for the specific language governing permissions and
#limitations under the License.
#
limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
print_function
import
numpy
as
np
import
paddle
import
paddle
import
paddle.fluid
as
fluid
import
paddle.fluid
as
fluid
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.param_attr
import
ParamAttr
from
paddle.fluid.layer_helper
import
LayerHelper
from
paddle.fluid.dygraph.nn
import
Conv2D
,
Pool2D
,
BatchNorm
,
Linear
,
Dropout
import
math
import
math
__all__
=
[
__all__
=
[
"ResNeXt"
,
"ResNeXt50_vd_64x4d"
,
"ResNeXt101_vd_64x4d"
,
"ResNeXt50_vd_32x4d"
,
"ResNeXt50_vd_64x4d"
,
"ResNeXt101_vd_32x4d"
,
"ResNeXt152_vd_64x4d"
,
"ResNeXt50_vd_32x4d"
,
"ResNeXt101_vd_32x4d"
,
"ResNeXt101_vd_64x4d"
,
"ResNeXt152_vd_32x4d"
,
"ResNeXt152_vd_64x4d"
"ResNeXt152_vd_32x4d"
]
]
class
ResNeXt
():
class
ConvBNLayer
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
is_3x3
=
False
,
cardinality
=
64
):
def
__init__
(
self
.
layers
=
layers
self
,
self
.
is_3x3
=
is_3x3
num_channels
,
self
.
cardinality
=
cardinality
num_filters
,
filter_size
,
def
net
(
self
,
input
,
class_dim
=
1000
):
stride
=
1
,
is_3x3
=
self
.
is_3x3
groups
=
1
,
layers
=
self
.
layers
is_vd_mode
=
False
,
cardinality
=
self
.
cardinality
act
=
None
,
supported_layers
=
[
50
,
101
,
152
]
name
=
None
,
):
assert
layers
in
supported_layers
,
\
super
(
ConvBNLayer
,
self
).
__init__
()
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
if
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
num_filters1
=
[
256
,
512
,
1024
,
2048
]
num_filters2
=
[
128
,
256
,
512
,
1024
]
if
is_3x3
==
False
:
conv
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
64
,
filter_size
=
7
,
stride
=
2
,
act
=
'relu'
)
else
:
conv
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
2
,
act
=
'relu'
,
name
=
'conv1_1'
)
conv
=
self
.
conv_bn_layer
(
input
=
conv
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
'conv1_2'
)
conv
=
self
.
conv_bn_layer
(
input
=
conv
,
num_filters
=
64
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
'conv1_3'
)
conv
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
for
block
in
range
(
len
(
depth
)):
self
.
is_vd_mode
=
is_vd_mode
for
i
in
range
(
depth
[
block
]):
self
.
_pool2d_avg
=
Pool2D
(
if
layers
in
[
101
,
152
,
200
]
and
block
==
2
:
pool_size
=
2
,
pool_stride
=
2
,
pool_padding
=
0
,
pool_type
=
'avg'
)
if
i
==
0
:
self
.
_conv
=
Conv2D
(
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
num_channels
=
num_channels
,
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
conv
=
self
.
bottleneck_block
(
input
=
conv
,
num_filters
=
num_filters1
[
block
]
if
cardinality
==
64
else
num_filters2
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
cardinality
=
cardinality
,
if_first
=
block
==
0
,
name
=
conv_name
)
pool
=
fluid
.
layers
.
pool2d
(
input
=
conv
,
pool_type
=
'avg'
,
global_pooling
=
True
)
stdv
=
1.0
/
math
.
sqrt
(
pool
.
shape
[
1
]
*
1.0
)
out
=
fluid
.
layers
.
fc
(
input
=
pool
,
size
=
class_dim
,
param_attr
=
fluid
.
param_attr
.
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
'fc_weights'
),
bias_attr
=
fluid
.
param_attr
.
ParamAttr
(
name
=
'fc_offset'
))
return
out
def
conv_bn_layer
(
self
,
input
,
num_filters
,
filter_size
,
stride
=
1
,
groups
=
1
,
act
=
None
,
name
=
None
):
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
filter_size
=
filter_size
,
stride
=
stride
,
stride
=
stride
,
...
@@ -137,121 +61,209 @@ class ResNeXt():
...
@@ -137,121 +61,209 @@ class ResNeXt():
bn_name
=
"bn_"
+
name
bn_name
=
"bn_"
+
name
else
:
else
:
bn_name
=
"bn"
+
name
[
3
:]
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_n
orm
(
self
.
_batch_norm
=
BatchN
orm
(
input
=
conv
,
num_filters
,
act
=
act
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
moving_variance_name
=
bn_name
+
'_variance'
)
def
conv_bn_layer_new
(
self
,
def
forward
(
self
,
inputs
):
input
,
if
self
.
is_vd_mode
:
num_filters
,
inputs
=
self
.
_pool2d_avg
(
inputs
)
filter_size
,
y
=
self
.
_conv
(
inputs
)
stride
=
1
,
y
=
self
.
_batch_norm
(
y
)
groups
=
1
,
return
y
act
=
None
,
name
=
None
):
pool
=
fluid
.
layers
.
pool2d
(
input
=
input
,
pool_size
=
2
,
pool_stride
=
2
,
pool_padding
=
0
,
pool_type
=
'avg'
,
ceil_mode
=
True
)
conv
=
fluid
.
layers
.
conv2d
(
input
=
pool
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
1
,
padding
=
(
filter_size
-
1
)
//
2
,
groups
=
groups
,
act
=
None
,
param_attr
=
ParamAttr
(
name
=
name
+
"_weights"
),
bias_attr
=
False
)
if
name
==
"conv1"
:
bn_name
=
"bn_"
+
name
else
:
bn_name
=
"bn"
+
name
[
3
:]
return
fluid
.
layers
.
batch_norm
(
input
=
conv
,
act
=
act
,
param_attr
=
ParamAttr
(
name
=
bn_name
+
'_scale'
),
bias_attr
=
ParamAttr
(
bn_name
+
'_offset'
),
moving_mean_name
=
bn_name
+
'_mean'
,
moving_variance_name
=
bn_name
+
'_variance'
)
def
shortcut
(
self
,
input
,
ch_out
,
stride
,
name
,
if_first
=
False
):
ch_in
=
input
.
shape
[
1
]
if
ch_in
!=
ch_out
or
stride
!=
1
:
if
if_first
:
return
self
.
conv_bn_layer
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
self
.
conv_bn_layer_new
(
input
,
ch_out
,
1
,
stride
,
name
=
name
)
else
:
return
input
def
bottleneck_block
(
self
,
input
,
num_filters
,
stride
,
cardinality
,
name
,
class
BottleneckBlock
(
fluid
.
dygraph
.
Layer
):
if_first
):
def
__init__
(
self
,
conv0
=
self
.
conv_bn_layer
(
num_channels
,
input
=
input
,
num_filters
,
stride
,
cardinality
,
shortcut
=
True
,
if_first
=
False
,
name
=
None
):
super
(
BottleneckBlock
,
self
).
__init__
()
self
.
conv0
=
ConvBNLayer
(
num_channels
=
num_channels
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
'relu'
,
act
=
'relu'
,
name
=
name
+
"_branch2a"
)
name
=
name
+
"_branch2a"
)
conv1
=
self
.
conv_bn_l
ayer
(
self
.
conv1
=
ConvBNL
ayer
(
input
=
conv0
,
num_channels
=
num_filters
,
num_filters
=
num_filters
,
num_filters
=
num_filters
,
filter_size
=
3
,
filter_size
=
3
,
groups
=
cardinality
,
stride
=
stride
,
stride
=
stride
,
act
=
'relu'
,
act
=
'relu'
,
groups
=
cardinality
,
name
=
name
+
"_branch2b"
)
name
=
name
+
"_branch2b"
)
conv2
=
self
.
conv_bn_l
ayer
(
self
.
conv2
=
ConvBNL
ayer
(
input
=
conv1
,
num_channels
=
num_filters
,
num_filters
=
num_filters
if
cardinality
==
64
else
num_filters
*
2
,
num_filters
=
num_filters
*
2
if
cardinality
==
32
else
num_filters
,
filter_size
=
1
,
filter_size
=
1
,
act
=
None
,
act
=
None
,
name
=
name
+
"_branch2c"
)
name
=
name
+
"_branch2c"
)
short
=
self
.
shortcut
(
if
not
shortcut
:
input
,
self
.
short
=
ConvBNLayer
(
num_filters
if
cardinality
==
64
else
num_filters
*
2
,
num_channels
=
num_channels
,
stride
,
num_filters
=
num_filters
*
2
if_first
=
if_first
,
if
cardinality
==
32
else
num_filters
,
name
=
name
+
"_branch1"
)
filter_size
=
1
,
stride
=
1
,
is_vd_mode
=
False
if
if_first
else
True
,
name
=
name
+
"_branch1"
)
self
.
shortcut
=
shortcut
def
forward
(
self
,
inputs
):
y
=
self
.
conv0
(
inputs
)
conv1
=
self
.
conv1
(
y
)
conv2
=
self
.
conv2
(
conv1
)
if
self
.
shortcut
:
short
=
inputs
else
:
short
=
self
.
short
(
inputs
)
y
=
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
)
layer_helper
=
LayerHelper
(
self
.
full_name
(),
act
=
'relu'
)
return
layer_helper
.
append_activation
(
y
)
class
ResNeXt
(
fluid
.
dygraph
.
Layer
):
def
__init__
(
self
,
layers
=
50
,
class_dim
=
1000
,
cardinality
=
32
):
super
(
ResNeXt
,
self
).
__init__
()
self
.
layers
=
layers
self
.
cardinality
=
cardinality
supported_layers
=
[
50
,
101
,
152
]
assert
layers
in
supported_layers
,
\
"supported layers are {} but input layer is {}"
.
format
(
supported_layers
,
layers
)
supported_cardinality
=
[
32
,
64
]
assert
cardinality
in
supported_cardinality
,
\
"supported cardinality is {} but input cardinality is {}"
\
.
format
(
supported_cardinality
,
cardinality
)
if
layers
==
50
:
depth
=
[
3
,
4
,
6
,
3
]
elif
layers
==
101
:
depth
=
[
3
,
4
,
23
,
3
]
elif
layers
==
152
:
depth
=
[
3
,
8
,
36
,
3
]
num_channels
=
[
64
,
256
,
512
,
1024
]
num_filters
=
[
128
,
256
,
512
,
1024
]
if
cardinality
==
32
else
[
256
,
512
,
1024
,
2048
]
self
.
conv1_1
=
ConvBNLayer
(
num_channels
=
3
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
2
,
act
=
'relu'
,
name
=
"conv1_1"
)
self
.
conv1_2
=
ConvBNLayer
(
num_channels
=
32
,
num_filters
=
32
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
"conv1_2"
)
self
.
conv1_3
=
ConvBNLayer
(
num_channels
=
32
,
num_filters
=
64
,
filter_size
=
3
,
stride
=
1
,
act
=
'relu'
,
name
=
"conv1_3"
)
self
.
pool2d_max
=
Pool2D
(
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
self
.
block_list
=
[]
for
block
in
range
(
len
(
depth
)):
shortcut
=
False
for
i
in
range
(
depth
[
block
]):
if
layers
in
[
101
,
152
]
and
block
==
2
:
if
i
==
0
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"a"
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
"b"
+
str
(
i
)
else
:
conv_name
=
"res"
+
str
(
block
+
2
)
+
chr
(
97
+
i
)
bottleneck_block
=
self
.
add_sublayer
(
'bb_%d_%d'
%
(
block
,
i
),
BottleneckBlock
(
num_channels
=
num_channels
[
block
]
if
i
==
0
else
num_filters
[
block
]
*
int
(
64
//
self
.
cardinality
),
num_filters
=
num_filters
[
block
],
stride
=
2
if
i
==
0
and
block
!=
0
else
1
,
cardinality
=
self
.
cardinality
,
shortcut
=
shortcut
,
if_first
=
block
==
i
==
0
,
name
=
conv_name
))
self
.
block_list
.
append
(
bottleneck_block
)
shortcut
=
True
self
.
pool2d_avg
=
Pool2D
(
pool_size
=
7
,
pool_type
=
'avg'
,
global_pooling
=
True
)
self
.
pool2d_avg_channels
=
num_channels
[
-
1
]
*
2
stdv
=
1.0
/
math
.
sqrt
(
self
.
pool2d_avg_channels
*
1.0
)
self
.
out
=
Linear
(
self
.
pool2d_avg_channels
,
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
fluid
.
initializer
.
Uniform
(
-
stdv
,
stdv
),
name
=
"fc_weights"
),
bias_attr
=
ParamAttr
(
name
=
"fc_offset"
))
return
fluid
.
layers
.
elementwise_add
(
x
=
short
,
y
=
conv2
,
act
=
'relu'
)
def
forward
(
self
,
inputs
):
y
=
self
.
conv1_1
(
inputs
)
y
=
self
.
conv1_2
(
y
)
y
=
self
.
conv1_3
(
y
)
y
=
self
.
pool2d_max
(
y
)
for
block
in
self
.
block_list
:
y
=
block
(
y
)
y
=
self
.
pool2d_avg
(
y
)
y
=
fluid
.
layers
.
reshape
(
y
,
shape
=
[
-
1
,
self
.
pool2d_avg_channels
])
y
=
self
.
out
(
y
)
return
y
def
ResNeXt50_vd_
64x4d
(
):
def
ResNeXt50_vd_
32x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
50
,
is_3x3
=
True
)
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
32
,
**
args
)
return
model
return
model
def
ResNeXt50_vd_
32x4d
(
):
def
ResNeXt50_vd_
64x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
32
,
is_3x3
=
True
)
model
=
ResNeXt
(
layers
=
50
,
cardinality
=
64
,
**
args
)
return
model
return
model
def
ResNeXt101_vd_
64x4d
(
):
def
ResNeXt101_vd_
32x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
101
,
is_3x3
=
True
)
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
32
,
**
args
)
return
model
return
model
def
ResNeXt101_vd_
32x4d
(
):
def
ResNeXt101_vd_
64x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
32
,
is_3x3
=
True
)
model
=
ResNeXt
(
layers
=
101
,
cardinality
=
64
,
**
args
)
return
model
return
model
def
ResNeXt152_vd_
64x4d
(
):
def
ResNeXt152_vd_
32x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
152
,
is_3x3
=
True
)
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
32
,
**
args
)
return
model
return
model
def
ResNeXt152_vd_
32x4d
(
):
def
ResNeXt152_vd_
64x4d
(
**
args
):
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
32
,
is_3x3
=
True
)
model
=
ResNeXt
(
layers
=
152
,
cardinality
=
64
,
**
args
)
return
model
return
model
ppcls/modeling/architectures/se_resnet_vd.py
浏览文件 @
7f80e25c
此差异已折叠。
点击以展开。
ppcls/modeling/architectures/se_resnext_vd.py
浏览文件 @
7f80e25c
此差异已折叠。
点击以展开。
ppcls/modeling/architectures/shufflenet_v2.py
浏览文件 @
7f80e25c
此差异已折叠。
点击以展开。
ppcls/modeling/architectures/shufflenet_v2_swish.py
已删除
100644 → 0
浏览文件 @
0e7bea51
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from
__future__
import
absolute_import
from
__future__
import
division
from
__future__
import
print_function
import
math
import
paddle.fluid
as
fluid
from
paddle.fluid.initializer
import
MSRA
from
paddle.fluid.param_attr
import
ParamAttr
__all__
=
[
'ShuffleNetV2_x0_5_swish'
,
'ShuffleNetV2_x1_0_swish'
,
'ShuffleNetV2_x1_5_swish'
,
'ShuffleNetV2_x2_0_swish'
,
'ShuffleNetV2_swish'
]
class
ShuffleNetV2_swish
():
def
__init__
(
self
,
scale
=
1.0
):
self
.
scale
=
scale
def
net
(
self
,
input
,
class_dim
=
1000
):
scale
=
self
.
scale
stage_repeats
=
[
4
,
8
,
4
]
if
scale
==
0.5
:
stage_out_channels
=
[
-
1
,
24
,
48
,
96
,
192
,
1024
]
elif
scale
==
1.0
:
stage_out_channels
=
[
-
1
,
24
,
116
,
232
,
464
,
1024
]
elif
scale
==
1.5
:
stage_out_channels
=
[
-
1
,
24
,
176
,
352
,
704
,
1024
]
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
))
#conv1
input_channel
=
stage_out_channels
[
1
]
conv1
=
self
.
conv_bn_layer
(
input
=
input
,
filter_size
=
3
,
num_filters
=
input_channel
,
padding
=
1
,
stride
=
2
,
name
=
'stage1_conv'
)
pool1
=
fluid
.
layers
.
pool2d
(
input
=
conv1
,
pool_size
=
3
,
pool_stride
=
2
,
pool_padding
=
1
,
pool_type
=
'max'
)
conv
=
pool1
# bottleneck sequences
for
idxstage
in
range
(
len
(
stage_repeats
)):
numrepeat
=
stage_repeats
[
idxstage
]
output_channel
=
stage_out_channels
[
idxstage
+
2
]
for
i
in
range
(
numrepeat
):
if
i
==
0
:
conv
=
self
.
inverted_residual_unit
(
input
=
conv
,
num_filters
=
output_channel
,
stride
=
2
,
benchmodel
=
2
,
name
=
str
(
idxstage
+
2
)
+
'_'
+
str
(
i
+
1
))
else
:
conv
=
self
.
inverted_residual_unit
(
input
=
conv
,
num_filters
=
output_channel
,
stride
=
1
,
benchmodel
=
1
,
name
=
str
(
idxstage
+
2
)
+
'_'
+
str
(
i
+
1
))
conv_last
=
self
.
conv_bn_layer
(
input
=
conv
,
filter_size
=
1
,
num_filters
=
stage_out_channels
[
-
1
],
padding
=
0
,
stride
=
1
,
name
=
'conv5'
)
pool_last
=
fluid
.
layers
.
pool2d
(
input
=
conv_last
,
pool_size
=
7
,
pool_stride
=
1
,
pool_padding
=
0
,
pool_type
=
'avg'
)
output
=
fluid
.
layers
.
fc
(
input
=
pool_last
,
size
=
class_dim
,
param_attr
=
ParamAttr
(
initializer
=
MSRA
(),
name
=
'fc6_weights'
),
bias_attr
=
ParamAttr
(
name
=
'fc6_offset'
))
return
output
def
conv_bn_layer
(
self
,
input
,
filter_size
,
num_filters
,
stride
,
padding
,
num_groups
=
1
,
use_cudnn
=
True
,
if_act
=
True
,
name
=
None
):
conv
=
fluid
.
layers
.
conv2d
(
input
=
input
,
num_filters
=
num_filters
,
filter_size
=
filter_size
,
stride
=
stride
,
padding
=
padding
,
groups
=
num_groups
,
act
=
None
,
use_cudnn
=
use_cudnn
,
param_attr
=
ParamAttr
(
initializer
=
MSRA
(),
name
=
name
+
'_weights'
),
bias_attr
=
False
)
out
=
int
((
input
.
shape
[
2
]
-
1
)
/
float
(
stride
)
+
1
)
bn_name
=
name
+
'_bn'
if
if_act
:
return
fluid
.
layers
.
batch_norm
(
input
=
conv
,
act
=
'swish'
,
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'
)
else
:
return
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'
)
def
channel_shuffle
(
self
,
x
,
groups
):
batchsize
,
num_channels
,
height
,
width
=
x
.
shape
[
0
],
x
.
shape
[
1
],
x
.
shape
[
2
],
x
.
shape
[
3
]
channels_per_group
=
num_channels
//
groups
# reshape
x
=
fluid
.
layers
.
reshape
(
x
=
x
,
shape
=
[
batchsize
,
groups
,
channels_per_group
,
height
,
width
])
x
=
fluid
.
layers
.
transpose
(
x
=
x
,
perm
=
[
0
,
2
,
1
,
3
,
4
])
# flatten
x
=
fluid
.
layers
.
reshape
(
x
=
x
,
shape
=
[
batchsize
,
num_channels
,
height
,
width
])
return
x
def
inverted_residual_unit
(
self
,
input
,
num_filters
,
stride
,
benchmodel
,
name
=
None
):
assert
stride
in
[
1
,
2
],
\
"supported stride are {} but your stride is {}"
.
format
([
1
,
2
],
stride
)
oup_inc
=
num_filters
//
2
inp
=
input
.
shape
[
1
]
if
benchmodel
==
1
:
x1
,
x2
=
fluid
.
layers
.
split
(
input
,
num_or_sections
=
[
input
.
shape
[
1
]
//
2
,
input
.
shape
[
1
]
//
2
],
dim
=
1
)
conv_pw
=
self
.
conv_bn_layer
(
input
=
x2
,
num_filters
=
oup_inc
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
num_groups
=
1
,
if_act
=
True
,
name
=
'stage_'
+
name
+
'_conv1'
)
conv_dw
=
self
.
conv_bn_layer
(
input
=
conv_pw
,
num_filters
=
oup_inc
,
filter_size
=
3
,
stride
=
stride
,
padding
=
1
,
num_groups
=
oup_inc
,
if_act
=
False
,
use_cudnn
=
False
,
name
=
'stage_'
+
name
+
'_conv2'
)
conv_linear
=
self
.
conv_bn_layer
(
input
=
conv_dw
,
num_filters
=
oup_inc
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
num_groups
=
1
,
if_act
=
True
,
name
=
'stage_'
+
name
+
'_conv3'
)
out
=
fluid
.
layers
.
concat
([
x1
,
conv_linear
],
axis
=
1
)
else
:
#branch1
conv_dw_1
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
inp
,
filter_size
=
3
,
stride
=
stride
,
padding
=
1
,
num_groups
=
inp
,
if_act
=
False
,
use_cudnn
=
False
,
name
=
'stage_'
+
name
+
'_conv4'
)
conv_linear_1
=
self
.
conv_bn_layer
(
input
=
conv_dw_1
,
num_filters
=
oup_inc
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
num_groups
=
1
,
if_act
=
True
,
name
=
'stage_'
+
name
+
'_conv5'
)
#branch2
conv_pw_2
=
self
.
conv_bn_layer
(
input
=
input
,
num_filters
=
oup_inc
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
num_groups
=
1
,
if_act
=
True
,
name
=
'stage_'
+
name
+
'_conv1'
)
conv_dw_2
=
self
.
conv_bn_layer
(
input
=
conv_pw_2
,
num_filters
=
oup_inc
,
filter_size
=
3
,
stride
=
stride
,
padding
=
1
,
num_groups
=
oup_inc
,
if_act
=
False
,
use_cudnn
=
False
,
name
=
'stage_'
+
name
+
'_conv2'
)
conv_linear_2
=
self
.
conv_bn_layer
(
input
=
conv_dw_2
,
num_filters
=
oup_inc
,
filter_size
=
1
,
stride
=
1
,
padding
=
0
,
num_groups
=
1
,
if_act
=
True
,
name
=
'stage_'
+
name
+
'_conv3'
)
out
=
fluid
.
layers
.
concat
([
conv_linear_1
,
conv_linear_2
],
axis
=
1
)
return
self
.
channel_shuffle
(
out
,
2
)
def
ShuffleNetV2_x0_5_swish
():
model
=
ShuffleNetV2_swish
(
scale
=
0.5
)
return
model
def
ShuffleNetV2_x1_0_swish
():
model
=
ShuffleNetV2_swish
(
scale
=
1.0
)
return
model
def
ShuffleNetV2_x1_5_swish
():
model
=
ShuffleNetV2_swish
(
scale
=
1.5
)
return
model
def
ShuffleNetV2_x2_0_swish
():
model
=
ShuffleNetV2_swish
(
scale
=
2.0
)
return
model
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录