class_docstr: This head is useful for dealing with Siamese models which have multiple towers.
  For an input of type (N * num_towers) x C, this head can convert the output
  to N x (num_towers * C).
  
  This head is used in case of PIRL https://arxiv.org/abs/1912.01991 and
  Jigsaw https://arxiv.org/abs/1603.09246 approaches.
docstr: Args:
      batch (torch.Tensor): 2D torch tensor `(N * num_towers) x C` or 4D tensor of
                            shape `(N * num_towers) x C x 1 x 1`
  Returns:
      out (torch.Tensor): 2D output torch tensor `N x (C * num_towers)`
docstr_tok: ["Args",":","batch","(","torch.Tensor",")",":","2D","torch","tensor","`","(","N","*","num_towers",")","x","C","`","or","4D","tensor","of","shape","`","(","N","*","num_towers",")","x","C","x","1","x","1","`","Returns",":","out","(","torch.Tensor",")",":","2D","output","torch","tensor","`","N","x","(","C","*","num_towers",")","`"]
code: def forward(self, batch: torch.Tensor):
      """
      Args:
          batch (torch.Tensor): 2D torch tensor `(N * num_towers) x C` or 4D tensor of
                                shape `(N * num_towers) x C x 1 x 1`
      Returns:
          out (torch.Tensor): 2D output torch tensor `N x (C * num_towers)`
      """
      # batch dimension = (N * num_towers) x C x H x W
      siamese_batch_size = batch.shape[0]
      assert (
          siamese_batch_size % self.num_towers == 0
      ), f"{siamese_batch_size} not divisible by num_towers {self.num_towers}"
      batch_size = siamese_batch_size // self.num_towers
      out = batch.view(batch_size, -1)
      return out
  
file_path: vissl/vissl/models/heads/siamese_concat_view.py
imports: import torch
  import torch.nn
  from vissl.config import AttrDict
  from vissl.models.heads import register_model_head
label_desc: Use image node_id 2 for calling the SiameseConcatView obj's underlying member method code with example usage: obj.forward(batch) and returns: out