class_docstr: RPA UL Agent.
  
  Performs unlikelihood such that tokens which lead to misclassification are
  penalized.
class_docstr_tok: ["RPA","UL","Agent",".","Performs","unlikelihood","such","that","tokens","which","lead","to","misclassification","are","penalized","."]
docstr: Perform several steps to include unlikelihood loss.
  
  1. Generate from model
  2. Compute a forward pass to score generations
  3. Determine which tokens to apply UL to
  4. Compute the UL loss
  5. Sum the losses, record metrics.
docstr_tok: ["Perform","several","steps","to","include","unlikelihood","loss",".","1",".","Generate","from","model","2",".","Compute","a","forward","pass","to","score","generations","3",".","Determine","which","tokens","to","apply","UL","to","4",".","Compute","the","UL","loss","5",".","Sum","the","losses",",","record","metrics","."]
code: def compute_loss(self, batch, return_output=False):
      """
      Perform several steps to include unlikelihood loss.
  
      1. Generate from model
      2. Compute a forward pass to score generations
      3. Determine which tokens to apply UL to
      4. Compute the UL loss
      5. Sum the losses, record metrics.
      """
      total_loss, model_output = super().compute_loss(
          batch, return_output=True
      )
  
      if (
          self.is_training
          and (torch.rand(1).item() >= self.opt["rpa_ul_ratio"])
      ) or (not self.is_training and self.opt["eval_skip_generation"]):
          if return_output:
              return total_loss, model_output
          else:
              return total_loss
  
      # Generate
      maxlen = self.label_truncate or 256
      with torch.no_grad():
          beam_pred_scores, _ = self._generate(
              batch, self.beam_size, maxlen
          )
  
      # forward pass to create graph for beam search case
      generations = [g[1:] for (g, _, _) in beam_pred_scores]
      pred_toks = torch.nn.utils.rnn.pad_sequence(
          generations, batch_first=True
      )
      model_output = self.model(*self._model_input(batch), ys=pred_toks)
      logits, *_ = model_output
  
      # construct mask marking incorrectly classified characters
      label_mask = torch.zeros_like(pred_toks).type_as(logits)
      (
          label_mask,
          wrong_class_cnt,
          wrong_class_all_cnt,
          right_class_cnt,
      ) = self.compute_ul_label_mask(label_mask, generations, batch)
      # Compute unlikelihood loss
      ul_loss = self.compute_ul_loss(pred_toks, label_mask, logits)  # type: ignore
      if label_mask.sum() > 0:
          total_loss += div(ul_loss.sum(), label_mask.sum())
      else:
          total_loss += ul_loss.sum()
  
      # record metrics
      self.record_local_metric(
          "ul_loss",
          AverageMetric.many(
              ul_loss.sum(dim=-1), label_mask.sum(dim=-1)
          ),
      )
      self.record_local_metric(
          "wrong_class", AverageMetric.many(wrong_class_cnt)
      )
      self.record_local_metric(
          "wrong_class_all", AverageMetric.many(wrong_class_all_cnt)
      )
      self.record_local_metric(
          "right_class", AverageMetric.many(right_class_cnt)
      )
  
      if return_output:
          return total_loss, model_output
      return total_loss
  
imports: from typing import Optional, List, Tuple
  from parlai.core.params import ParlaiParser
  from parlai.core.opt import Opt
  from parlai.core.torch_agent import Batch
  import torch
  import torch.nn
  import torch.nn.functional
  from parlai.agents.transformer.transformer import TransformerGeneratorAgent
  from parlai.core.torch_agent import Output
  from parlai.core.metrics import AverageMetric
  from projects.light_whoami.agents.rpa_rerank import RPAReranker
  from projects.msc.agents.long_tga import TransformerVariantAgent
label_desc: Use image node_id 4 for calling the RpaUlAgent obj's underlying member method code with example usage: obj.compute_loss(batch, return_output) and returns: total_loss, total_loss,  model_output, total_loss,  model_output, total_loss