Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
SOLOv2-pytorch
Commits
f603f484
Commit
f603f484
authored
Jan 14, 2019
by
Kai Chen
Browse files
Merge branch 'master' into registry
parents
62255259
a8ec6fb3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
378 additions
and
72 deletions
+378
-72
configs/mask_rcnn_r50_fpn_gn_2x.py
configs/mask_rcnn_r50_fpn_gn_2x.py
+180
-0
mmdet/models/backbones/resnet.py
mmdet/models/backbones/resnet.py
+113
-52
mmdet/models/backbones/resnext.py
mmdet/models/backbones/resnext.py
+31
-11
mmdet/models/necks/fpn.py
mmdet/models/necks/fpn.py
+1
-1
mmdet/models/utils/conv_module.py
mmdet/models/utils/conv_module.py
+6
-1
mmdet/models/utils/norm.py
mmdet/models/utils/norm.py
+47
-7
No files found.
configs/mask_rcnn_r50_fpn_gn_2x.py
0 → 100644
View file @
f603f484
# model settings
normalize
=
dict
(
type
=
'GN'
,
num_groups
=
32
,
frozen
=
False
)
model
=
dict
(
type
=
'MaskRCNN'
,
pretrained
=
'open-mmlab://contrib/resnet50_gn'
,
backbone
=
dict
(
type
=
'ResNet'
,
depth
=
50
,
num_stages
=
4
,
out_indices
=
(
0
,
1
,
2
,
3
),
frozen_stages
=
1
,
style
=
'pytorch'
,
normalize
=
normalize
),
neck
=
dict
(
type
=
'FPN'
,
in_channels
=
[
256
,
512
,
1024
,
2048
],
out_channels
=
256
,
num_outs
=
5
,
normalize
=
normalize
),
rpn_head
=
dict
(
type
=
'RPNHead'
,
in_channels
=
256
,
feat_channels
=
256
,
anchor_scales
=
[
8
],
anchor_ratios
=
[
0.5
,
1.0
,
2.0
],
anchor_strides
=
[
4
,
8
,
16
,
32
,
64
],
target_means
=
[.
0
,
.
0
,
.
0
,
.
0
],
target_stds
=
[
1.0
,
1.0
,
1.0
,
1.0
],
use_sigmoid_cls
=
True
),
bbox_roi_extractor
=
dict
(
type
=
'SingleRoIExtractor'
,
roi_layer
=
dict
(
type
=
'RoIAlign'
,
out_size
=
7
,
sample_num
=
2
),
out_channels
=
256
,
featmap_strides
=
[
4
,
8
,
16
,
32
]),
bbox_head
=
dict
(
type
=
'ConvFCBBoxHead'
,
num_shared_convs
=
4
,
num_shared_fcs
=
1
,
in_channels
=
256
,
conv_out_channels
=
256
,
fc_out_channels
=
1024
,
roi_feat_size
=
7
,
num_classes
=
81
,
target_means
=
[
0.
,
0.
,
0.
,
0.
],
target_stds
=
[
0.1
,
0.1
,
0.2
,
0.2
],
reg_class_agnostic
=
False
,
normalize
=
normalize
),
mask_roi_extractor
=
dict
(
type
=
'SingleRoIExtractor'
,
roi_layer
=
dict
(
type
=
'RoIAlign'
,
out_size
=
14
,
sample_num
=
2
),
out_channels
=
256
,
featmap_strides
=
[
4
,
8
,
16
,
32
]),
mask_head
=
dict
(
type
=
'FCNMaskHead'
,
num_convs
=
4
,
in_channels
=
256
,
conv_out_channels
=
256
,
num_classes
=
81
,
normalize
=
normalize
))
# model training and testing settings
train_cfg
=
dict
(
rpn
=
dict
(
assigner
=
dict
(
type
=
'MaxIoUAssigner'
,
pos_iou_thr
=
0.7
,
neg_iou_thr
=
0.3
,
min_pos_iou
=
0.3
,
ignore_iof_thr
=-
1
),
sampler
=
dict
(
type
=
'RandomSampler'
,
num
=
256
,
pos_fraction
=
0.5
,
neg_pos_ub
=-
1
,
add_gt_as_proposals
=
False
),
allowed_border
=
0
,
pos_weight
=-
1
,
smoothl1_beta
=
1
/
9.0
,
debug
=
False
),
rcnn
=
dict
(
assigner
=
dict
(
type
=
'MaxIoUAssigner'
,
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
min_pos_iou
=
0.5
,
ignore_iof_thr
=-
1
),
sampler
=
dict
(
type
=
'RandomSampler'
,
num
=
512
,
pos_fraction
=
0.25
,
neg_pos_ub
=-
1
,
add_gt_as_proposals
=
True
),
mask_size
=
28
,
pos_weight
=-
1
,
debug
=
False
))
test_cfg
=
dict
(
rpn
=
dict
(
nms_across_levels
=
False
,
nms_pre
=
2000
,
nms_post
=
2000
,
max_num
=
2000
,
nms_thr
=
0.7
,
min_bbox_size
=
0
),
rcnn
=
dict
(
score_thr
=
0.05
,
nms
=
dict
(
type
=
'nms'
,
iou_thr
=
0.5
),
max_per_img
=
100
,
mask_thr_binary
=
0.5
))
# dataset settings
dataset_type
=
'CocoDataset'
data_root
=
'data/coco/'
img_norm_cfg
=
dict
(
mean
=
[
123.675
,
116.28
,
103.53
],
std
=
[
58.395
,
57.12
,
57.375
],
to_rgb
=
True
)
data
=
dict
(
imgs_per_gpu
=
2
,
workers_per_gpu
=
2
,
train
=
dict
(
type
=
dataset_type
,
ann_file
=
data_root
+
'annotations/instances_train2017.json'
,
img_prefix
=
data_root
+
'train2017/'
,
img_scale
=
(
1333
,
800
),
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
,
flip_ratio
=
0.5
,
with_mask
=
True
,
with_crowd
=
True
,
with_label
=
True
),
val
=
dict
(
type
=
dataset_type
,
ann_file
=
data_root
+
'annotations/instances_val2017.json'
,
img_prefix
=
data_root
+
'val2017/'
,
img_scale
=
(
1333
,
800
),
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
,
flip_ratio
=
0
,
with_mask
=
True
,
with_crowd
=
True
,
with_label
=
True
),
test
=
dict
(
type
=
dataset_type
,
ann_file
=
data_root
+
'annotations/instances_val2017.json'
,
img_prefix
=
data_root
+
'val2017/'
,
img_scale
=
(
1333
,
800
),
img_norm_cfg
=
img_norm_cfg
,
size_divisor
=
32
,
flip_ratio
=
0
,
with_mask
=
False
,
with_label
=
False
,
test_mode
=
True
))
# optimizer
optimizer
=
dict
(
type
=
'SGD'
,
lr
=
0.02
,
momentum
=
0.9
,
weight_decay
=
0.0001
)
optimizer_config
=
dict
(
grad_clip
=
dict
(
max_norm
=
35
,
norm_type
=
2
))
# learning policy
lr_config
=
dict
(
policy
=
'step'
,
warmup
=
'linear'
,
warmup_iters
=
500
,
warmup_ratio
=
1.0
/
3
,
step
=
[
16
,
22
])
checkpoint_config
=
dict
(
interval
=
1
)
# yapf:disable
log_config
=
dict
(
interval
=
50
,
hooks
=
[
dict
(
type
=
'TextLoggerHook'
),
# dict(type='TensorboardLoggerHook')
])
# yapf:enable
# runtime settings
total_epochs
=
24
dist_params
=
dict
(
backend
=
'nccl'
)
log_level
=
'INFO'
work_dir
=
'./work_dirs/mask_rcnn_r50_fpn_gn_2x'
load_from
=
None
resume_from
=
None
workflow
=
[(
'train'
,
1
)]
mmdet/models/backbones/resnet.py
View file @
f603f484
...
...
@@ -5,6 +5,7 @@ import torch.utils.checkpoint as cp
from
mmcv.cnn
import
constant_init
,
kaiming_init
from
mmcv.runner
import
load_checkpoint
from
..utils
import
build_norm_layer
from
..registry
import
BACKBONES
...
...
@@ -31,27 +32,41 @@ class BasicBlock(nn.Module):
dilation
=
1
,
downsample
=
None
,
style
=
'pytorch'
,
with_cp
=
False
):
with_cp
=
False
,
normalize
=
dict
(
type
=
'BN'
)):
super
(
BasicBlock
,
self
).
__init__
()
self
.
norm1_name
,
norm1
=
build_norm_layer
(
normalize
,
planes
,
postfix
=
1
)
self
.
norm2_name
,
norm2
=
build_norm_layer
(
normalize
,
planes
,
postfix
=
2
)
self
.
conv1
=
conv3x3
(
inplanes
,
planes
,
stride
,
dilation
)
self
.
bn1
=
nn
.
BatchNorm2d
(
planes
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
add_module
(
self
.
norm1_name
,
norm1
)
self
.
conv2
=
conv3x3
(
planes
,
planes
)
self
.
bn2
=
nn
.
BatchNorm2d
(
planes
)
self
.
add_module
(
self
.
norm2_name
,
norm2
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
downsample
=
downsample
self
.
stride
=
stride
self
.
dilation
=
dilation
assert
not
with_cp
@
property
def
norm1
(
self
):
return
getattr
(
self
,
self
.
norm1_name
)
@
property
def
norm2
(
self
):
return
getattr
(
self
,
self
.
norm2_name
)
def
forward
(
self
,
x
):
identity
=
x
out
=
self
.
conv1
(
x
)
out
=
self
.
b
n1
(
out
)
out
=
self
.
n
orm
1
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv2
(
out
)
out
=
self
.
b
n2
(
out
)
out
=
self
.
n
orm
2
(
out
)
if
self
.
downsample
is
not
None
:
identity
=
self
.
downsample
(
x
)
...
...
@@ -72,7 +87,8 @@ class Bottleneck(nn.Module):
dilation
=
1
,
downsample
=
None
,
style
=
'pytorch'
,
with_cp
=
False
):
with_cp
=
False
,
normalize
=
dict
(
type
=
'BN'
)):
"""Bottleneck block for ResNet.
If style is "pytorch", the stride-two layer is the 3x3 conv layer,
if it is "caffe", the stride-two layer is the first 1x1 conv layer.
...
...
@@ -81,18 +97,27 @@ class Bottleneck(nn.Module):
assert
style
in
[
'pytorch'
,
'caffe'
]
self
.
inplanes
=
inplanes
self
.
planes
=
planes
self
.
normalize
=
normalize
if
style
==
'pytorch'
:
self
.
conv1_stride
=
1
self
.
conv2_stride
=
stride
else
:
self
.
conv1_stride
=
stride
self
.
conv2_stride
=
1
self
.
norm1_name
,
norm1
=
build_norm_layer
(
normalize
,
planes
,
postfix
=
1
)
self
.
norm2_name
,
norm2
=
build_norm_layer
(
normalize
,
planes
,
postfix
=
2
)
self
.
norm3_name
,
norm3
=
build_norm_layer
(
normalize
,
planes
*
self
.
expansion
,
postfix
=
3
)
self
.
conv1
=
nn
.
Conv2d
(
inplanes
,
planes
,
kernel_size
=
1
,
stride
=
self
.
conv1_stride
,
bias
=
False
)
self
.
add_module
(
self
.
norm1_name
,
norm1
)
self
.
conv2
=
nn
.
Conv2d
(
planes
,
planes
,
...
...
@@ -101,17 +126,29 @@ class Bottleneck(nn.Module):
padding
=
dilation
,
dilation
=
dilation
,
bias
=
False
)
self
.
bn1
=
nn
.
BatchNorm2d
(
planes
)
self
.
bn2
=
nn
.
BatchNorm2d
(
planes
)
self
.
add_module
(
self
.
norm2_name
,
norm2
)
self
.
conv3
=
nn
.
Conv2d
(
planes
,
planes
*
self
.
expansion
,
kernel_size
=
1
,
bias
=
False
)
self
.
bn3
=
nn
.
BatchNorm2d
(
planes
*
self
.
expansion
)
self
.
add_module
(
self
.
norm3_name
,
norm3
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
downsample
=
downsample
self
.
stride
=
stride
self
.
dilation
=
dilation
self
.
with_cp
=
with_cp
self
.
normalize
=
normalize
@
property
def
norm1
(
self
):
return
getattr
(
self
,
self
.
norm1_name
)
@
property
def
norm2
(
self
):
return
getattr
(
self
,
self
.
norm2_name
)
@
property
def
norm3
(
self
):
return
getattr
(
self
,
self
.
norm3_name
)
def
forward
(
self
,
x
):
...
...
@@ -119,15 +156,15 @@ class Bottleneck(nn.Module):
identity
=
x
out
=
self
.
conv1
(
x
)
out
=
self
.
b
n1
(
out
)
out
=
self
.
n
orm
1
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv2
(
out
)
out
=
self
.
b
n2
(
out
)
out
=
self
.
n
orm
2
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv3
(
out
)
out
=
self
.
b
n3
(
out
)
out
=
self
.
n
orm
3
(
out
)
if
self
.
downsample
is
not
None
:
identity
=
self
.
downsample
(
x
)
...
...
@@ -153,7 +190,8 @@ def make_res_layer(block,
stride
=
1
,
dilation
=
1
,
style
=
'pytorch'
,
with_cp
=
False
):
with_cp
=
False
,
normalize
=
dict
(
type
=
'BN'
)):
downsample
=
None
if
stride
!=
1
or
inplanes
!=
planes
*
block
.
expansion
:
downsample
=
nn
.
Sequential
(
...
...
@@ -163,7 +201,7 @@ def make_res_layer(block,
kernel_size
=
1
,
stride
=
stride
,
bias
=
False
),
nn
.
BatchNorm2d
(
planes
*
block
.
expansion
),
build_norm_layer
(
normalize
,
planes
*
block
.
expansion
)
[
1
]
,
)
layers
=
[]
...
...
@@ -175,11 +213,13 @@ def make_res_layer(block,
dilation
,
downsample
,
style
=
style
,
with_cp
=
with_cp
))
with_cp
=
with_cp
,
normalize
=
normalize
))
inplanes
=
planes
*
block
.
expansion
for
i
in
range
(
1
,
blocks
):
layers
.
append
(
block
(
inplanes
,
planes
,
1
,
dilation
,
style
=
style
,
with_cp
=
with_cp
))
block
(
inplanes
,
planes
,
1
,
dilation
,
style
=
style
,
with_cp
=
with_cp
,
normalize
=
normalize
))
return
nn
.
Sequential
(
*
layers
)
...
...
@@ -199,11 +239,14 @@ class ResNet(nn.Module):
the first 1x1 conv layer.
frozen_stages (int): Stages to be frozen (all param fixed). -1 means
not freezing any parameters.
bn_eval (bool): Whether to set BN layers to eval mode, namely, freeze
running stats (mean and var).
bn_frozen (bool): Whether to freeze weight and bias of BN layers.
normalize (dict): dictionary to construct and config norm layer.
norm_eval (bool): Whether to set norm layers to eval mode, namely,
freeze running stats (mean and var). Note: Effect on Batch Norm
and its variants only.
with_cp (bool): Use checkpoint or not. Using checkpoint will save some
memory while slowing down the training speed.
zero_init_residual (bool): whether to use zero init for last norm layer
in resblocks to let them behave as identity.
"""
arch_settings
=
{
...
...
@@ -222,9 +265,12 @@ class ResNet(nn.Module):
out_indices
=
(
0
,
1
,
2
,
3
),
style
=
'pytorch'
,
frozen_stages
=-
1
,
bn_eval
=
True
,
bn_frozen
=
False
,
with_cp
=
False
):
normalize
=
dict
(
type
=
'BN'
,
frozen
=
False
),
norm_eval
=
True
,
with_cp
=
False
,
zero_init_residual
=
True
):
super
(
ResNet
,
self
).
__init__
()
if
depth
not
in
self
.
arch_settings
:
raise
KeyError
(
'invalid depth {} for resnet'
.
format
(
depth
))
...
...
@@ -238,19 +284,15 @@ class ResNet(nn.Module):
assert
max
(
out_indices
)
<
num_stages
self
.
style
=
style
self
.
frozen_stages
=
frozen_stages
self
.
bn_eval
=
bn_eval
self
.
bn_frozen
=
bn_frozen
self
.
normalize
=
normalize
self
.
with_cp
=
with_cp
self
.
norm_eval
=
norm_eval
self
.
zero_init_residual
=
zero_init_residual
self
.
block
,
stage_blocks
=
self
.
arch_settings
[
depth
]
self
.
stage_blocks
=
stage_blocks
[:
num_stages
]
self
.
inplanes
=
64
self
.
conv1
=
nn
.
Conv2d
(
3
,
64
,
kernel_size
=
7
,
stride
=
2
,
padding
=
3
,
bias
=
False
)
self
.
bn1
=
nn
.
BatchNorm2d
(
64
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
maxpool
=
nn
.
MaxPool2d
(
kernel_size
=
3
,
stride
=
2
,
padding
=
1
)
self
.
_make_stem_layer
()
self
.
res_layers
=
[]
for
i
,
num_blocks
in
enumerate
(
self
.
stage_blocks
):
...
...
@@ -265,15 +307,42 @@ class ResNet(nn.Module):
stride
=
stride
,
dilation
=
dilation
,
style
=
self
.
style
,
with_cp
=
with_cp
)
with_cp
=
with_cp
,
normalize
=
normalize
)
self
.
inplanes
=
planes
*
self
.
block
.
expansion
layer_name
=
'layer{}'
.
format
(
i
+
1
)
self
.
add_module
(
layer_name
,
res_layer
)
self
.
res_layers
.
append
(
layer_name
)
self
.
_freeze_stages
()
self
.
feat_dim
=
self
.
block
.
expansion
*
64
*
2
**
(
len
(
self
.
stage_blocks
)
-
1
)
@
property
def
norm1
(
self
):
return
getattr
(
self
,
self
.
norm1_name
)
def
_make_stem_layer
(
self
):
self
.
conv1
=
nn
.
Conv2d
(
3
,
64
,
kernel_size
=
7
,
stride
=
2
,
padding
=
3
,
bias
=
False
)
self
.
norm1_name
,
norm1
=
build_norm_layer
(
self
.
normalize
,
64
,
postfix
=
1
)
self
.
add_module
(
self
.
norm1_name
,
norm1
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
maxpool
=
nn
.
MaxPool2d
(
kernel_size
=
3
,
stride
=
2
,
padding
=
1
)
def
_freeze_stages
(
self
):
if
self
.
frozen_stages
>=
0
:
for
m
in
[
self
.
conv1
,
self
.
norm1
]:
for
param
in
m
.
parameters
():
param
.
requires_grad
=
False
for
i
in
range
(
1
,
self
.
frozen_stages
+
1
):
m
=
getattr
(
self
,
'layer{}'
.
format
(
i
))
for
param
in
m
.
parameters
():
param
.
requires_grad
=
False
def
init_weights
(
self
,
pretrained
=
None
):
if
isinstance
(
pretrained
,
str
):
logger
=
logging
.
getLogger
()
...
...
@@ -282,14 +351,21 @@ class ResNet(nn.Module):
for
m
in
self
.
modules
():
if
isinstance
(
m
,
nn
.
Conv2d
):
kaiming_init
(
m
)
elif
isinstance
(
m
,
nn
.
BatchNorm2d
):
elif
isinstance
(
m
,
(
nn
.
BatchNorm2d
,
nn
.
GroupNorm
)
):
constant_init
(
m
,
1
)
if
self
.
zero_init_residual
:
for
m
in
self
.
modules
():
if
isinstance
(
m
,
Bottleneck
):
constant_init
(
m
.
norm3
,
0
)
elif
isinstance
(
m
,
BasicBlock
):
constant_init
(
m
.
norm2
,
0
)
else
:
raise
TypeError
(
'pretrained must be a str or None'
)
def
forward
(
self
,
x
):
x
=
self
.
conv1
(
x
)
x
=
self
.
b
n1
(
x
)
x
=
self
.
n
orm
1
(
x
)
x
=
self
.
relu
(
x
)
x
=
self
.
maxpool
(
x
)
outs
=
[]
...
...
@@ -305,23 +381,8 @@ class ResNet(nn.Module):
def
train
(
self
,
mode
=
True
):
super
(
ResNet
,
self
).
train
(
mode
)
if
self
.
b
n_eval
:
if
mode
and
self
.
n
orm
_eval
:
for
m
in
self
.
modules
():
# trick: eval have effect on BatchNorm only
if
isinstance
(
m
,
nn
.
BatchNorm2d
):
m
.
eval
()
if
self
.
bn_frozen
:
for
params
in
m
.
parameters
():
params
.
requires_grad
=
False
if
mode
and
self
.
frozen_stages
>=
0
:
for
param
in
self
.
conv1
.
parameters
():
param
.
requires_grad
=
False
for
param
in
self
.
bn1
.
parameters
():
param
.
requires_grad
=
False
self
.
bn1
.
eval
()
self
.
bn1
.
weight
.
requires_grad
=
False
self
.
bn1
.
bias
.
requires_grad
=
False
for
i
in
range
(
1
,
self
.
frozen_stages
+
1
):
mod
=
getattr
(
self
,
'layer{}'
.
format
(
i
))
mod
.
eval
()
for
param
in
mod
.
parameters
():
param
.
requires_grad
=
False
mmdet/models/backbones/resnext.py
View file @
f603f484
...
...
@@ -5,6 +5,7 @@ import torch.nn as nn
from
.resnet
import
ResNet
from
.resnet
import
Bottleneck
as
_Bottleneck
from
..registry
import
BACKBONES
from
..utils
import
build_norm_layer
class
Bottleneck
(
_Bottleneck
):
...
...
@@ -21,13 +22,23 @@ class Bottleneck(_Bottleneck):
else
:
width
=
math
.
floor
(
self
.
planes
*
(
base_width
/
64
))
*
groups
self
.
norm1_name
,
norm1
=
build_norm_layer
(
self
.
normalize
,
width
,
postfix
=
1
)
self
.
norm2_name
,
norm2
=
build_norm_layer
(
self
.
normalize
,
width
,
postfix
=
2
)
self
.
norm3_name
,
norm3
=
build_norm_layer
(
self
.
normalize
,
self
.
planes
*
self
.
expansion
,
postfix
=
3
)
self
.
conv1
=
nn
.
Conv2d
(
self
.
inplanes
,
width
,
kernel_size
=
1
,
stride
=
self
.
conv1_stride
,
bias
=
False
)
self
.
bn1
=
nn
.
BatchNorm2d
(
width
)
self
.
add_module
(
self
.
norm1_name
,
norm1
)
self
.
conv2
=
nn
.
Conv2d
(
width
,
width
,
...
...
@@ -37,10 +48,10 @@ class Bottleneck(_Bottleneck):
dilation
=
self
.
dilation
,
groups
=
groups
,
bias
=
False
)
self
.
bn2
=
nn
.
BatchNorm2d
(
width
)
self
.
add_module
(
self
.
norm2_name
,
norm2
)
self
.
conv3
=
nn
.
Conv2d
(
width
,
self
.
planes
*
self
.
expansion
,
kernel_size
=
1
,
bias
=
False
)
self
.
bn3
=
nn
.
BatchNorm2d
(
self
.
planes
*
self
.
expansion
)
self
.
add_module
(
self
.
norm3_name
,
norm3
)
def
make_res_layer
(
block
,
...
...
@@ -52,7 +63,8 @@ def make_res_layer(block,
groups
=
1
,
base_width
=
4
,
style
=
'pytorch'
,
with_cp
=
False
):
with_cp
=
False
,
normalize
=
dict
(
type
=
'BN'
)):
downsample
=
None
if
stride
!=
1
or
inplanes
!=
planes
*
block
.
expansion
:
downsample
=
nn
.
Sequential
(
...
...
@@ -62,7 +74,7 @@ def make_res_layer(block,
kernel_size
=
1
,
stride
=
stride
,
bias
=
False
),
nn
.
BatchNorm2d
(
planes
*
block
.
expansion
),
build_norm_layer
(
normalize
,
planes
*
block
.
expansion
)
[
1
]
,
)
layers
=
[]
...
...
@@ -76,7 +88,8 @@ def make_res_layer(block,
groups
=
groups
,
base_width
=
base_width
,
style
=
style
,
with_cp
=
with_cp
))
with_cp
=
with_cp
,
normalize
=
normalize
))
inplanes
=
planes
*
block
.
expansion
for
i
in
range
(
1
,
blocks
):
layers
.
append
(
...
...
@@ -88,7 +101,8 @@ def make_res_layer(block,
groups
=
groups
,
base_width
=
base_width
,
style
=
style
,
with_cp
=
with_cp
))
with_cp
=
with_cp
,
normalize
=
normalize
))
return
nn
.
Sequential
(
*
layers
)
...
...
@@ -110,11 +124,14 @@ class ResNeXt(ResNet):
the first 1x1 conv layer.
frozen_stages (int): Stages to be frozen (all param fixed). -1 means
not freezing any parameters.
bn_eval (bool): Whether to set BN layers to eval mode, namely, freeze
running stats (mean and var).
bn_frozen (bool): Whether to freeze weight and bias of BN layers.
normalize (dict): dictionary to construct and config norm layer.
norm_eval (bool): Whether to set norm layers to eval mode, namely,
freeze running stats (mean and var). Note: Effect on Batch Norm
and its variants only.
with_cp (bool): Use checkpoint or not. Using checkpoint will save some
memory while slowing down the training speed.
zero_init_residual (bool): whether to use zero init for last norm layer
in resblocks to let them behave as identity.
"""
arch_settings
=
{
...
...
@@ -144,8 +161,11 @@ class ResNeXt(ResNet):
groups
=
self
.
groups
,
base_width
=
self
.
base_width
,
style
=
self
.
style
,
with_cp
=
self
.
with_cp
)
with_cp
=
self
.
with_cp
,
normalize
=
self
.
normalize
)
self
.
inplanes
=
planes
*
self
.
block
.
expansion
layer_name
=
'layer{}'
.
format
(
i
+
1
)
self
.
add_module
(
layer_name
,
res_layer
)
self
.
res_layers
.
append
(
layer_name
)
self
.
_freeze_stages
()
mmdet/models/necks/fpn.py
View file @
f603f484
import
torch.nn
as
nn
import
torch.nn.functional
as
F
from
mmcv.cnn
import
xavier_init
from
..utils
import
ConvModule
from
..utils
import
xavier_init
from
..registry
import
NECKS
...
...
mmdet/models/utils/conv_module.py
View file @
f603f484
...
...
@@ -53,7 +53,8 @@ class ConvModule(nn.Module):
if
self
.
with_norm
:
norm_channels
=
out_channels
if
self
.
activate_last
else
in_channels
self
.
norm
=
build_norm_layer
(
normalize
,
norm_channels
)
self
.
norm_name
,
norm
=
build_norm_layer
(
normalize
,
norm_channels
)
self
.
add_module
(
self
.
norm_name
,
norm
)
if
self
.
with_activatation
:
assert
activation
in
[
'relu'
],
'Only ReLU supported.'
...
...
@@ -63,6 +64,10 @@ class ConvModule(nn.Module):
# Default using msra init
self
.
init_weights
()
@
property
def
norm
(
self
):
return
getattr
(
self
,
self
.
norm_name
)
def
init_weights
(
self
):
nonlinearity
=
'relu'
if
self
.
activation
is
None
else
self
.
activation
kaiming_init
(
self
.
conv
,
nonlinearity
=
nonlinearity
)
...
...
mmdet/models/utils/norm.py
View file @
f603f484
import
torch.nn
as
nn
norm_cfg
=
{
'BN'
:
nn
.
BatchNorm2d
,
'SyncBN'
:
None
,
'GN'
:
None
}
norm_cfg
=
{
# format: layer_type: (abbreviation, module)
'BN'
:
(
'bn'
,
nn
.
BatchNorm2d
),
'SyncBN'
:
(
'bn'
,
None
),
'GN'
:
(
'gn'
,
nn
.
GroupNorm
),
# and potentially 'SN'
}
def
build_norm_layer
(
cfg
,
num_features
):
def
build_norm_layer
(
cfg
,
num_features
,
postfix
=
''
):
""" Build normalization layer
Args:
cfg (dict): cfg should contain:
type (str): identify norm layer type.
layer args: args needed to instantiate a norm layer.
frozen (bool): [optional] whether stop gradient updates
of norm layer, it is helpful to set frozen mode
in backbone's norms.
num_features (int): number of channels from input
postfix (int, str): appended into norm abbreation to
create named layer.
Returns:
name (str): abbreation + postfix
layer (nn.Module): created norm layer
"""
assert
isinstance
(
cfg
,
dict
)
and
'type'
in
cfg
cfg_
=
cfg
.
copy
()
cfg_
.
setdefault
(
'eps'
,
1e-5
)
layer_type
=
cfg_
.
pop
(
'type'
)
layer_type
=
cfg_
.
pop
(
'type'
)
if
layer_type
not
in
norm_cfg
:
raise
KeyError
(
'Unrecognized norm type {}'
.
format
(
layer_type
))
elif
norm_cfg
[
layer_type
]
is
None
:
raise
NotImplementedError
else
:
abbr
,
norm_layer
=
norm_cfg
[
layer_type
]
if
norm_layer
is
None
:
raise
NotImplementedError
assert
isinstance
(
postfix
,
(
int
,
str
))
name
=
abbr
+
str
(
postfix
)
frozen
=
cfg_
.
pop
(
'frozen'
,
False
)
cfg_
.
setdefault
(
'eps'
,
1e-5
)
if
layer_type
!=
'GN'
:
layer
=
norm_layer
(
num_features
,
**
cfg_
)
else
:
assert
'num_groups'
in
cfg_
layer
=
norm_layer
(
num_channels
=
num_features
,
**
cfg_
)
if
frozen
:
for
param
in
layer
.
parameters
():
param
.
requires_grad
=
False
return
n
orm_cfg
[
layer_type
](
num_features
,
**
cfg_
)
return
n
ame
,
layer
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment