class_docstr: LowRankTensorFusion is a PyTorch module that performs multimodal fusion using a low-rank tensor-based approach.
     The 'input_dims' argument specifies the input dimensions of each modality. The 'output_dim' argument defines the
     output dimension after the fusion. The 'rank' argument is a hyperparameter specifying the rank for the low-rank
     tensor decomposition.
     This fusion method performs fusion by assuming a low-rank structure for the interaction tensor, effectively
     compressing the interaction space. It leverages a set of low-rank factors, one for each modality, that are
     learned during training.
     These factors are initialized with xavier normal distribution and are applied to their corresponding modalities
     during the forward pass. A tensor product is computed across all modalities and their respective factors,
     resulting in a fused tensor.
     Next, a weighted summation of this fused tensor is computed using fusion weights, followed by the addition of a
     fusion bias. Both fusion weights and bias are learnable parameters initialized with xavier normal distribution
     and zero respectively.
     The final output is reshaped to the specified 'output_dim' and returned. If 'flatten' is set to True, each
     modality is first flattened before concatenation with a ones tensor and the subsequent multiplication with its
     factor.
     This approach provides an efficient and compact representation for capturing interactions among multiple
     modalities, making it suitable for tasks involving high-dimensional multimodal data.
  Args:
      input_dims (int): A list or tuple of integers indicating input dimensions of the modalities.
      output_dim (int): output dimension after the fusion.
      rank (int): A hyperparameter specifying the rank for the low-rank tensor decomposition.
      flatten (bool): Boolean to dictate if output should be flattened or not. Default: True
  
  Note:
      Adapted from https://github.com/Justin1904/Low-rank-Multimodal-Fusion.
code: def forward(self, modalities):
      batch_size = modalities[0].shape[0]
      fused_tensor = 1
      for modality, factor in zip(modalities, self.factors):
          ones = Variable(
              torch.ones(batch_size, 1).type(modality.dtype),
              requires_grad=False,
          ).to(
              torch.device(
                  "cuda:0" if torch.cuda.is_available() else "cpu"
              )
          )
          modality = modality.to(
              torch.device(
                  "cuda:0" if torch.cuda.is_available() else "cpu"
              )
          )
  
          factor = factor.to(
              torch.device(
                  "cuda:0" if torch.cuda.is_available() else "cpu"
              )
          )
  
          if self.flatten:
              modality_withones = torch.cat(
                  (ones, torch.flatten(modality, start_dim=1)), dim=1
              )
          else:
              modality_withones = torch.cat((ones, modality), dim=1)
          modality_factor = torch.matmul(modality_withones, factor)
          fused_tensor = fused_tensor * modality_factor
  
      output = (
          torch.matmul(
              self.fusion_weights, fused_tensor.permute(1, 0, 2)
          ).squeeze()
          + self.fusion_bias
      )
      output = output.view(-1, self.output_dim)
      return output
  
file_path: pykale/kale/embed/feature_fusion.py
imports: import torch
  from torch import nn
  from torch.autograd import Variable
label_desc: Use image node_id 2 for calling the LowRankTensorFusion obj's underlying member method code with example usage: obj.forward(modalities) and returns: output