class_docstr: The class for implementing DRRG and TextSnake U-Net-like FPN.
  
  DRRG: `Deep Relational Reasoning Graph Network for Arbitrary Shape
  Text Detection <https://arxiv.org/abs/2003.07493>`_.
  
  TextSnake: `A Flexible Representation for Detecting Text of Arbitrary
  Shapes <https://arxiv.org/abs/1807.01544>`_.
  
  Args:
      in_channels (list[int]): Number of input channels at each scale. The
          length of the list should be 4.
      out_channels (int): The number of output channels.
      init_cfg (dict or list[dict], optional): Initialization configs.
docstr: Args:
      x (list[Tensor] | tuple[Tensor]): A list of four tensors of shape
          :math:`(N, C_i, H_i, W_i)`, representing C2, C3, C4, C5
          features respectively. :math:`C_i` should matches the number in
          ``in_channels``.
  
  Returns:
      Tensor: Shape :math:`(N, C, H, W)` where :math:`H=4H_0` and
      :math:`W=4W_0`.
docstr_tok: ["Args",":","x","(","list","[","Tensor","]","|","tuple","[","Tensor","]",")",":","A","list","of","four","tensors","of","shape",":","math",":","`","(","N",",","C_i",",","H_i",",","W_i",")","`",",","representing","C2",",","C3",",","C4",",","C5","features","respectively",".",":","math",":","`","C_i","`","should","matches","the","number","in","``","in_channels","``",".","Returns",":","Tensor",":","Shape",":","math",":","`","(","N",",","C",",","H",",","W",")","`","where",":","math",":","`","H=4H_0","`","and",":","math",":","`","W=4W_0","`","."]
code: def forward(
      self, x: List[Union[torch.Tensor, Tuple[torch.Tensor]]]
  ) -> torch.Tensor:
      """
      Args:
          x (list[Tensor] | tuple[Tensor]): A list of four tensors of shape
              :math:`(N, C_i, H_i, W_i)`, representing C2, C3, C4, C5
              features respectively. :math:`C_i` should matches the number in
              ``in_channels``.
  
      Returns:
          Tensor: Shape :math:`(N, C, H, W)` where :math:`H=4H_0` and
          :math:`W=4W_0`.
      """
      c2, c3, c4, c5 = x
  
      x = F.relu(self.up4(c5))
  
      c4 = F.interpolate(
          c4, size=x.shape[2:], mode="bilinear", align_corners=True
      )
      x = torch.cat([x, c4], dim=1)
      x = F.relu(self.up_block3(x))
  
      c3 = F.interpolate(
          c3, size=x.shape[2:], mode="bilinear", align_corners=True
      )
      x = torch.cat([x, c3], dim=1)
      x = F.relu(self.up_block2(x))
  
      c2 = F.interpolate(
          c2, size=x.shape[2:], mode="bilinear", align_corners=True
      )
      x = torch.cat([x, c2], dim=1)
      x = F.relu(self.up_block1(x))
  
      x = self.up_block0(x)
      # the output should be of the same height and width as backbone input
      return x
  
file_path: mmocr/mmocr/models/textdet/necks/fpn_unet.py
imports: from typing import Dict, List, Optional, Tuple, Union
  import torch
  import torch.nn.functional
  from mmengine.model import BaseModule
  from torch import nn
  from mmocr.registry import MODELS
label_desc: Use image node_id 2 for calling the FPN_UNet obj's underlying member method code with example usage: obj.forward(x) and returns: x