-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5637ff8
commit df2d36d
Showing
232 changed files
with
34,909 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright (c) Open-MMLab. All rights reserved. | ||
# flake8: noqa | ||
from .arraymisc import * | ||
from .fileio import * | ||
from .image import * | ||
from .utils import * | ||
from .version import * | ||
from .video import * | ||
from .visualization import * | ||
|
||
# The following modules are not imported to this level, so mmcv may be used | ||
# without PyTorch. | ||
# - runner | ||
# - parallel | ||
# - op |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Copyright (c) Open-MMLab. All rights reserved. | ||
from .quantization import dequantize, quantize | ||
|
||
__all__ = ['quantize', 'dequantize'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Copyright (c) Open-MMLab. All rights reserved. | ||
import numpy as np | ||
|
||
|
||
def quantize(arr, min_val, max_val, levels, dtype=np.int64): | ||
"""Quantize an array of (-inf, inf) to [0, levels-1]. | ||
Args: | ||
arr (ndarray): Input array. | ||
min_val (scalar): Minimum value to be clipped. | ||
max_val (scalar): Maximum value to be clipped. | ||
levels (int): Quantization levels. | ||
dtype (np.type): The type of the quantized array. | ||
Returns: | ||
tuple: Quantized array. | ||
""" | ||
if not (isinstance(levels, int) and levels > 1): | ||
raise ValueError( | ||
f'levels must be a positive integer, but got {levels}') | ||
if min_val >= max_val: | ||
raise ValueError( | ||
f'min_val ({min_val}) must be smaller than max_val ({max_val})') | ||
|
||
arr = np.clip(arr, min_val, max_val) - min_val | ||
quantized_arr = np.minimum( | ||
np.floor(levels * arr / (max_val - min_val)).astype(dtype), levels - 1) | ||
|
||
return quantized_arr | ||
|
||
|
||
def dequantize(arr, min_val, max_val, levels, dtype=np.float64): | ||
"""Dequantize an array. | ||
Args: | ||
arr (ndarray): Input array. | ||
min_val (scalar): Minimum value to be clipped. | ||
max_val (scalar): Maximum value to be clipped. | ||
levels (int): Quantization levels. | ||
dtype (np.type): The type of the dequantized array. | ||
Returns: | ||
tuple: Dequantized array. | ||
""" | ||
if not (isinstance(levels, int) and levels > 1): | ||
raise ValueError( | ||
f'levels must be a positive integer, but got {levels}') | ||
if min_val >= max_val: | ||
raise ValueError( | ||
f'min_val ({min_val}) must be smaller than max_val ({max_val})') | ||
|
||
dequantized_arr = (arr + 0.5).astype(dtype) * (max_val - | ||
min_val) / levels + min_val | ||
|
||
return dequantized_arr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Copyright (c) Open-MMLab. All rights reserved. | ||
from .alexnet import AlexNet | ||
from .bricks import (ACTIVATION_LAYERS, CONV_LAYERS, NORM_LAYERS, | ||
PADDING_LAYERS, PLUGIN_LAYERS, UPSAMPLE_LAYERS, | ||
ContextBlock, Conv2d, ConvAWS2d, ConvModule, | ||
ConvTranspose2d, ConvWS2d, DepthwiseSeparableConvModule, | ||
GeneralizedAttention, HSigmoid, HSwish, Linear, MaxPool2d, | ||
NonLocal1d, NonLocal2d, NonLocal3d, Scale, Swish, | ||
build_activation_layer, build_conv_layer, | ||
build_norm_layer, build_padding_layer, build_plugin_layer, | ||
build_upsample_layer, conv_ws_2d, is_norm) | ||
from .resnet import ResNet, make_res_layer | ||
from .utils import (bias_init_with_prob, caffe2_xavier_init, constant_init, | ||
fuse_conv_bn, get_model_complexity_info, kaiming_init, | ||
normal_init, uniform_init, xavier_init) | ||
from .vgg import VGG, make_vgg_layer | ||
|
||
__all__ = [ | ||
'AlexNet', 'VGG', 'make_vgg_layer', 'ResNet', 'make_res_layer', | ||
'constant_init', 'xavier_init', 'normal_init', 'uniform_init', | ||
'kaiming_init', 'caffe2_xavier_init', 'bias_init_with_prob', 'ConvModule', | ||
'build_activation_layer', 'build_conv_layer', 'build_norm_layer', | ||
'build_padding_layer', 'build_upsample_layer', 'build_plugin_layer', | ||
'is_norm', 'NonLocal1d', 'NonLocal2d', 'NonLocal3d', 'ContextBlock', | ||
'HSigmoid', 'Swish', 'HSwish', 'GeneralizedAttention', 'ACTIVATION_LAYERS', | ||
'CONV_LAYERS', 'NORM_LAYERS', 'PADDING_LAYERS', 'UPSAMPLE_LAYERS', | ||
'PLUGIN_LAYERS', 'Scale', 'get_model_complexity_info', 'conv_ws_2d', | ||
'ConvAWS2d', 'ConvWS2d', 'fuse_conv_bn', 'DepthwiseSeparableConvModule', | ||
'Linear', 'Conv2d', 'ConvTranspose2d', 'MaxPool2d' | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Copyright (c) Open-MMLab. All rights reserved. | ||
import logging | ||
|
||
import torch.nn as nn | ||
|
||
from ..runner import load_checkpoint | ||
|
||
|
||
class AlexNet(nn.Module): | ||
"""AlexNet backbone. | ||
Args: | ||
num_classes (int): number of classes for classification. | ||
""" | ||
|
||
def __init__(self, num_classes=-1): | ||
super(AlexNet, self).__init__() | ||
self.num_classes = num_classes | ||
self.features = nn.Sequential( | ||
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2), | ||
nn.ReLU(inplace=True), | ||
nn.MaxPool2d(kernel_size=3, stride=2), | ||
nn.Conv2d(64, 192, kernel_size=5, padding=2), | ||
nn.ReLU(inplace=True), | ||
nn.MaxPool2d(kernel_size=3, stride=2), | ||
nn.Conv2d(192, 384, kernel_size=3, padding=1), | ||
nn.ReLU(inplace=True), | ||
nn.Conv2d(384, 256, kernel_size=3, padding=1), | ||
nn.ReLU(inplace=True), | ||
nn.Conv2d(256, 256, kernel_size=3, padding=1), | ||
nn.ReLU(inplace=True), | ||
nn.MaxPool2d(kernel_size=3, stride=2), | ||
) | ||
if self.num_classes > 0: | ||
self.classifier = nn.Sequential( | ||
nn.Dropout(), | ||
nn.Linear(256 * 6 * 6, 4096), | ||
nn.ReLU(inplace=True), | ||
nn.Dropout(), | ||
nn.Linear(4096, 4096), | ||
nn.ReLU(inplace=True), | ||
nn.Linear(4096, num_classes), | ||
) | ||
|
||
def init_weights(self, pretrained=None): | ||
if isinstance(pretrained, str): | ||
logger = logging.getLogger() | ||
load_checkpoint(self, pretrained, strict=False, logger=logger) | ||
elif pretrained is None: | ||
# use default initializer | ||
pass | ||
else: | ||
raise TypeError('pretrained must be a str or None') | ||
|
||
def forward(self, x): | ||
|
||
x = self.features(x) | ||
if self.num_classes > 0: | ||
x = x.view(x.size(0), 256 * 6 * 6) | ||
x = self.classifier(x) | ||
|
||
return x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from .activation import build_activation_layer | ||
from .context_block import ContextBlock | ||
from .conv import build_conv_layer | ||
from .conv2d_adaptive_padding import Conv2dAdaptivePadding | ||
from .conv_module import ConvModule | ||
from .conv_ws import ConvAWS2d, ConvWS2d, conv_ws_2d | ||
from .depthwise_separable_conv_module import DepthwiseSeparableConvModule | ||
from .generalized_attention import GeneralizedAttention | ||
from .hsigmoid import HSigmoid | ||
from .hswish import HSwish | ||
from .non_local import NonLocal1d, NonLocal2d, NonLocal3d | ||
from .norm import build_norm_layer, is_norm | ||
from .padding import build_padding_layer | ||
from .plugin import build_plugin_layer | ||
from .registry import (ACTIVATION_LAYERS, CONV_LAYERS, NORM_LAYERS, | ||
PADDING_LAYERS, PLUGIN_LAYERS, UPSAMPLE_LAYERS) | ||
from .scale import Scale | ||
from .swish import Swish | ||
from .upsample import build_upsample_layer | ||
from .wrappers import Conv2d, ConvTranspose2d, Linear, MaxPool2d | ||
|
||
__all__ = [ | ||
'ConvModule', 'build_activation_layer', 'build_conv_layer', | ||
'build_norm_layer', 'build_padding_layer', 'build_upsample_layer', | ||
'build_plugin_layer', 'is_norm', 'HSigmoid', 'HSwish', 'NonLocal1d', | ||
'NonLocal2d', 'NonLocal3d', 'ContextBlock', 'GeneralizedAttention', | ||
'ACTIVATION_LAYERS', 'CONV_LAYERS', 'NORM_LAYERS', 'PADDING_LAYERS', | ||
'UPSAMPLE_LAYERS', 'PLUGIN_LAYERS', 'Scale', 'ConvAWS2d', 'ConvWS2d', | ||
'conv_ws_2d', 'DepthwiseSeparableConvModule', 'Swish', 'Linear', | ||
'Conv2dAdaptivePadding', 'Conv2d', 'ConvTranspose2d', 'MaxPool2d' | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import torch.nn as nn | ||
|
||
from mmcv.utils import build_from_cfg | ||
from .registry import ACTIVATION_LAYERS | ||
|
||
for module in [ | ||
nn.ReLU, nn.LeakyReLU, nn.PReLU, nn.RReLU, nn.ReLU6, nn.ELU, | ||
nn.Sigmoid, nn.Tanh | ||
]: | ||
ACTIVATION_LAYERS.register_module(module=module) | ||
|
||
|
||
def build_activation_layer(cfg): | ||
"""Build activation layer. | ||
Args: | ||
cfg (dict): The activation layer config, which should contain: | ||
- type (str): Layer type. | ||
- layer args: Args needed to instantiate an activation layer. | ||
Returns: | ||
nn.Module: Created activation layer. | ||
""" | ||
return build_from_cfg(cfg, ACTIVATION_LAYERS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import torch | ||
from torch import nn | ||
|
||
from ..utils import constant_init, kaiming_init | ||
from .registry import PLUGIN_LAYERS | ||
|
||
|
||
def last_zero_init(m): | ||
if isinstance(m, nn.Sequential): | ||
constant_init(m[-1], val=0) | ||
else: | ||
constant_init(m, val=0) | ||
|
||
|
||
@PLUGIN_LAYERS.register_module() | ||
class ContextBlock(nn.Module): | ||
"""ContextBlock module in GCNet. | ||
See 'GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond' | ||
(https://arxiv.org/abs/1904.11492) for details. | ||
Args: | ||
in_channels (int): Channels of the input feature map. | ||
ratio (float): Ratio of channels of transform bottleneck | ||
pooling_type (str): Pooling method for context modeling. | ||
Options are 'att' and 'avg', stand for attention pooling and | ||
average pooling respectively. Default: 'att'. | ||
fusion_types (Sequence[str]): Fusion method for feature fusion, | ||
Options are 'channels_add', 'channel_mul', stand for channelwise | ||
addition and multiplication respectively. Default: ('channel_add',) | ||
""" | ||
|
||
_abbr_ = 'context_block' | ||
|
||
def __init__(self, | ||
in_channels, | ||
ratio, | ||
pooling_type='att', | ||
fusion_types=('channel_add', )): | ||
super(ContextBlock, self).__init__() | ||
assert pooling_type in ['avg', 'att'] | ||
assert isinstance(fusion_types, (list, tuple)) | ||
valid_fusion_types = ['channel_add', 'channel_mul'] | ||
assert all([f in valid_fusion_types for f in fusion_types]) | ||
assert len(fusion_types) > 0, 'at least one fusion should be used' | ||
self.in_channels = in_channels | ||
self.ratio = ratio | ||
self.planes = int(in_channels * ratio) | ||
self.pooling_type = pooling_type | ||
self.fusion_types = fusion_types | ||
if pooling_type == 'att': | ||
self.conv_mask = nn.Conv2d(in_channels, 1, kernel_size=1) | ||
self.softmax = nn.Softmax(dim=2) | ||
else: | ||
self.avg_pool = nn.AdaptiveAvgPool2d(1) | ||
if 'channel_add' in fusion_types: | ||
self.channel_add_conv = nn.Sequential( | ||
nn.Conv2d(self.in_channels, self.planes, kernel_size=1), | ||
nn.LayerNorm([self.planes, 1, 1]), | ||
nn.ReLU(inplace=True), # yapf: disable | ||
nn.Conv2d(self.planes, self.in_channels, kernel_size=1)) | ||
else: | ||
self.channel_add_conv = None | ||
if 'channel_mul' in fusion_types: | ||
self.channel_mul_conv = nn.Sequential( | ||
nn.Conv2d(self.in_channels, self.planes, kernel_size=1), | ||
nn.LayerNorm([self.planes, 1, 1]), | ||
nn.ReLU(inplace=True), # yapf: disable | ||
nn.Conv2d(self.planes, self.in_channels, kernel_size=1)) | ||
else: | ||
self.channel_mul_conv = None | ||
self.reset_parameters() | ||
|
||
def reset_parameters(self): | ||
if self.pooling_type == 'att': | ||
kaiming_init(self.conv_mask, mode='fan_in') | ||
self.conv_mask.inited = True | ||
|
||
if self.channel_add_conv is not None: | ||
last_zero_init(self.channel_add_conv) | ||
if self.channel_mul_conv is not None: | ||
last_zero_init(self.channel_mul_conv) | ||
|
||
def spatial_pool(self, x): | ||
batch, channel, height, width = x.size() | ||
if self.pooling_type == 'att': | ||
input_x = x | ||
# [N, C, H * W] | ||
input_x = input_x.view(batch, channel, height * width) | ||
# [N, 1, C, H * W] | ||
input_x = input_x.unsqueeze(1) | ||
# [N, 1, H, W] | ||
context_mask = self.conv_mask(x) | ||
# [N, 1, H * W] | ||
context_mask = context_mask.view(batch, 1, height * width) | ||
# [N, 1, H * W] | ||
context_mask = self.softmax(context_mask) | ||
# [N, 1, H * W, 1] | ||
context_mask = context_mask.unsqueeze(-1) | ||
# [N, 1, C, 1] | ||
context = torch.matmul(input_x, context_mask) | ||
# [N, C, 1, 1] | ||
context = context.view(batch, channel, 1, 1) | ||
else: | ||
# [N, C, 1, 1] | ||
context = self.avg_pool(x) | ||
|
||
return context | ||
|
||
def forward(self, x): | ||
# [N, C, 1, 1] | ||
context = self.spatial_pool(x) | ||
|
||
out = x | ||
if self.channel_mul_conv is not None: | ||
# [N, C, 1, 1] | ||
channel_mul_term = torch.sigmoid(self.channel_mul_conv(context)) | ||
out = out * channel_mul_term | ||
if self.channel_add_conv is not None: | ||
# [N, C, 1, 1] | ||
channel_add_term = self.channel_add_conv(context) | ||
out = out + channel_add_term | ||
|
||
return out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from torch import nn | ||
|
||
from .registry import CONV_LAYERS | ||
|
||
CONV_LAYERS.register_module('Conv1d', module=nn.Conv1d) | ||
CONV_LAYERS.register_module('Conv2d', module=nn.Conv2d) | ||
CONV_LAYERS.register_module('Conv3d', module=nn.Conv3d) | ||
CONV_LAYERS.register_module('Conv', module=nn.Conv2d) | ||
|
||
|
||
def build_conv_layer(cfg, *args, **kwargs): | ||
"""Build convolution layer. | ||
Args: | ||
cfg (None or dict): The conv layer config, which should contain: | ||
- type (str): Layer type. | ||
- layer args: Args needed to instantiate an activation layer. | ||
args (argument list): Arguments passed to the `__init__` | ||
method of the corresponding conv layer. | ||
kwargs (keyword arguments): Keyword arguments passed to the `__init__` | ||
method of the corresponding conv layer. | ||
Returns: | ||
nn.Module: Created conv layer. | ||
""" | ||
if cfg is None: | ||
cfg_ = dict(type='Conv2d') | ||
else: | ||
if not isinstance(cfg, dict): | ||
raise TypeError('cfg must be a dict') | ||
if 'type' not in cfg: | ||
raise KeyError('the cfg dict must contain the key "type"') | ||
cfg_ = cfg.copy() | ||
|
||
layer_type = cfg_.pop('type') | ||
if layer_type not in CONV_LAYERS: | ||
raise KeyError(f'Unrecognized norm type {layer_type}') | ||
else: | ||
conv_layer = CONV_LAYERS.get(layer_type) | ||
|
||
layer = conv_layer(*args, **kwargs, **cfg_) | ||
|
||
return layer |
Oops, something went wrong.