Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleClas
提交
4273d40a
P
PaddleClas
项目概览
PaddlePaddle
/
PaddleClas
大约 2 年 前同步成功
通知
118
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看板
未验证
提交
4273d40a
编写于
7月 31, 2020
作者:
L
littletomatodonkey
提交者:
GitHub
7月 31, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #232 from cuicheng01/dygraph
Dygraph
上级
0e7bea51
11d1c59c
变更
32
展开全部
隐藏空白更改
内联
并排
Showing
32 changed file
with
2933 addition
and
2709 deletion
+2933
-2709
configs/MobileNetV3/MobileNetV3_large_x0_35.yaml
configs/MobileNetV3/MobileNetV3_large_x0_35.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_large_x0_5.yaml
configs/MobileNetV3/MobileNetV3_large_x0_5.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_large_x0_75.yaml
configs/MobileNetV3/MobileNetV3_large_x0_75.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_large_x1_0.yaml
configs/MobileNetV3/MobileNetV3_large_x1_0.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_large_x1_25.yaml
configs/MobileNetV3/MobileNetV3_large_x1_25.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_small_x0_35.yaml
configs/MobileNetV3/MobileNetV3_small_x0_35.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_small_x0_5.yaml
configs/MobileNetV3/MobileNetV3_small_x0_5.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_small_x0_75.yaml
configs/MobileNetV3/MobileNetV3_small_x0_75.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_small_x1_0.yaml
configs/MobileNetV3/MobileNetV3_small_x1_0.yaml
+1
-1
configs/MobileNetV3/MobileNetV3_small_x1_25.yaml
configs/MobileNetV3/MobileNetV3_small_x1_25.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2.yaml
configs/ShuffleNet/ShuffleNetV2.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2_swish.yaml
configs/ShuffleNet/ShuffleNetV2_swish.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2_x0_25.yaml
configs/ShuffleNet/ShuffleNetV2_x0_25.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2_x0_33.yaml
configs/ShuffleNet/ShuffleNetV2_x0_33.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2_x0_5.yaml
configs/ShuffleNet/ShuffleNetV2_x0_5.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2_x1_5.yaml
configs/ShuffleNet/ShuffleNetV2_x1_5.yaml
+1
-1
configs/ShuffleNet/ShuffleNetV2_x2_0.yaml
configs/ShuffleNet/ShuffleNetV2_x2_0.yaml
+1
-1
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
未找到文件。
configs/MobileNetV3/MobileNetV3_large_x0_35.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
2.6
lr
:
2.6
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_large_x0_5.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
1.3
lr
:
1.3
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_large_x0_75.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
1.3
lr
:
1.3
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_large_x1_0.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
2.6
lr
:
2.6
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_large_x1_25.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.65
lr
:
0.65
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_small_x0_35.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
2.6
lr
:
2.6
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_small_x0_5.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
2.6
lr
:
2.6
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_small_x0_75.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
2.6
lr
:
2.6
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_small_x1_0.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
2.6
lr
:
2.6
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/MobileNetV3/MobileNetV3_small_x1_25.yaml
浏览文件 @
4273d40a
...
@@ -15,7 +15,7 @@ topk: 5
...
@@ -15,7 +15,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
1.3
lr
:
1.3
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.5
lr
:
0.5
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2_swish.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.5
lr
:
0.5
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2_x0_25.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.5
lr
:
0.5
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2_x0_33.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.5
lr
:
0.5
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2_x0_5.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.5
lr
:
0.5
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2_x1_5.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.25
lr
:
0.25
warmup_epoch
:
5
warmup_epoch
:
5
...
...
configs/ShuffleNet/ShuffleNetV2_x2_0.yaml
浏览文件 @
4273d40a
...
@@ -14,7 +14,7 @@ topk: 5
...
@@ -14,7 +14,7 @@ topk: 5
image_shape
:
[
3
,
224
,
224
]
image_shape
:
[
3
,
224
,
224
]
LEARNING_RATE
:
LEARNING_RATE
:
function
:
'
Cosine
Warmup
'
function
:
'
Cosine'
params
:
params
:
lr
:
0.25
lr
:
0.25
warmup_epoch
:
5
warmup_epoch
:
5
...
...
ppcls/modeling/architectures/__init__.py
浏览文件 @
4273d40a
...
@@ -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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
...
@@ -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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
...
@@ -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
浏览文件 @
4273d40a
...
@@ -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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
#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
浏览文件 @
4273d40a
此差异已折叠。
点击以展开。
ppcls/modeling/architectures/se_resnext_vd.py
浏览文件 @
4273d40a
此差异已折叠。
点击以展开。
ppcls/modeling/architectures/shufflenet_v2.py
浏览文件 @
4273d40a
此差异已折叠。
点击以展开。
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录