|
|
|
from typing import Optional, Tuple, Union |
|
|
|
from mmcv.cnn import build_activation_layer, build_conv_layer, build_norm_layer |
|
from mmengine.model import BaseModule |
|
from mmengine.registry import MODELS |
|
from torch import nn |
|
|
|
from mmdet3d.utils import ConfigType, OptConfigType, OptMultiConfig |
|
|
|
try: |
|
from MinkowskiEngine import (MinkowskiBatchNorm, MinkowskiConvolution, |
|
MinkowskiConvolutionTranspose, MinkowskiReLU, |
|
MinkowskiSyncBatchNorm, SparseTensor) |
|
from MinkowskiEngine.modules.resnet_block import BasicBlock, Bottleneck |
|
except ImportError: |
|
SparseTensor = None |
|
from mmcv.cnn.resnet import BasicBlock, Bottleneck |
|
IS_MINKOWSKI_ENGINE_AVAILABLE = False |
|
else: |
|
MODELS._register_module(MinkowskiConvolution, 'MinkowskiConvNd') |
|
MODELS._register_module(MinkowskiConvolutionTranspose, |
|
'MinkowskiConvNdTranspose') |
|
MODELS._register_module(MinkowskiBatchNorm, 'MinkowskiBN') |
|
MODELS._register_module(MinkowskiSyncBatchNorm, 'MinkowskiSyncBN') |
|
MODELS._register_module(MinkowskiReLU, 'MinkowskiReLU') |
|
IS_MINKOWSKI_ENGINE_AVAILABLE = True |
|
|
|
|
|
class MinkowskiConvModule(BaseModule): |
|
"""A minkowski engine conv block that bundles conv/norm/activation layers. |
|
|
|
Args: |
|
in_channels (int): In channels of block. |
|
out_channels (int): Out channels of block. |
|
kernel_size (int or Tuple[int]): Kernel_size of block. |
|
stride (int or Tuple[int]): Stride of the first block. Defaults to 1. |
|
dilation (int): Dilation of block. Defaults to 1. |
|
bias (bool): Whether to use bias in conv. Defaults to False. |
|
conv_cfg (:obj:`ConfigDict` or dict, optional): Config of conv layer. |
|
Defaults to None. |
|
norm_cfg (:obj:`ConfigDict` or dict): The config of normalization. |
|
Defaults to dict(type='MinkowskiBN'). |
|
act_cfg (:obj:`ConfigDict` or dict): The config of activation. |
|
Defaults to dict(type='MinkowskiReLU', inplace=True). |
|
init_cfg (:obj:`ConfigDict` or dict, optional): Initialization config. |
|
Defaults to None. |
|
""" |
|
|
|
def __init__(self, |
|
in_channels: int, |
|
out_channels: int, |
|
kernel_size: Union[int, Tuple[int, int, int]], |
|
stride: Union[int, Tuple[int, int, int]] = 1, |
|
dilation: int = 1, |
|
bias: bool = False, |
|
conv_cfg: OptConfigType = None, |
|
norm_cfg: ConfigType = dict(type='MinkowskiBN'), |
|
act_cfg: ConfigType = dict( |
|
type='MinkowskiReLU', inplace=True), |
|
init_cfg: OptMultiConfig = None, |
|
**kwargs) -> None: |
|
super().__init__(init_cfg) |
|
layers = [] |
|
if conv_cfg is None: |
|
conv_cfg = dict(type='MinkowskiConvNd') |
|
conv = build_conv_layer( |
|
conv_cfg, |
|
in_channels, |
|
out_channels, |
|
kernel_size, |
|
stride, |
|
dilation, |
|
bias, |
|
dimension=3) |
|
layers.append(conv) |
|
|
|
if norm_cfg is not None: |
|
_, norm = build_norm_layer(norm_cfg, out_channels) |
|
layers.append(norm) |
|
if act_cfg is not None: |
|
activation = build_activation_layer(act_cfg) |
|
layers.append(activation) |
|
self.net = nn.Sequential(*layers) |
|
|
|
def forward(self, x: SparseTensor) -> SparseTensor: |
|
out = self.net(x) |
|
return out |
|
|
|
|
|
class MinkowskiBasicBlock(BasicBlock, BaseModule): |
|
"""A wrapper of minkowski engine basic block. It inherits from mmengine's |
|
`BaseModule` and allows additional keyword arguments. |
|
|
|
Args: |
|
inplanes (int): In channels of block. |
|
planes (int): Out channels of block. |
|
stride (int or Tuple[int]): Stride of the first conv. Defaults to 1. |
|
dilation (int): Dilation of block. Defaults to 1. |
|
downsample (nn.Module, optional): Residual branch conv module if |
|
necessary. Defaults to None. |
|
bn_momentum (float): Momentum of batch norm layer. Defaults to 0.1. |
|
dimension (int): Dimension of minkowski convolution. Defaults to 3. |
|
init_cfg (:obj:`ConfigDict` or dict, optional): Initialization config. |
|
Defaults to None. |
|
""" |
|
|
|
def __init__(self, |
|
inplanes: int, |
|
planes: int, |
|
stride: int = 1, |
|
dilation: int = 1, |
|
downsample: Optional[nn.Module] = None, |
|
bn_momentum: float = 0.1, |
|
dimension: int = 3, |
|
init_cfg: OptConfigType = None, |
|
**kwargs): |
|
BaseModule.__init__(self, init_cfg) |
|
BasicBlock.__init__( |
|
self, |
|
inplanes, |
|
planes, |
|
stride=stride, |
|
dilation=dilation, |
|
downsample=downsample, |
|
bn_momentum=bn_momentum, |
|
dimension=dimension) |
|
|
|
|
|
class MinkowskiBottleneck(Bottleneck, BaseModule): |
|
"""A wrapper of minkowski engine bottleneck block. It inherits from |
|
mmengine's `BaseModule` and allows additional keyword arguments. |
|
|
|
Args: |
|
inplanes (int): In channels of block. |
|
planes (int): Out channels of block. |
|
stride (int or Tuple[int]): Stride of the second conv. Defaults to 1. |
|
dilation (int): Dilation of block. Defaults to 1. |
|
downsample (nn.Module, optional): Residual branch conv module if |
|
necessary. Defaults to None. |
|
bn_momentum (float): Momentum of batch norm layer. Defaults to 0.1. |
|
dimension (int): Dimension of minkowski convolution. Defaults to 3. |
|
init_cfg (:obj:`ConfigDict` or dict, optional): Initialization config. |
|
Defaults to None. |
|
""" |
|
|
|
def __init__(self, |
|
inplanes: int, |
|
planes: int, |
|
stride: int = 1, |
|
dilation: int = 1, |
|
downsample: Optional[nn.Module] = None, |
|
bn_momentum: float = 0.1, |
|
dimension: int = 3, |
|
init_cfg: OptConfigType = None, |
|
**kwargs): |
|
BaseModule.__init__(self, init_cfg) |
|
Bottleneck.__init__( |
|
self, |
|
inplanes, |
|
planes, |
|
stride=stride, |
|
dilation=dilation, |
|
downsample=downsample, |
|
bn_momentum=bn_momentum, |
|
dimension=dimension) |
|
|