class_docstr: Applies a GroupLinear transformation layer, as defined `here <https://arxiv.org/abs/1808.09029>`_,
  `here <https://arxiv.org/abs/1911.12385>`_ and `here <https://arxiv.org/abs/2008.00623>`_
  
  Args:
      in_features (int): number of features in the input tensor
      out_features (int): number of features in the output tensor
      n_groups (int): number of groups
      bias (Optional[bool]): use bias or not
      feature_shuffle (Optional[bool]): Shuffle features between groups
  
  Shape:
      - Input: :math:`(N, *, C_{in})`
      - Output: :math:`(N, *, C_{out})`
class_docstr_tok: ["Applies","a","GroupLinear","transformation","layer",",","as","defined","`","here","<","https",":","\/\/arxiv.org\/abs\/1808.09029",">","`","_",",","`","here","<","https",":","\/\/arxiv.org\/abs\/1911.12385",">","`","_","and","`","here","<","https",":","\/\/arxiv.org\/abs\/2008.00623",">","`","_","Args",":","in_features","(","int",")",":","number","of","features","in","the","input","tensor","out_features","(","int",")",":","number","of","features","in","the","output","tensor","n_groups","(","int",")",":","number","of","groups","bias","(","Optional","[","bool","]",")",":","use","bias","or","not","feature_shuffle","(","Optional","[","bool","]",")",":","Shuffle","features","between","groups","Shape",":","-","Input",":",":","math",":","`","(","N",",","*",",","C_","{","in","}",")","`","-","Output",":",":","math",":","`","(","N",",","*",",","C_","{","out","}",")","`"]
code: def __init__(
      self,
      in_features: int,
      out_features: int,
      n_groups: int,
      bias: Optional[bool] = True,
      feature_shuffle: Optional[bool] = False,
      *args,
      **kwargs,
  ) -> None:
      if in_features % n_groups != 0:
          logger.error(
              "Input dimensions ({}) must be divisible by n_groups ({})".format(
                  in_features, n_groups
              )
          )
      if out_features % n_groups != 0:
          logger.error(
              "Output dimensions ({}) must be divisible by n_groups ({})".format(
                  out_features, n_groups
              )
          )
  
      in_groups = in_features // n_groups
      out_groups = out_features // n_groups
  
      super().__init__()
  
      self.weight = nn.Parameter(
          torch.Tensor(n_groups, in_groups, out_groups)
      )
      if bias:
          self.bias = nn.Parameter(
              torch.Tensor(n_groups, 1, out_groups)
          )
      else:
          self.bias = None
  
      self.out_features = out_features
      self.in_features = in_features
      self.n_groups = n_groups
      self.feature_shuffle = feature_shuffle
  
      self.reset_params()
  
imports: import argparse
  from typing import Optional
  import torch
  from torch import Tensor, nn
  from torch.nn import functional
  from cvnets.layers.base_layer import BaseLayer
  from utils import logger
label_desc: Use image node_id 1 to create a new GroupLinear object from inherited base classes: BaseLayer with example: obj = GroupLinear(in_features, out_features, n_groups, bias, feature_shuffle)