class_docstr: ACAR head of ACAR-Net
  Args:
      width (`int`):
          Input dimension of linear layer.
      roi_spatial (`int`):
          Portion to filter in spatial dimension.
      num_classes (`int`):
          Number of classes.
     dropout (`float`):
          Dropout ratio.
      bias (`bool`):
          Flag to control if use bias.
      reduce_dim (`int`):
          Reduce dimension.
      hidden_dim (`int`):
          Hidden dimension.
      downsample (`str`):
          downsample layer.
      depth (`int`):
          depth.
      kernel_size (`int`):
          kernel size
      mlp_1x1 (`bool`):
          use mlp_1x1
class_docstr_tok: ["ACAR","head","of","ACAR-Net","Args",":","width","(","`","int","`",")",":","Input","dimension","of","linear","layer",".","roi_spatial","(","`","int","`",")",":","Portion","to","filter","in","spatial","dimension",".","num_classes","(","`","int","`",")",":","Number","of","classes",".","dropout","(","`","float","`",")",":","Dropout","ratio",".","bias","(","`","bool","`",")",":","Flag","to","control","if","use","bias",".","reduce_dim","(","`","int","`",")",":","Reduce","dimension",".","hidden_dim","(","`","int","`",")",":","Hidden","dimension",".","downsample","(","`","str","`",")",":","downsample","layer",".","depth","(","`","int","`",")",":","depth",".","kernel_size","(","`","int","`",")",":","kernel","size","mlp_1x1","(","`","bool","`",")",":","use","mlp_1x1"]
code: def forward(self, data):
      if not isinstance(data["features"], list):
          feats = [data["features"]]
      else:
          feats = data["features"]
  
      # temporal average pooling
      h, w = feats[0].shape[3:]
      # requires all features have the same spatial dimensions
      feats = [
          nn.AdaptiveAvgPool3d((1, h, w))(f).view(-1, f.shape[1], h, w)
          for f in feats
      ]
      feats = torch.cat(feats, dim=1)
  
      feats = self.conv_reduce(feats)
  
      rois = data["rois"]
      rois[:, 1] = rois[:, 1] * w
      rois[:, 2] = rois[:, 2] * h
      rois[:, 3] = rois[:, 3] * w
      rois[:, 4] = rois[:, 4] * h
      rois = rois.detach()
      roi_feats = torchvision.ops.roi_align(
          feats, rois, (self.roi_spatial, self.roi_spatial)
      )
      roi_feats = self.roi_maxpool(roi_feats).view(data["num_rois"], -1)
  
      roi_ids = data["roi_ids"]
      sizes_before_padding = data["sizes_before_padding"]
      high_order_feats = []
      for idx in range(feats.shape[0]):  # iterate over mini-batch
          n_rois = roi_ids[idx + 1] - roi_ids[idx]
          if n_rois == 0:
              continue
  
          eff_h, eff_w = math.ceil(
              h * sizes_before_padding[idx][1]
          ), math.ceil(w * sizes_before_padding[idx][0])
          bg_feats = feats[idx][:, :eff_h, :eff_w]
          bg_feats = bg_feats.unsqueeze(0).repeat((n_rois, 1, 1, 1))
          actor_feats = roi_feats[roi_ids[idx] : roi_ids[idx + 1]]
          tiled_actor_feats = (
              actor_feats.unsqueeze(2).unsqueeze(2).expand_as(bg_feats)
          )
          interact_feats = torch.cat(
              [bg_feats, tiled_actor_feats], dim=1
          )
  
          interact_feats = self.conv1(interact_feats)
          interact_feats = nn.functional.relu(interact_feats)
          interact_feats = self.conv2(interact_feats)
          interact_feats = nn.functional.relu(interact_feats)
  
          interact_feats = self.downsample(interact_feats)
  
          interact_feats = self.hr2o(interact_feats)
          interact_feats = self.gap(interact_feats)
          high_order_feats.append(interact_feats)
  
      high_order_feats = torch.cat(high_order_feats, dim=0).view(
          data["num_rois"], -1
      )
  
      outputs = self.fc1(roi_feats)
      outputs = nn.functional.relu(outputs)
      outputs = torch.cat([outputs, high_order_feats], dim=1)
  
      if self.dp is not None:
          outputs = self.dp(outputs)
      outputs = self.fc2(outputs)
  
      return outputs
  
file_path: towhee/towhee/models/acar_net/head.py
imports: import math
  import torch
  from torch import nn
  import torchvision
label_desc: Use image node_id 2 for calling the ACARHead obj's underlying member method code with example usage: obj.forward(data) and returns: outputs