class_docstr: The graph transformer layer from the `"Masked Label Prediction:
  Unified Message Passing Model for Semi-Supervised Classification"
  <https://arxiv.org/abs/2009.03509>`_ paper.
  
  Parameters
  ----------
  in_node_feats : int or pair of ints
      Input feature size. A pair denotes feature sizes of source and
      destination nodes.
  out_node_feats : int
      Output feature size.
  num_heads : int
      Number of multi-head-attentions.
  concat : bool, optional
      If False, the multi-head attentions are averaged instead of concatenated.
      Default: ``True``.
  beta : bool, optional
      If True, use a gated residual connection. Default: ``True``.
  edge_feats: int, optional
      Edge feature size. Default: ``None``.
  bias: bool, optional
      If True, learns a bias term. Default: ``True``.
  root_weight: bool, optional
      If False, will skip to learn a root weight matrix. Default: ``True``.
code: def __init__(
      self,
      in_node_feats: Union[int, Tuple[int, int]],
      out_node_feats: int,
      num_heads: int,
      concat: bool = True,
      beta: bool = False,
      edge_feats: Optional[int] = None,
      bias: bool = True,
      root_weight: bool = True,
  ):
      super().__init__()
  
      self.in_node_feats = in_node_feats
      self.out_node_feats = out_node_feats
      self.num_heads = num_heads
      self.concat = concat
      self.beta = beta
      self.edge_feats = edge_feats
      self.bias = bias
      self.root_weight = root_weight
  
      if isinstance(in_node_feats, int):
          in_node_feats = (in_node_feats, in_node_feats)
  
      self.lin_key = nn.Linear(
          in_node_feats[0], num_heads * out_node_feats
      )
      self.lin_query = nn.Linear(
          in_node_feats[1], num_heads * out_node_feats
      )
      self.lin_value = nn.Linear(
          in_node_feats[0], num_heads * out_node_feats
      )
  
      if edge_feats is not None:
          self.lin_edge = nn.Linear(
              edge_feats, num_heads * out_node_feats, bias=False
          )
      else:
          self.lin_edge = self.register_parameter("lin_edge", None)
  
      if concat:
          self.lin_skip = nn.Linear(
              in_node_feats[1], num_heads * out_node_feats, bias=bias
          )
          if self.beta:
              self.lin_beta = nn.Linear(
                  3 * num_heads * out_node_feats, 1, bias=bias
              )
          else:
              self.lin_beta = self.register_parameter("lin_beta", None)
      else:
          self.lin_skip = nn.Linear(
              in_node_feats[1], out_node_feats, bias=bias
          )
          if self.beta:
              self.lin_beta = nn.Linear(
                  3 * out_node_feats, 1, bias=False
              )
          else:
              self.lin_beta = self.register_parameter("lin_beta", None)
  
      self.reset_parameters()
  
imports: from typing import Optional, Tuple, Union
  from cugraph_dgl.nn.conv.base import BaseConv, SparseGraph
  from cugraph.utilities.utils import import_optional
label_desc: Use image node_id 1 to create a new TransformerConv object from inherited base classes: BaseConv with example: obj = TransformerConv(in_node_feats, out_node_feats, num_heads, concat, beta, edge_feats, bias, root_weight)