class_docstr: Processes the output of both `SparseArch` (sparse_features) and `DenseArch`
  (dense_features). Return Y*Z and the dense layer itself (all concatenated)
  where Y is the output of interaction branch 1 and Z is the output of interaction
  branch 2. Y and Z are of size Bx(F1xD) and Bx(DxF2) respectively for some F1 and F2.
  
  .. note::
  
      The dimensionality of the `dense_features` (D) is expected to match the
      dimensionality of the `sparse_features` so that the dot products between them
      can be computed.
      The output dimension of the 2 interaction branches should be a multiple
      of D.
  
  
  Args:
      num_sparse_features (int): F.
      interaction_branch1 (nn.Module): MLP module for the first branch of
          interaction layer
      interaction_branch2 (nn.Module): MLP module for the second branch of
          interaction layer
  
  Example::
  
      D = 3
      B = 10
      keys = ["f1", "f2"]
      F = len(keys)
      # Assume last layer of
      I1 = DenseArch(
          in_features= 3 * D + D,
          layer_sizes=[4*D, 4*D], # F1 = 4
          device=dense_device,
      )
      I2 = DenseArch(
          in_features= 3 * D + D,
          layer_sizes=[4*D, 4*D], # F2 = 4
          device=dense_device,
      )
      inter_arch = InteractionProjectionArch(
                      num_sparse_features=len(keys),
                      interaction_branch1 = I1,
                      interaction_branch2 = I2,
                  )
  
      dense_features = torch.rand((B, D))
      sparse_features = torch.rand((B, F, D))
  
      #  B X (D + F1 * F2)
      concat_dense = inter_arch(dense_features, sparse_features)
class_docstr_tok: ["Processes","the","output","of","both","`","SparseArch","`","(","sparse_features",")","and","`","DenseArch","`","(","dense_features",")",".","Return","Y","*","Z","and","the","dense","layer","itself","(","all","concatenated",")","where","Y","is","the","output","of","interaction","branch","1","and","Z","is","the","output","of","interaction","branch","2",".","Y","and","Z","are","of","size","Bx","(","F1xD",")","and","Bx","(","DxF2",")","respectively","for","some","F1","and","F2",".","..","note",":",":","The","dimensionality","of","the","`","dense_features","`","(","D",")","is","expected","to","match","the","dimensionality","of","the","`","sparse_features","`","so","that","the","dot","products","between","them","can","be","computed",".","The","output","dimension","of","the","2","interaction","branches","should","be","a","multiple","of","D.","Args",":","num_sparse_features","(","int",")",":","F.","interaction_branch1","(","nn.Module",")",":","MLP","module","for","the","first","branch","of","interaction","layer","interaction_branch2","(","nn.Module",")",":","MLP","module","for","the","second","branch","of","interaction","layer","Example",":",":","D","=","3","B","=","10","keys","=","[","``","f1","''",",","``","f2","''","]","F","=","len","(","keys",")","#","Assume","last","layer","of","I1","=","DenseArch","(","in_features=","3","*","D","+","D",",","layer_sizes=","[","4","*","D",",","4","*","D","]",",","#","F1","=","4","device=dense_device",",",")","I2","=","DenseArch","(","in_features=","3","*","D","+","D",",","layer_sizes=","[","4","*","D",",","4","*","D","]",",","#","F2","=","4","device=dense_device",",",")","inter_arch","=","InteractionProjectionArch","(","num_sparse_features=len","(","keys",")",",","interaction_branch1","=","I1",",","interaction_branch2","=","I2",",",")","dense_features","=","torch.rand","(","(","B",",","D",")",")","sparse_features","=","torch.rand","(","(","B",",","F",",","D",")",")","#","B","X","(","D","+","F1","*","F2",")","concat_dense","=","inter_arch","(","dense_features",",","sparse_features",")"]
code: def __init__(
      self,
      num_sparse_features: int,
      interaction_branch1: nn.Module,
      interaction_branch2: nn.Module,
  ) -> None:
      super().__init__()
      self.F: int = num_sparse_features
      self.interaction_branch1 = interaction_branch1
      self.interaction_branch2 = interaction_branch2
  
imports: from typing import Dict, List, Optional, Tuple
  import torch
  from torch import nn
  from torchrec.datasets.utils import Batch
  from torchrec.modules.crossnet import LowRankCrossNet
  from torchrec.modules.embedding_modules import EmbeddingBagCollection
  from torchrec.modules.mlp import MLP
  from torchrec.sparse.jagged_tensor import KeyedJaggedTensor, KeyedTensor
label_desc: Use image node_id 1 to create a new InteractionProjectionArch object from inherited base classes: nn with example: obj = InteractionProjectionArch(num_sparse_features, interaction_branch1, interaction_branch2)