class_docstr: Relational graph convolution layer from `Modeling Relational Data with Graph
  Convolutional Networks <https://arxiv.org/abs/1703.06103>`__
  
  It can be described as below:
  
  .. math::
  
     h_i^{(l+1)} = \sigma(\sum_{r\in\mathcal{R}}
     \sum_{j\in\mathcal{N}^r(i)}\frac{1}{c_{i,r}}W_r^{(l)}h_j^{(l)}+W_0^{(l)}h_i^{(l)})
  
  where :math:`\mathcal{N}^r(i)` is the neighbor set of node :math:`i` w.r.t. relation
  :math:`r`. :math:`c_{i,r}` is the normalizer equal
  to :math:`|\mathcal{N}^r(i)|`. :math:`\sigma` is an activation function. :math:`W_0`
  is the self-loop weight.
  
  The basis regularization decomposes :math:`W_r` by:
  
  .. math::
  
     W_r^{(l)} = \sum_{b=1}^B a_{rb}^{(l)}V_b^{(l)}
  
  where :math:`B` is the number of bases, :math:`V_b^{(l)}` are linearly combined
  with coefficients :math:`a_{rb}^{(l)}`.
  
  The block-diagonal-decomposition regularization decomposes :math:`W_r` into :math:`B`
  number of block diagonal matrices. We refer :math:`B` as the number of bases.
  
  The block regularization decomposes :math:`W_r` by:
  
  .. math::
  
     W_r^{(l)} = \oplus_{b=1}^B Q_{rb}^{(l)}
  
  where :math:`B` is the number of bases, :math:`Q_{rb}^{(l)}` are block
  bases with shape :math:`R^{(d^{(l+1)}/B)*(d^{l}/B)}`.
  
  Parameters
  ----------
  in_feat : int
      Input feature size; i.e, the number of dimensions of :math:`h_j^{(l)}`.
  out_feat : int
      Output feature size; i.e., the number of dimensions of :math:`h_i^{(l+1)}`.
  num_rels : int
      Number of relations. .
  regularizer : str
      Which weight regularizer to use "basis" or "bdd".
      "basis" is short for basis-diagonal-decomposition.
      "bdd" is short for block-diagonal-decomposition.
  num_bases : int, optional
      Number of bases. If is none, use number of relations. Default: ``None``.
  bias : bool, optional
      True if bias is added. Default: ``True``.
  activation : callable, optional
      Activation function. Default: ``None``.
  self_loop : bool, optional
      True to include self loop message. Default: ``True``.
  low_mem : bool, optional
      True to use low memory implementation of relation message passing function. Default: False.
      This option trades speed with memory consumption, and will slowdown the forward/backward.
      Turn it on when you encounter OOM problem during training or evaluation. Default: ``False``.
  dropout : float, optional
      Dropout rate. Default: ``0.0``
  layer_norm: float, optional
      Add layer norm. Default: ``False``
  
  Examples
  --------
  >>> import dgl
  >>> import numpy as np
  >>> import tensorflow as tf
  >>> from dgl.nn import RelGraphConv
  >>>
  >>> with tf.device("CPU:0"):
  >>>     g = dgl.graph(([0,1,2,3,2,5], [1,2,3,4,0,3]))
  >>>     feat = tf.ones((6, 10))
  >>>     conv = RelGraphConv(10, 2, 3, regularizer='basis', num_bases=2)
  >>>     etype = tf.convert_to_tensor(np.array([0,1,2,0,1,2]).astype(np.int64))
  >>>     res = conv(g, feat, etype)
  >>>     res
  <tf.Tensor: shape=(6, 2), dtype=float32, numpy=
  array([[-0.02938664,  1.7932655 ],
      [ 0.1146394 ,  0.48319   ],
      [-0.02938664,  1.7932655 ],
      [ 1.2054908 , -0.26098895],
      [ 0.1146394 ,  0.48319   ],
      [ 0.75915515,  1.1454091 ]], dtype=float32)>
  
  >>> # One-hot input
  >>> with tf.device("CPU:0"):
  >>>     one_hot_feat = tf.convert_to_tensor(np.array([0,1,2,3,4,5]).astype(np.int64))
  >>>     res = conv(g, one_hot_feat, etype)
  >>>     res
  <tf.Tensor: shape=(6, 2), dtype=float32, numpy=
  array([[-0.24205256, -0.7922753 ],
      [ 0.62085056,  0.4893622 ],
      [-0.9484881 , -0.26546806],
      [-0.2163915 , -0.12585883],
      [-0.14293689,  0.77483284],
      [ 0.091169  , -0.06761569]], dtype=float32)>
code: def __init__(
      self,
      in_feat,
      out_feat,
      num_rels,
      regularizer="basis",
      num_bases=None,
      bias=True,
      activation=None,
      self_loop=True,
      low_mem=False,
      dropout=0.0,
      layer_norm=False,
  ):
      super(RelGraphConv, self).__init__()
      self.in_feat = in_feat
      self.out_feat = out_feat
      self.num_rels = num_rels
      self.regularizer = regularizer
      self.num_bases = num_bases
      if (
          self.num_bases is None
          or self.num_bases > self.num_rels
          or self.num_bases < 0
      ):
          self.num_bases = self.num_rels
      self.bias = bias
      self.activation = activation
      self.self_loop = self_loop
      self.low_mem = low_mem
  
      assert (
          layer_norm is False
      ), "TensorFlow currently does not support layer norm."
  
      xinit = tf.keras.initializers.glorot_uniform()
      zeroinit = tf.keras.initializers.zeros()
  
      if regularizer == "basis":
          # add basis weights
          self.weight = tf.Variable(
              initial_value=xinit(
                  shape=(self.num_bases, self.in_feat, self.out_feat),
                  dtype="float32",
              ),
              trainable=True,
          )
          if self.num_bases < self.num_rels:
              # linear combination coefficients
              self.w_comp = tf.Variable(
                  initial_value=xinit(
                      shape=(self.num_rels, self.num_bases),
                      dtype="float32",
                  ),
                  trainable=True,
              )
          # message func
          self.message_func = self.basis_message_func
      elif regularizer == "bdd":
          if in_feat % num_bases != 0 or out_feat % num_bases != 0:
              raise ValueError(
                  "Feature size must be a multiplier of num_bases."
              )
          # add block diagonal weights
          self.submat_in = in_feat // self.num_bases
          self.submat_out = out_feat // self.num_bases
  
          # assuming in_feat and out_feat are both divisible by num_bases
          self.weight = tf.Variable(
              initial_value=xinit(
                  shape=(
                      self.num_rels,
                      self.num_bases * self.submat_in * self.submat_out,
                  ),
                  dtype="float32",
              ),
              trainable=True,
          )
          # message func
          self.message_func = self.bdd_message_func
      else:
          raise ValueError(
              "Regularizer must be either 'basis' or 'bdd'"
          )
  
      # bias
      if self.bias:
          self.h_bias = tf.Variable(
              initial_value=zeroinit(shape=(out_feat), dtype="float32"),
              trainable=True,
          )
  
      # weight for self loop
      if self.self_loop:
          self.loop_weight = tf.Variable(
              initial_value=xinit(
                  shape=(in_feat, out_feat), dtype="float32"
              ),
              trainable=True,
          )
  
      self.dropout = layers.Dropout(rate=dropout)
  
file_path: dgl/python/dgl/nn/tensorflow/conv/relgraphconv.py
imports: import tensorflow
  from tensorflow.keras import layers
  from ....None import function
  from ..None import utils
label_desc: Use image node_id 1 to create a new RelGraphConv object from inherited base classes: layers with example: obj = RelGraphConv(in_feat, out_feat, num_rels, regularizer, num_bases, bias, activation, _loop, low_mem, dropout, layer_norm)