class_docstr: Common API for MME-based domain adaptation on video data: DAN, JAN
code: def compute_loss(self, batch, split_name="valid"):
      # _s refers to source, _tu refers to unlabeled target
      if self.image_modality == "joint" and len(batch) == 4:
          (
              (x_s_rgb, y_s),
              (x_s_flow, y_s_flow),
              (x_tu_rgb, y_tu),
              (x_tu_flow, y_tu_flow),
          ) = batch
          [phi_s_rgb, phi_s_flow], y_hat = self.forward(
              {"rgb": x_s_rgb, "flow": x_s_flow}
          )
          [phi_t_rgb, phi_t_flow], y_t_hat = self.forward(
              {"rgb": x_tu_rgb, "flow": x_tu_flow}
          )
          mmd_rgb = self._compute_mmd(
              phi_s_rgb, phi_t_rgb, y_hat, y_t_hat
          )
          mmd_flow = self._compute_mmd(
              phi_s_flow, phi_t_flow, y_hat, y_t_hat
          )
          mmd = mmd_rgb + mmd_flow
      elif self.image_modality in ["rgb", "flow"] and len(batch) == 2:
          (x_s, y_s), (x_tu, y_tu) = batch
          phi_s, y_hat = self.forward(x_s)
          phi_t, y_t_hat = self.forward(x_tu)
          mmd = self._compute_mmd(phi_s, phi_t, y_hat, y_t_hat)
      else:
          raise NotImplementedError(
              "Batch len is {}. Check the Dataloader.".format(
                  len(batch)
              )
          )
  
      # Uncomment when checking whether rgb & flow labels are equal.
      # print('rgb_s:{}, flow_s:{}, rgb_f:{}, flow_f:{}'.format(y_s, y_s_flow, y_tu, y_tu_flow))
      # print('equal: {}/{}'.format(torch.all(torch.eq(y_s, y_s_flow)), torch.all(torch.eq(y_tu, y_tu_flow))))
  
      # ok is abbreviation for (all) correct
      loss_cls, ok_src = losses.cross_entropy_logits(y_hat, y_s)
      _, ok_tgt = losses.cross_entropy_logits(y_t_hat, y_tu)
      ok_src = ok_src.double().mean()
      ok_tgt = ok_tgt.double().mean()
  
      mmd = mmd.double().mean()
      task_loss = loss_cls
  
      log_metrics = {
          f"{split_name}_source_acc": ok_src,
          f"{split_name}_target_acc": ok_tgt,
          f"{split_name}_domain_acc": mmd,
      }
      return task_loss, mmd, log_metrics
  
imports: import torch
  import kale.predict.losses
  from kale.loaddata.video_access import get_image_modality
  from kale.pipeline.domain_adapter import BaseMMDLike, CDANTrainer, DANNTrainer, GradReverse, Method, set_requires_grad, WDGRLTrainer
label_desc: Use image node_id 3 for calling the BaseMMDLikeVideo obj's underlying member method code with example usage: obj.compute_loss(batch, split_name) and returns: task_loss,  mmd,  log_metrics