Example #1
0
 def __init__(self, layer):
     # yapf: disable
     layers = [
         Parallel([nn.Identity(), layer]),
         Sum()
     ]
     # yapf: enable
     super().__init__(*layers)
Example #2
0
    def __init__(self,
                 in_feats_shapes: Sequence[Tuple[int, ...]],
                 hidden_channels: int = 256,
                 out_channels: int = 2):
        """Constructor.

        Args:
            in_feats_shapes (Sequence[Tuple[int, ...]]): Shapes of the feature
                maps that will be fed into the network. These are expected to
                be tuples of the form (., C, H, ...).
            hidden_channels (int, optional): The number of channels to which
                all feature maps are convereted before being added together.
                Defaults to 256.
            out_channels (int, optional): Number of output channels. This will
                normally be the number of classes. Defaults to 2.
        """
        # reverse so that the deepest (i.e. produced by the deepest layer in
        # the backbone network) feature map is first.
        in_feats_shapes = in_feats_shapes[::-1]
        in_feats_channels = [s[1] for s in in_feats_shapes]

        # 1x1 conv to make the channels of all feature maps the same
        in_convs = Parallel([
            nn.Conv2d(in_channels, hidden_channels, kernel_size=1)
            for in_channels in in_feats_channels
        ])
        upsample_and_add = SequentialMultiInputMultiOutput(*[
            Residual(
                Interpolate(size=s[2:], mode='bilinear', align_corners=False))
            for s in in_feats_shapes
        ])
        out_convs = Parallel([
            nn.Conv2d(hidden_channels, out_channels, kernel_size=3, padding=1)
            for s in in_feats_shapes
        ])
        # yapf: disable
        layers = [
            Reverse(),
            in_convs,
            upsample_and_add,
            out_convs,
            Reverse()
        ]
        # yapf: enable
        super().__init__(*layers)
Example #3
0
def make_fused_backbone(old_backbone: nn.Module, new_backbone: nn.Module,
                        featureMapExtractorCls: Type,
                        channel_split: Tuple[int, int]) -> nn.Module:
    """Create a fused backbone using FuseNet style feature fusion.
    See the paper, "FuseNet", by Hazirbas et al., 
    https://vision.in.tum.de/_media/spezial/bib/hazirbasma2016fusenet.pdf.
    """
    backbone = nn.Sequential(
        SplitTensor(channel_split, dim=1),
        Parallel([nn.Identity(),
                  featureMapExtractorCls(new_backbone)]),
        featureMapExtractorCls(old_backbone, mode='fusion'))
    return backbone
Example #4
0
    def _make_upsamplers(cls,
                         in_channels: int,
                         size: int,
                         num_upsamples_per_layer: Iterable[int],
                         num_groups: int = 32) -> Parallel:
        layers = []
        for num_upsamples in num_upsamples_per_layer:
            upsampler = cls._upsample_feat(in_channels=in_channels,
                                           num_upsamples=num_upsamples,
                                           size=size,
                                           num_groups=num_groups)
            layers.append(upsampler)

        upsamplers = Parallel(layers)
        return upsamplers
Example #5
0
 def __init__(self, model: nn.Module, mode: Optional[str] = None):
     super().__init__()
     self.mode = mode
     # yapf: disable
     stem = nn.Sequential(
         model.conv1,
         model.bn1,
         model.relu,
         model.maxpool
     )
     layers = [
         model.layer1,
         model.layer2,
         model.layer3,
         model.layer4,
     ]
     # yapf: enable
     if mode == 'fusion':
         self.m = nn.Sequential(
             Parallel([stem, nn.Identity()]),
             SequentialMultiInputMultiOutput(
                 *[nn.Sequential(Sum(), m) for m in layers]))
     else:
         self.m = SequentialMultiOutput(stem, *layers)
Example #6
0
    def __init__(self,
                 in_feats_shapes: Sequence[Tuple[int, ...]],
                 hidden_channels: int = 256,
                 out_channels: int = 2,
                 out_size: Optional[int] = None,
                 num_upsamples_per_layer: Optional[Sequence[int]] = None,
                 upsamplng_factor: int = 2,
                 num_groups_for_norm: int = 32):
        """Constructor.

        Args:
            in_feats_shapes (Sequence[Tuple[int, ...]]): Shapes of the feature
                maps that will be fed into the network. These are expected to
                be tuples of the form (., C, H, ...).
            hidden_channels (int, optional): The number of channels to which
                all feature maps are convereted before being added together.
                Defaults to 256.
            out_channels (int, optional): Number of output channels. This will
                normally be the number of classes. Defaults to 2.
            out_size (Optional[int], optional): Size of output. If None, 
                the size of the first feature map will be used.
                Defaults to None.
            num_upsamples_per_layer (Optional[Sequence[int]], optional): Number
                of upsampling iterations for each feature map. Will depend on
                the size of the feature map. Each upsampling iteration
                comprises a conv-group_norm-relu block followed by a scaling
                using torch.nn.functional.interpolate.
                If None, each feature map is assumed to be half the size of the
                preceeding one, meaning that it requires one more upsampling
                iteration than the last one.
                Defaults to None.
            upsamplng_factor (int, optional): How much to scale per upsampling
                iteration. Defaults to 2.
            num_groups_for_norm (int, optional): Number of groups for group
                norm layers. Defaults to 32.
        """
        if num_upsamples_per_layer is None:
            num_upsamples_per_layer = list(range(len(in_feats_shapes)))

        if out_size is None:
            out_size = in_feats_shapes[0][-2:]

        in_convs = Parallel([
            nn.Conv2d(s[1], hidden_channels, kernel_size=1)
            for s in in_feats_shapes
        ])
        upsamplers = self._make_upsamplers(
            in_channels=hidden_channels,
            size=out_size,
            num_upsamples_per_layer=num_upsamples_per_layer,
            num_groups=num_groups_for_norm)
        out_conv = nn.Conv2d(hidden_channels // 2, out_channels, kernel_size=1)

        # yapf: disable
        layers = [
            in_convs,
            upsamplers,
            Sum(),
            out_conv
        ]
        # yapf: enable
        super().__init__(*layers)
Example #7
0
def make_fpn_efficientnet(name: str = 'efficientnet_b0',
                          fpn_type: str = 'fpn',
                          out_size: Tuple[int, int] = (224, 224),
                          fpn_channels: int = 256,
                          num_classes: int = 1000,
                          pretrained: Optional[str] = 'imagenet',
                          in_channels: str = 3) -> nn.Module:
    """Loads the PyTorch implementation of EfficientNet from
    https://github.com/lukemelas/EfficientNet-PyTorch using torch.hub.

    Args:
        name (str, optional): Name of the EfficientNet backbone. Only those
            available in the lukemelas/EfficientNet-PyTorch repos are
            supported. Defaults to 'efficientnet_b0'.
        fpn_type (str, optional): Type of FPN. 'fpn' | 'panoptic' | 'panet'.
            Defaults to 'fpn'.
        out_size (Tuple[int, int], optional): Size of segmentation output.
            Defaults to (224, 224).
        fpn_channels (int, optional): Number of hidden channels to use in the
            FPN. Defaults to 256.
        num_classes (int, optional): Number of classes for which to make
            predictions. Determines the channel width of the output.
            Defaults to 1000.
        pretrained (Optional[str], optional): One of
            None | 'imagenet' | 'advprop'. See lukemelas/EfficientNet-PyTorch
            for details. Defaults to True.
        in_channels (int, optional): Channel width of the input. If greater
            than 3, a parallel backbone is added to incorporate the new
            channels and the feature maps of the two backbones are added
            together to produce the final feature maps. Note that this is
            currently different from make_fpn_resnet. See
            lukemelas/EfficientNet-PyTorch for the in_channels < 3 case.
            Defaults to 3.

    Raises:
        NotImplementedError: On unknown fpn_style.

    Returns:
        nn.Module: the FPN model
    """
    effnet = _load_efficientnet(name=name,
                                num_classes=num_classes,
                                pretrained=pretrained)

    if in_channels > 3:
        new_channels = in_channels - 3
        new_effnet = _load_efficientnet(
            name=name,
            num_classes=num_classes,
            pretrained=pretrained,
            in_channels=new_channels,
        )
        backbone = nn.Sequential(
            SplitTensor((3, new_channels), dim=1),
            Parallel([
                EfficientNetFeatureMapsExtractor(effnet),
                EfficientNetFeatureMapsExtractor(new_effnet)
            ]), AddAcross())
    else:
        backbone = EfficientNetFeatureMapsExtractor(effnet)

    feat_shapes = _get_shapes(backbone, channels=in_channels, size=out_size)
    if fpn_type == 'fpn':
        fpn = nn.Sequential(
            FPN(feat_shapes,
                hidden_channels=fpn_channels,
                out_channels=num_classes), SelectOne(idx=0))
    elif fpn_type == 'panoptic':
        fpn = PanopticFPN(feat_shapes,
                          hidden_channels=fpn_channels,
                          out_channels=num_classes)
    elif fpn_type == 'panet+fpn':
        feat_shapes2 = [(n, fpn_channels, h, w)
                        for (n, c, h, w) in feat_shapes]
        fpn = nn.Sequential(
            PANetFPN(feat_shapes,
                     hidden_channels=fpn_channels,
                     out_channels=fpn_channels),
            FPN(feat_shapes2,
                hidden_channels=fpn_channels,
                out_channels=num_classes), SelectOne(idx=0))
    else:
        raise NotImplementedError()
    # yapf: disable
    model = nn.Sequential(
        backbone,
        fpn,
        Interpolate(size=out_size, mode='bilinear', align_corners=False))
    # yapf: enable
    return model