129 lines
4.6 KiB
Python
129 lines
4.6 KiB
Python
# Copyright (c) OpenMMLab. All rights reserved.
|
|
import warnings
|
|
|
|
import torch.nn as nn
|
|
from mmcv.cnn import VGG
|
|
from mmcv.runner import BaseModule
|
|
|
|
from ..builder import BACKBONES
|
|
from ..necks import ssd_neck
|
|
|
|
|
|
@BACKBONES.register_module()
|
|
class SSDVGG(VGG, BaseModule):
|
|
"""VGG Backbone network for single-shot-detection.
|
|
|
|
Args:
|
|
depth (int): Depth of vgg, from {11, 13, 16, 19}.
|
|
with_last_pool (bool): Whether to add a pooling layer at the last
|
|
of the model
|
|
ceil_mode (bool): When True, will use `ceil` instead of `floor`
|
|
to compute the output shape.
|
|
out_indices (Sequence[int]): Output from which stages.
|
|
out_feature_indices (Sequence[int]): Output from which feature map.
|
|
pretrained (str, optional): model pretrained path. Default: None
|
|
init_cfg (dict or list[dict], optional): Initialization config dict.
|
|
Default: None
|
|
input_size (int, optional): Deprecated argumment.
|
|
Width and height of input, from {300, 512}.
|
|
l2_norm_scale (float, optional) : Deprecated argumment.
|
|
L2 normalization layer init scale.
|
|
|
|
Example:
|
|
>>> self = SSDVGG(input_size=300, depth=11)
|
|
>>> self.eval()
|
|
>>> inputs = torch.rand(1, 3, 300, 300)
|
|
>>> level_outputs = self.forward(inputs)
|
|
>>> for level_out in level_outputs:
|
|
... print(tuple(level_out.shape))
|
|
(1, 1024, 19, 19)
|
|
(1, 512, 10, 10)
|
|
(1, 256, 5, 5)
|
|
(1, 256, 3, 3)
|
|
(1, 256, 1, 1)
|
|
"""
|
|
extra_setting = {
|
|
300: (256, 'S', 512, 128, 'S', 256, 128, 256, 128, 256),
|
|
512: (256, 'S', 512, 128, 'S', 256, 128, 'S', 256, 128, 'S', 256, 128),
|
|
}
|
|
|
|
def __init__(self,
|
|
depth,
|
|
with_last_pool=False,
|
|
ceil_mode=True,
|
|
out_indices=(3, 4),
|
|
out_feature_indices=(22, 34),
|
|
pretrained=None,
|
|
init_cfg=None,
|
|
input_size=None,
|
|
l2_norm_scale=None):
|
|
# TODO: in_channels for mmcv.VGG
|
|
super(SSDVGG, self).__init__(
|
|
depth,
|
|
with_last_pool=with_last_pool,
|
|
ceil_mode=ceil_mode,
|
|
out_indices=out_indices)
|
|
|
|
self.features.add_module(
|
|
str(len(self.features)),
|
|
nn.MaxPool2d(kernel_size=3, stride=1, padding=1))
|
|
self.features.add_module(
|
|
str(len(self.features)),
|
|
nn.Conv2d(512, 1024, kernel_size=3, padding=6, dilation=6))
|
|
self.features.add_module(
|
|
str(len(self.features)), nn.ReLU(inplace=True))
|
|
self.features.add_module(
|
|
str(len(self.features)), nn.Conv2d(1024, 1024, kernel_size=1))
|
|
self.features.add_module(
|
|
str(len(self.features)), nn.ReLU(inplace=True))
|
|
self.out_feature_indices = out_feature_indices
|
|
|
|
assert not (init_cfg and pretrained), \
|
|
'init_cfg and pretrained cannot be specified at the same time'
|
|
|
|
if init_cfg is not None:
|
|
self.init_cfg = init_cfg
|
|
elif isinstance(pretrained, str):
|
|
warnings.warn('DeprecationWarning: pretrained is deprecated, '
|
|
'please use "init_cfg" instead')
|
|
self.init_cfg = dict(type='Pretrained', checkpoint=pretrained)
|
|
elif pretrained is None:
|
|
self.init_cfg = [
|
|
dict(type='Kaiming', layer='Conv2d'),
|
|
dict(type='Constant', val=1, layer='BatchNorm2d'),
|
|
dict(type='Normal', std=0.01, layer='Linear'),
|
|
]
|
|
else:
|
|
raise TypeError('pretrained must be a str or None')
|
|
|
|
if input_size is not None:
|
|
warnings.warn('DeprecationWarning: input_size is deprecated')
|
|
if l2_norm_scale is not None:
|
|
warnings.warn('DeprecationWarning: l2_norm_scale in VGG is '
|
|
'deprecated, it has been moved to SSDNeck.')
|
|
|
|
def init_weights(self, pretrained=None):
|
|
super(VGG, self).init_weights()
|
|
|
|
def forward(self, x):
|
|
"""Forward function."""
|
|
outs = []
|
|
for i, layer in enumerate(self.features):
|
|
x = layer(x)
|
|
if i in self.out_feature_indices:
|
|
outs.append(x)
|
|
|
|
if len(outs) == 1:
|
|
return outs[0]
|
|
else:
|
|
return tuple(outs)
|
|
|
|
|
|
class L2Norm(ssd_neck.L2Norm):
|
|
|
|
def __init__(self, **kwargs):
|
|
super(L2Norm, self).__init__(**kwargs)
|
|
warnings.warn('DeprecationWarning: L2Norm in ssd_vgg.py '
|
|
'is deprecated, please use L2Norm in '
|
|
'mmdet/models/necks/ssd_neck.py instead')
|