Beispiel #1
0
 def __init__(self, n_dim: int, channel: int, reduction: int = 16):
     """
     Squeeze and Excitation Layer
     https://arxiv.org/abs/1709.01507
     Parameters
     ----------
     n_dim : int
         dimensionality of convolution
     channel : int
         number of input channel
     reduction : int
         channel reduction factor
     """
     super().__init__()
     self.pool = PoolingNd('AdaptiveAvg', n_dim, 1)
     self.fc = torch.nn.Sequential(
         ConvNd(n_dim,
                channel,
                channel // reduction,
                kernel_size=1,
                bias=False), torch.nn.ReLU(inplace=True),
         ConvNd(n_dim,
                channel // reduction,
                channel,
                kernel_size=1,
                bias=False), torch.nn.Sigmoid())
Beispiel #2
0
 def __init__(self,
              num_classes: int,
              in_channels: int,
              n_dim: int = 2,
              pool_type: str = "Max"):
     super().__init__()
     self.features = torch.nn.Sequential(
         ConvNd(n_dim, in_channels, 64, kernel_size=11, stride=4,
                padding=2),
         torch.nn.ReLU(inplace=True),
         PoolingNd(pool_type, n_dim, kernel_size=3, stride=2),
         ConvNd(n_dim, 64, 192, kernel_size=5, padding=2),
         torch.nn.ReLU(inplace=True),
         PoolingNd(pool_type, n_dim, kernel_size=3, stride=2),
         ConvNd(n_dim, 192, 384, kernel_size=3, padding=1),
         torch.nn.ReLU(inplace=True),
         ConvNd(n_dim, 384, 256, kernel_size=3, padding=1),
         torch.nn.ReLU(inplace=True),
         ConvNd(n_dim, 256, 256, kernel_size=3, padding=1),
         torch.nn.ReLU(inplace=True),
         PoolingNd(pool_type, n_dim, kernel_size=3, stride=2),
     )
     self.avgpool = PoolingNd("AdaptiveAvg", n_dim, 6)
     self.classifier = torch.nn.Sequential(
         torch.nn.Dropout(),
         torch.nn.Linear(256 * pow(6, n_dim), 4096),
         torch.nn.ReLU(inplace=True),
         torch.nn.Dropout(),
         torch.nn.Linear(4096, 4096),
         torch.nn.ReLU(inplace=True),
         torch.nn.Linear(4096, num_classes),
     )
Beispiel #3
0
 def __init__(self,
              num_input_features: int,
              growth_rate: int,
              bn_size: int,
              drop_rate: float,
              n_dim: int = 2,
              norm_type: str = "Batch"):
     super().__init__()
     self.add_module('norm1', NormNd(norm_type, n_dim, num_input_features)),
     self.add_module('relu1', torch.nn.ReLU(inplace=True)),
     self.add_module(
         'conv1',
         ConvNd(n_dim,
                num_input_features,
                bn_size * growth_rate,
                kernel_size=1,
                stride=1,
                bias=False)),
     self.add_module('norm2', NormNd(norm_type, n_dim,
                                     bn_size * growth_rate)),
     self.add_module('relu2', torch.nn.ReLU(inplace=True)),
     self.add_module(
         'conv2',
         ConvNd(n_dim,
                bn_size * growth_rate,
                growth_rate,
                kernel_size=3,
                stride=1,
                padding=1,
                bias=False)),
     self.drop_rate = drop_rate
Beispiel #4
0
def _conv1x1(n_dim: int, in_channels: int, out_channels: int,
             groups: int = 1) -> ConvNd:
    """
    Creates a module containing the appropriate convolution

    Parameters
    ----------
    n_dim : int
        dimensionality of the input
    in_channels : int
        number of input channels
    out_channels : int
        number of output channels
    groups : int
        number of convolution groups

    Returns
    -------
    ConvNd
        appropriate convolution

    """
    return ConvNd(
        n_dim,
        in_channels,
        out_channels,
        kernel_size=1,
        groups=groups,
        stride=1)
Beispiel #5
0
def _conv1x1(in_planes: int,
             out_planes: int,
             stride: Union[int, Sequence[int]] = 1,
             n_dim: int = 2) -> ConvNd:
    """1x1 convolution"""
    return ConvNd(n_dim,
                  in_planes,
                  out_planes,
                  kernel_size=1,
                  stride=stride,
                  bias=False)
Beispiel #6
0
def _conv3x3(in_planes: int,
             out_planes: int,
             stride: Union[int, Sequence[int]] = 1,
             n_dim: int = 2) -> ConvNd:
    """3x3 convolution with padding"""
    return ConvNd(n_dim,
                  in_planes,
                  out_planes,
                  kernel_size=3,
                  stride=stride,
                  padding=1,
                  bias=False)
Beispiel #7
0
    def __init__(self,
                 block: torch.nn.Module,
                 layers: Sequence[int],
                 num_classes: int,
                 in_channels: int,
                 zero_init_residual: bool = False,
                 norm_layer: str = "Batch",
                 n_dim: int = 2,
                 start_filts: int = 64):
        super().__init__()

        self.start_filts = start_filts
        self.inplanes = copy.deepcopy(start_filts)
        self.conv1 = ConvNd(n_dim,
                            in_channels,
                            self.inplanes,
                            kernel_size=7,
                            stride=2,
                            padding=3,
                            bias=False)

        self.bn1 = NormNd(norm_layer, n_dim, self.inplanes)
        self.relu = torch.nn.ReLU(inplace=True)
        self.maxpool = PoolingNd("Max",
                                 n_dim=n_dim,
                                 kernel_size=3,
                                 stride=2,
                                 padding=1)

        num_layers = 0
        for idx, _layers in enumerate(layers):
            stride = 1 if idx == 0 else 2
            planes = min(self.start_filts * pow(2, idx), self.start_filts * 8)
            _local_layer = self._make_layer(block,
                                            planes,
                                            _layers,
                                            stride=stride,
                                            norm_layer=norm_layer,
                                            n_dim=n_dim)

            setattr(self, "layer%d" % (idx + 1), _local_layer)
            num_layers += 1

        self.num_layers = num_layers

        self.avgpool = PoolingNd("AdaptiveAvg", n_dim, 1)
        self.fc = torch.nn.Linear(self.inplanes, num_classes)
        self.reset_weights(zero_init_residual=zero_init_residual)
Beispiel #8
0
 def __init__(self,
              num_input_features: int,
              num_output_features: int,
              n_dim: int = 2,
              norm_type: str = "Batch"):
     super().__init__()
     self.add_module('norm', NormNd(norm_type, n_dim, num_input_features))
     self.add_module('relu', torch.nn.ReLU(inplace=True))
     self.add_module(
         'conv',
         ConvNd(n_dim,
                num_input_features,
                num_output_features,
                kernel_size=1,
                stride=1,
                bias=False))
     self.add_module('pool', PoolingNd("AdaptiveAvg", n_dim, output_size=2))
Beispiel #9
0
def _upconv2x2(n_dim: int, in_channels: int, out_channels: int,
               mode: str = 'transpose') -> torch.nn.Module:
    """
    Creates a module to perform upsampling

    Parameters
    ----------
    n_dim : int
        the dimensionality of the input
    in_channels : int
        number of input channels
    out_channels : int
        number of output channels
    mode : str
        mode for upsampling

    Returns
    -------
    torch.nn.Module
        the moule performing the upsampling (either on a convolutional basis
        or on an interpolation basis)

    """
    if mode == 'transpose':
        return ConvNd(
            n_dim,
            in_channels,
            out_channels,
            kernel_size=2,
            stride=2,
            transposed=True
        )
    else:
        # out_channels is always going to be the same
        # as in_channels
        if n_dim == 2:
            upsample_mode = "bilinear"
        elif n_dim == 3:
            upsample_mode = "trilinear"
        else:
            raise ValueError

        return torch.nn.Sequential(
            torch.nn.Upsample(mode=upsample_mode, scale_factor=2),
            _conv1x1(n_dim, in_channels, out_channels))
Beispiel #10
0
    def __init__(self,
                 in_planes,
                 out_planes,
                 kernel_size=3,
                 stride=1,
                 groups=1,
                 n_dim=2,
                 norm_type="Batch"):
        padding = (kernel_size - 1) // 2

        super().__init__(
            ConvNd(n_dim,
                   in_planes,
                   out_planes,
                   kernel_size,
                   stride,
                   padding,
                   groups=groups,
                   bias=False), NormNd(norm_type, n_dim, out_planes),
            torch.nn.ReLU6(inplace=True))
Beispiel #11
0
    def make_layers(cfg: Sequence[Union[int, str]], in_channels: int,
                    norm_type: str = None, n_dim: int = 2,
                    pool_type: str = "Max") -> torch.nn.Sequential:
        layers = []

        for v in cfg:
            if v == 'P':
                layers += [PoolingNd(pool_type, n_dim, kernel_size=2,
                                     stride=2)]
            else:
                _layers = [ConvNd(n_dim, in_channels, v, kernel_size=3,
                                  padding=1)]
                if norm_type is not None:
                    _layers.append(NormNd(norm_type, n_dim, v))

                _layers.append(torch.nn.ReLU(inplace=True))
                layers += _layers
                in_channels = v

        return torch.nn.Sequential(*layers)
Beispiel #12
0
def _conv3x3(n_dim: int, in_channels: int, out_channels: int,
             stride: Union[int, tuple, list] = 1,
             padding: Union[int, tuple, list] = 1,
             bias: bool = True, groups: int = 1) -> ConvNd:
    """
    functional interface to create appropriate convolutional layer

    Parameters
    ----------
    n_dim : int
        the dimensionality of the input
    in_channels : int
        number of input channels
    out_channels : int
        number of output channels
    stride : int or tuple or list
        convolutional strides
    padding : int or tuple or list
        convolutional padding
    bias : bool
        whether to include a bias
    groups : int
        number of convolution groups

    Returns
    -------
    ConvNd
        assembled convolution

    """
    return ConvNd(
        n_dim,
        in_channels,
        out_channels,
        kernel_size=3,
        stride=stride,
        padding=padding,
        bias=bias,
        groups=groups)
Beispiel #13
0
    def __init__(self,
                 inp,
                 oup,
                 stride,
                 expand_ratio,
                 n_dim=2,
                 norm_type="Batch"):
        super().__init__()
        self.stride = stride
        assert stride in [1, 2]

        hidden_dim = int(round(inp * expand_ratio))
        self.use_res_connect = self.stride == 1 and inp == oup

        layers = []
        if expand_ratio != 1:
            # pw
            layers.append(
                _ConvNormReLU(inp,
                              hidden_dim,
                              kernel_size=1,
                              n_dim=n_dim,
                              norm_type=norm_type))
        layers.extend([
            # dw
            _ConvNormReLU(hidden_dim,
                          hidden_dim,
                          stride=stride,
                          groups=hidden_dim,
                          n_dim=n_dim,
                          norm_type=norm_type),
            # pw-linear
            ConvNd(n_dim, hidden_dim, oup, 1, 1, 0, bias=False),
            NormNd(norm_type, n_dim, oup)
        ])
        self.conv = torch.nn.Sequential(*layers)
Beispiel #14
0
    def __init__(self,
                 in_channels: int,
                 channels: int,
                 stride: int,
                 cardinality: int,
                 width: int,
                 n_dim: int,
                 norm_layer: str,
                 reduction: int = 16):
        """
        Squeeze and Excitation ResNeXt Block
        Parameters
        ----------
        in_channels : int
            number of input channels
        stride : int
            stride of 3x3 convolution layer
        cardinality : int
            number of convolution groups
        width : int
            width of resnext block
        n_dim : int
            dimensionality of convolutions
        norm_layer : str
            type of normalization layer
        reduction : int
            reduction for se layer
        """
        super().__init__()
        out_channels = channels * self.expansion
        if cardinality == 1:
            rc = channels
        else:
            width_ratio = channels * (width / self.start_filts)
            rc = cardinality * math.floor(width_ratio)

        self.conv_reduce = ConvNd(n_dim,
                                  in_channels,
                                  rc,
                                  kernel_size=1,
                                  stride=1,
                                  padding=0,
                                  bias=False)
        self.bn_reduce = NormNd(norm_layer, n_dim, rc)
        self.relu = torch.nn.ReLU(inplace=True)

        self.conv_conv = ConvNd(n_dim,
                                rc,
                                rc,
                                kernel_size=3,
                                stride=stride,
                                padding=1,
                                groups=cardinality,
                                bias=False)
        self.bn = NormNd(norm_layer, n_dim, rc)

        self.conv_expand = ConvNd(n_dim,
                                  rc,
                                  out_channels,
                                  kernel_size=1,
                                  stride=1,
                                  padding=0,
                                  bias=False)
        self.bn_expand = NormNd(norm_layer, n_dim, out_channels)

        self.shortcut = torch.nn.Sequential()

        if in_channels != out_channels or stride != 1:
            self.shortcut.add_module(
                'shortcut_conv',
                ConvNd(n_dim,
                       in_channels,
                       out_channels,
                       kernel_size=1,
                       stride=stride,
                       padding=0,
                       bias=False))
            self.shortcut.add_module('shortcut_bn',
                                     NormNd(norm_layer, n_dim, out_channels))

        self.selayer = _SELayer(n_dim, out_channels, reduction=reduction)
Beispiel #15
0
    def __init__(self,
                 num_classes: int,
                 in_channels: int,
                 growth_rate: int = 32,
                 block_config: Sequence[int] = (6, 12, 24, 16),
                 num_init_features: int = 64,
                 bn_size: int = 4,
                 drop_rate: float = 0,
                 n_dim: int = 2,
                 pool_type: str = "Max",
                 norm_type: str = "Batch"):

        super().__init__()

        # First convolution
        self.features = torch.nn.Sequential(
            OrderedDict([
                ('conv0',
                 ConvNd(n_dim,
                        in_channels,
                        num_init_features,
                        kernel_size=7,
                        stride=2,
                        padding=3,
                        bias=False)),
                ('norm0', NormNd(norm_type, n_dim, num_init_features)),
                ('relu0', torch.nn.ReLU(inplace=True)),
                ('pool0',
                 PoolingNd(pool_type,
                           n_dim,
                           kernel_size=3,
                           stride=2,
                           padding=1)),
            ]))

        # Each denseblock
        num_features = num_init_features
        for i, num_layers in enumerate(block_config):
            block = _DenseBlock(num_layers=num_layers,
                                num_input_features=num_features,
                                bn_size=bn_size,
                                growth_rate=growth_rate,
                                drop_rate=drop_rate,
                                n_dim=n_dim,
                                norm_type=norm_type)

            self.features.add_module('denseblock%d' % (i + 1), block)
            num_features = num_features + num_layers * growth_rate

            if i != len(block_config) - 1:
                trans = _Transition(num_input_features=num_features,
                                    num_output_features=num_features // 2,
                                    n_dim=n_dim,
                                    norm_type=norm_type)
                self.features.add_module('transition%d' % (i + 1), trans)
                num_features = num_features // 2

        # Final norm
        self.features.add_module('norm5', NormNd(norm_type, n_dim,
                                                 num_features))

        self.pool = PoolingNd("AdaptiveAvg", n_dim, 1)

        # Linear layer
        self.classifier = torch.nn.Linear(num_features, num_classes)

        # Official init from torch repo.
        for m in self.modules():
            if isinstance(m, ConvNd):
                torch.nn.init.kaiming_normal_(m.conv.weight)
            elif isinstance(m, NormNd):
                if hasattr(m.norm, "weight") and m.norm.weight is not None:
                    torch.nn.init.constant_(m.norm.weight, 1)

                if hasattr(m.norm, "bias") and m.norm.bias is not None:
                    torch.nn.init.constant_(m.norm.bias, 0)
            elif isinstance(m, torch.nn.Linear):
                torch.nn.init.constant_(m.bias, 0)
Beispiel #16
0
    def __init__(self,
                 n_dim: int,
                 norm_layer: str,
                 in_channels: int,
                 start_filts: int,
                 mode: str = '7x7'):
        """
        Defines different sequences of start convolutions
        Parameters
        ----------
        n_dim : int
            dimensionality of convolutions
        norm_layer : str
            type of normlization layer
        in_channels : int
            number of input channels
        start_filts : int
            number of channels after first convolution
        mode : str
            either '7x7' for default configuration (7x7 conv) or 3x3 for
            three consecutive convolutions as proposed in
            https://arxiv.org/abs/1812.01187
        """
        super().__init__()
        self._in_channels = in_channels
        self._start_filts = start_filts
        self._mode = mode

        if mode == '7x7':
            self.convs = torch.nn.Sequential(*[
                ConvNd(n_dim,
                       in_channels,
                       self._start_filts,
                       kernel_size=7,
                       stride=2,
                       padding=3,
                       bias=False),
                NormNd(norm_layer, n_dim, self._start_filts)
            ])
        elif mode == '3x3':
            self.convs = torch.nn.Sequential(*[
                ConvNd(n_dim,
                       in_channels,
                       self._start_filts,
                       kernel_size=3,
                       stride=2,
                       padding=1,
                       bias=False),
                NormNd(norm_layer, n_dim, self._start_filts),
                ConvNd(n_dim,
                       self._start_filts,
                       self._start_filts,
                       kernel_size=3,
                       stride=1,
                       padding=1,
                       bias=False),
                NormNd(norm_layer, n_dim, self._start_filts),
                ConvNd(n_dim,
                       self._start_filts,
                       self._start_filts,
                       kernel_size=3,
                       stride=1,
                       padding=1,
                       bias=False),
                NormNd(norm_layer, n_dim, self._start_filts)
            ])
        else:
            raise ValueError('{} is not a supported mode!'.format(mode))