class_docstr: Decoupled SOLO mask head used in `SOLO: Segmenting Objects by Locations.
  
  <https://arxiv.org/abs/1912.04488>`_
  
  Args:
      init_cfg (dict or list[dict], optional): Initialization config dict.
docstr: Forward features from the upstream network.
  
  Args:
      x (tuple[Tensor]): Features from the upstream network, each is
          a 4D-tensor.
  
  Returns:
      tuple: A tuple of classification scores and mask prediction.
  
          - mlvl_mask_preds_x (list[Tensor]): Multi-level mask prediction
            from x branch. Each element in the list has shape
            (batch_size, num_grids ,h ,w).
          - mlvl_mask_preds_y (list[Tensor]): Multi-level mask prediction
            from y branch. Each element in the list has shape
            (batch_size, num_grids ,h ,w).
          - mlvl_cls_preds (list[Tensor]): Multi-level scores.
            Each element in the list has shape
            (batch_size, num_classes, num_grids ,num_grids).
code: def forward(self, x: Tuple[Tensor]) -> Tuple:
      """Forward features from the upstream network.
  
      Args:
          x (tuple[Tensor]): Features from the upstream network, each is
              a 4D-tensor.
  
      Returns:
          tuple: A tuple of classification scores and mask prediction.
  
              - mlvl_mask_preds_x (list[Tensor]): Multi-level mask prediction
                from x branch. Each element in the list has shape
                (batch_size, num_grids ,h ,w).
              - mlvl_mask_preds_y (list[Tensor]): Multi-level mask prediction
                from y branch. Each element in the list has shape
                (batch_size, num_grids ,h ,w).
              - mlvl_cls_preds (list[Tensor]): Multi-level scores.
                Each element in the list has shape
                (batch_size, num_classes, num_grids ,num_grids).
      """
      assert len(x) == self.num_levels
      feats = self.resize_feats(x)
      mask_preds_x = []
      mask_preds_y = []
      cls_preds = []
      for i in range(self.num_levels):
          x = feats[i]
          mask_feat = x
          cls_feat = x
          # generate and concat the coordinate
          coord_feat = generate_coordinate(
              mask_feat.size(), mask_feat.device
          )
          mask_feat_x = torch.cat(
              [mask_feat, coord_feat[:, 0:1, ...]], 1
          )
          mask_feat_y = torch.cat(
              [mask_feat, coord_feat[:, 1:2, ...]], 1
          )
  
          for mask_layer_x, mask_layer_y in zip(
              self.mask_convs_x, self.mask_convs_y
          ):
              mask_feat_x = mask_layer_x(mask_feat_x)
              mask_feat_y = mask_layer_y(mask_feat_y)
  
          mask_feat_x = F.interpolate(
              mask_feat_x, scale_factor=2, mode="bilinear"
          )
          mask_feat_y = F.interpolate(
              mask_feat_y, scale_factor=2, mode="bilinear"
          )
  
          mask_pred_x = self.conv_mask_list_x[i](mask_feat_x)
          mask_pred_y = self.conv_mask_list_y[i](mask_feat_y)
  
          # cls branch
          for j, cls_layer in enumerate(self.cls_convs):
              if j == self.cls_down_index:
                  num_grid = self.num_grids[i]
                  cls_feat = F.interpolate(
                      cls_feat, size=num_grid, mode="bilinear"
                  )
              cls_feat = cls_layer(cls_feat)
  
          cls_pred = self.conv_cls(cls_feat)
  
          if not self.training:
              feat_wh = feats[0].size()[-2:]
              upsampled_size = (feat_wh[0] * 2, feat_wh[1] * 2)
              mask_pred_x = F.interpolate(
                  mask_pred_x.sigmoid(),
                  size=upsampled_size,
                  mode="bilinear",
              )
              mask_pred_y = F.interpolate(
                  mask_pred_y.sigmoid(),
                  size=upsampled_size,
                  mode="bilinear",
              )
              cls_pred = cls_pred.sigmoid()
              # get local maximum
              local_max = F.max_pool2d(cls_pred, 2, stride=1, padding=1)
              keep_mask = local_max[:, :, :-1, :-1] == cls_pred
              cls_pred = cls_pred * keep_mask
  
          mask_preds_x.append(mask_pred_x)
          mask_preds_y.append(mask_pred_y)
          cls_preds.append(cls_pred)
      return mask_preds_x, mask_preds_y, cls_preds
  
imports: from typing import List, Optional, Tuple
  import mmcv
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.cnn import ConvModule
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.models.utils.misc import floordiv
  from mmdet.registry import MODELS
  from mmdet.utils import ConfigType, InstanceList, MultiConfig, OptConfigType
  from ..layers import mask_matrix_nms
  from ..utils import center_of_mass, generate_coordinate, multi_apply
  from .base_mask_head import BaseMaskHead
label_desc: Use image node_id 3 for calling the DecoupledSOLOHead obj's underlying member method code with example usage: obj.forward(x) and returns: mask_preds_x,  mask_preds_y,  cls_preds