class_docstr: GCAModule in MASTER.
  
  Args:
      in_channels (int): Channels of input tensor.
      ratio (float): Scale ratio of in_channels.
      n_head (int): Numbers of attention head.
      pooling_type (str): Spatial pooling type. Options are [``avg``,
          ``att``].
      scale_attn (bool): Whether to scale the attention map. Defaults to
          False.
      fusion_type (str): Fusion type of input and context. Options are
          [``channel_add``, ``channel_mul``, ``channel_concat``].
class_docstr_tok: ["GCAModule","in","MASTER",".","Args",":","in_channels","(","int",")",":","Channels","of","input","tensor",".","ratio","(","float",")",":","Scale","ratio","of","in_channels",".","n_head","(","int",")",":","Numbers","of","attention","head",".","pooling_type","(","str",")",":","Spatial","pooling","type",".","Options","are","[","``","avg","``",",","``","att","``","]",".","scale_attn","(","bool",")",":","Whether","to","scale","the","attention","map",".","Defaults","to","False",".","fusion_type","(","str",")",":","Fusion","type","of","input","and","context",".","Options","are","[","``","channel_add","``",",","``","channel_mul","``",",","``","channel_concat","``","]","."]
code: def __init__(
      self,
      in_channels: int,
      ratio: float,
      n_head: int,
      pooling_type: str = "att",
      scale_attn: bool = False,
      fusion_type: str = "channel_add",
      **kwargs,
  ) -> None:
      super().__init__()
  
      assert pooling_type in ["avg", "att"]
      assert fusion_type in [
          "channel_add",
          "channel_mul",
          "channel_concat",
      ]
  
      # in_channels must be divided by headers evenly
      assert in_channels % n_head == 0 and in_channels >= 8
  
      self.n_head = n_head
      self.in_channels = in_channels
      self.ratio = ratio
      self.planes = int(in_channels * ratio)
      self.pooling_type = pooling_type
      self.fusion_type = fusion_type
      self.scale_attn = scale_attn
      self.single_header_inplanes = int(in_channels / n_head)
  
      if pooling_type == "att":
          self.conv_mask = nn.Conv2d(
              self.single_header_inplanes, 1, kernel_size=1
          )
          self.softmax = nn.Softmax(dim=2)
      else:
          self.avg_pool = nn.AdaptiveAvgPool2d(1)
  
      if fusion_type == "channel_add":
          self.channel_add_conv = nn.Sequential(
              nn.Conv2d(self.in_channels, self.planes, kernel_size=1),
              nn.LayerNorm([self.planes, 1, 1]),
              nn.ReLU(inplace=True),
              nn.Conv2d(self.planes, self.in_channels, kernel_size=1),
          )
      elif fusion_type == "channel_concat":
          self.channel_concat_conv = nn.Sequential(
              nn.Conv2d(self.in_channels, self.planes, kernel_size=1),
              nn.LayerNorm([self.planes, 1, 1]),
              nn.ReLU(inplace=True),
              nn.Conv2d(self.planes, self.in_channels, kernel_size=1),
          )
          # for concat
          self.cat_conv = nn.Conv2d(
              2 * self.in_channels, self.in_channels, kernel_size=1
          )
      elif fusion_type == "channel_mul":
          self.channel_mul_conv = nn.Sequential(
              nn.Conv2d(self.in_channels, self.planes, kernel_size=1),
              nn.LayerNorm([self.planes, 1, 1]),
              nn.ReLU(inplace=True),
              nn.Conv2d(self.planes, self.in_channels, kernel_size=1),
          )
  
file_path: mmocr/mmocr/models/textrecog/plugins/common.py
imports: from typing import Tuple, Union
  import torch
  import torch.nn
  from mmocr.registry import MODELS
label_desc: Use image node_id 1 to create a new GCAModule object from inherited base classes: nn with example: obj = GCAModule(in_channels, ratio, n_head, pooling_type, scale_attn, fusion_type)