class_docstr: Bidirection version GCN layer from paper `GCN <https://arxiv.org/abs/1609.02907>`__.
  
  .. math::
      h_{i, \vdash}^{(l+1)} = \sigma(b^{(l)}_{\vdash} + \sum_{j\in\mathcal{N}_{\vdash}(i)}
      \frac{1}{c_{ij}}h_{j}^{(l)}W^{(l)}_{\vdash})
  
      h_{i, \dashv}^{(l+1)} = \sigma(b^{(l)}_{\dashv} + \sum_{j\in\mathcal{N}_{\dashv}(i)}
      \frac{1}{c_{ij}}h_{j}^{(l)}W^{(l)}_{\dashv})
  
      r_{i}^{l} &= \sigma (W_{f}[h_{i, \vdash}^{l};h_{i, \dashv}^{l};
              h_{i, \vdash}^{l}*h_{i, \dashv}^{l};
              h_{i, \vdash}^{l}-h_{i, \dashv}^{l}])
  
  Parameters
  ----------
  input_size : int
      Input feature size; i.e, the number of dimensions of :math:`h_j^{(l)}`.
  output_size : int
      Output feature size; i.e., the number of dimensions of :math:`h_i^{(l+1)}`.
  gcn_norm : str, optional
      How to apply the normalizer. If is `'right'`, divide the aggregated messages
      by each node's in-degrees, which is equivalent to averaging the received messages.
      If is `'none'`, no normalization is applied. Default is `'both'`,
      where the :math:`c_{ij}` in the paper is applied.
  weight : bool, optional
      If True, apply a linear layer. Otherwise, aggregating the messages
      without a weight matrix.
  bias : bool, optional
      If True, adds a learnable bias to the output. Default: ``True``.
  activation : callable activation function/layer or None, optional
      If not None, applies an activation function to the updated node features.
      Default: ``None``.
  allow_zero_in_degree : bool, optional
      If there are 0-in-degree nodes in the graph, output for those nodes will be invalid
      since no message will be passed to those nodes. This is harmful for some applications
      causing silent performance regression. This module will raise a DGLError if it detects
      0-in-degree nodes in input graph. By setting ``True``, it will suppress the check
      and let the users handle it by themselves. Default: ``False``.
class_docstr_tok: ["Bidirection","version","GCN","layer","from","paper","`","GCN","<","https",":","\/\/arxiv.org\/abs\/1609.02907",">","`","__",".","..","math",":",":","h_","{","i",",","\\vdash","}","^","{","(","l+1",")","}","=","\\sigma","(","b^","{","(","l",")","}","_","{","\\vdash","}","+","\\sum_","{","j\\in\\mathcal","{","N","}","_","{","\\vdash","}","(","i",")","}","\\frac","{","1","}","{","c_","{","ij","}","}","h_","{","j","}","^","{","(","l",")","}","W^","{","(","l",")","}","_","{","\\vdash","}",")","h_","{","i",",","\\dashv","}","^","{","(","l+1",")","}","=","\\sigma","(","b^","{","(","l",")","}","_","{","\\dashv","}","+","\\sum_","{","j\\in\\mathcal","{","N","}","_","{","\\dashv","}","(","i",")","}","\\frac","{","1","}","{","c_","{","ij","}","}","h_","{","j","}","^","{","(","l",")","}","W^","{","(","l",")","}","_","{","\\dashv","}",")","r_","{","i","}","^","{","l","}","&","=","\\sigma","(","W_","{","f","}","[","h_","{","i",",","\\vdash","}","^","{","l","}",";","h_","{","i",",","\\dashv","}","^","{","l","}",";","h_","{","i",",","\\vdash","}","^","{","l","}","*","h_","{","i",",","\\dashv","}","^","{","l","}",";","h_","{","i",",","\\vdash","}","^","{","l","}","-h_","{","i",",","\\dashv","}","^","{","l","}","]",")","Parameters","--","--","--","--","--","input_size",":","int","Input","feature","size",";","i.e",",","the","number","of","dimensions","of",":","math",":","`","h_j^","{","(","l",")","}","`",".","output_size",":","int","Output","feature","size",";","i.e.",",","the","number","of","dimensions","of",":","math",":","`","h_i^","{","(","l+1",")","}","`",".","gcn_norm",":","str",",","optional","How","to","apply","the","normalizer",".","If","is","`","'right","'","`",",","divide","the","aggregated","messages","by","each","node","'s","in-degrees",",","which","is","equivalent","to","averaging","the","received","messages",".","If","is","`","'none","'","`",",","no","normalization","is","applied",".","Default","is","`","'both","'","`",",","where","the",":","math",":","`","c_","{","ij","}","`","in","the","paper","is","applied",".","weight",":","bool",",","optional","If","True",",","apply","a","linear","layer",".","Otherwise",",","aggregating","the","messages","without","a","weight","matrix",".","bias",":","bool",",","optional","If","True",",","adds","a","learnable","bias","to","the","output",".","Default",":","``","True","``",".","activation",":","callable","activation","function\/layer","or","None",",","optional","If","not","None",",","applies","an","activation","function","to","the","updated","node","features",".","Default",":","``","None","``",".","allow_zero_in_degree",":","bool",",","optional","If","there","are","0-in-degree","nodes","in","the","graph",",","output","for","those","nodes","will","be","invalid","since","no","message","will","be","passed","to","those","nodes",".","This","is","harmful","for","some","applications","causing","silent","performance","regression",".","This","module","will","raise","a","DGLError","if","it","detects","0-in-degree","nodes","in","input","graph",".","By","setting","``","True","``",",","it","will","suppress","the","check","and","let","the","users","handle","it","by","themselves",".","Default",":","``","False","``","."]
code: def __init__(
      self,
      input_size,
      output_size,
      feat_drop=0.0,
      gcn_norm="both",
      weight=True,
      bias=True,
      activation=None,
      allow_zero_in_degree=False,
      residual=True,
  ):
      super(BiFuseGCNLayerConv, self).__init__()
      if gcn_norm not in ("none", "both", "right"):
          raise RuntimeError(
              'Invalid gcn_norm value. Must be either "none", "both" or "right".'
              ' But got "{}".'.format(gcn_norm)
          )
      self._input_size = input_size
      self._output_size = output_size
      self._gcn_norm = gcn_norm
      self._allow_zero_in_degree = allow_zero_in_degree
      self._feat_drop = nn.Dropout(feat_drop)
  
      if weight:
          self.weight_fw = nn.Parameter(
              torch.Tensor(input_size, output_size)
          )
          self.weight_bw = nn.Parameter(
              torch.Tensor(input_size, output_size)
          )
      else:
          self.register_parameter("weight_fw", None)
          self.register_parameter("weight_bw", None)
  
      if bias:
          self.bias_fw = nn.Parameter(torch.Tensor(output_size))
          self.bias_bw = nn.Parameter(torch.Tensor(output_size))
      else:
          self.register_parameter("bias_fw", None)
          self.register_parameter("bias_bw", None)
  
      self.reset_parameters()
  
      self._activation = activation
  
      self.fuse_linear = nn.Linear(
          4 * output_size, output_size, bias=True
      )
  
      if residual:
          if self._input_size != output_size:
              self.res_fc = nn.Linear(
                  self._input_size, output_size, bias=True
              )
          else:
              self.res_fc = nn.Identity()
      else:
          self.register_buffer("res_fc", None)
  
imports: import dgl.function
  import torch
  import torch.nn
  from torch.nn import init
  from .base import GNNBase, GNNLayerBase
label_desc: Use image node_id 1 to create a new BiFuseGCNLayerConv object from inherited base classes: GNNLayerBase with example: obj = BiFuseGCNLayerConv(input_size, output_size, feat_drop, gcn_norm, weight, bias, activation, allow_zero_in_degree, residual)