class_docstr: Hierarchical Attention Network (RNN baseline model)
docstr: Compute on step/epoch metrics
code: def log_metrics(
      self,
      predictions,
      targets,
      loss,
      stage,
      on_step: bool = True,
      on_epoch: bool = True,
  ):
      """Compute on step/epoch metrics"""
      assert stage in ["train", "val", "test"]
      if self.hparams.encoder_type == "neural":
          scores = F.softmax(predictions, dim=1)
      else:
          predictions = torch.sigmoid(predictions)
          scores = torch.zeros(
              (predictions.size(0), 2),
              dtype=predictions.dtype,
              device=predictions.device,
          )
          scores[:, 0] += torch.ones(
              predictions.size(0),
              dtype=predictions.dtype,
              device=predictions.device,
          )
          scores[:, 0] -= predictions.squeeze()
          scores[:, 1] += predictions.squeeze()
  
      if stage == "train":
          self.log(
              "train/loss", loss, on_step=on_step, on_epoch=on_epoch
          )
          if self.hparams.loss_type in [
              "robust",
              "asymmetric",
              "asymmetric_dynamic",
          ]:
              self.log(
                  "train/pos_samples",
                  torch.sum(targets[:, 1]) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
              self.log(
                  "train/pos_predictions",
                  sum(scores[:, 0] < 0.5) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
          else:
              self.log(
                  "train/pos_samples",
                  torch.sum(targets) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
  
          self.log(
              "train/accuracy",
              self.train_accuracy(scores, targets),
              on_step=on_step,
              on_epoch=on_epoch,
          )
          self.log(
              "train/recall",
              self.train_recall(scores, targets),
              on_step=on_step,
              on_epoch=on_epoch,
          )
          self.log(
              "train/precision",
              self.train_precision(scores, targets),
              on_step=on_step,
              on_epoch=on_epoch,
          )
          self.log(
              "train/f1",
              self.train_f1(scores, targets),
              on_step=on_step,
              on_epoch=on_epoch,
          )
  
      elif stage == "val":
          self.log("val/loss", loss, on_step=on_step, on_epoch=on_epoch)
          if self.hparams.loss_type in [
              "robust",
              "asymmetric",
              "asymmetric_dynamic",
          ]:
              self.log(
                  "val/pos_samples",
                  torch.sum(targets[:, 1]) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
              self.log(
                  "val/pos_predictions",
                  sum(scores[:, 0] < 0.5) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
          else:
              self.log(
                  "val/pos_samples",
                  torch.sum(targets) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
  
          self.val_cr_f1.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
          self.val_cr_bacc.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
          self.val_cr_mcc.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
          self.val_aul.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
  
          self.log(
              "val/f1_corrected",
              self.val_cr_f1,
              on_step=False,
              on_epoch=True,
          )
          self.log(
              "val/bacc_corrected",
              self.val_cr_bacc,
              on_step=False,
              on_epoch=True,
          )
          self.log(
              "val/mcc_corrected",
              self.val_cr_mcc,
              on_step=False,
              on_epoch=True,
          )
          self.log(
              "val/aul", self.val_aul, on_step=False, on_epoch=True
          )
  
      elif stage == "test":
          self.log(
              "test/loss", loss, on_step=on_step, on_epoch=on_epoch
          )
          if self.hparams.loss_type in [
              "robust",
              "asymmetric",
              "asymmetric_dynamic",
          ]:
              self.log(
                  "test/pos_samples",
                  torch.sum(targets[:, 1]) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
              self.log(
                  "test/pos_predictions",
                  sum(scores[:, 0] < 0.5) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
  
          else:
              self.log(
                  "test/pos_samples",
                  torch.sum(targets) / targets.shape[0],
                  on_step=on_step,
                  on_epoch=on_epoch,
              )
  
          self.test_cr_f1.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
          self.test_cr_bacc.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
          self.test_cr_mcc.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
          self.test_aul.update(
              scores[:, 1], targets[:, 1]
          )  # this should not happen in self.log
  
          self.test_trg.update(targets[:, 1])
          self.test_prb.update(scores[:, 1])
  
          self.log(
              "test/f1_corrected",
              self.test_cr_f1,
              on_step=False,
              on_epoch=True,
          )
          self.log(
              "test/bacc_corrected",
              self.test_cr_bacc,
              on_step=False,
              on_epoch=True,
          )
          self.log(
              "test/mcc_corrected",
              self.test_cr_mcc,
              on_step=False,
              on_epoch=True,
          )
          self.log(
              "test/aul", self.test_aul, on_step=False, on_epoch=True
          )
  
imports: from turtle import hideturtle
  import pytorch_lightning
  import torch
  import torch.nn.functional
  import torch.nn
  from pytorch_lightning import seed_everything
  from pathlib import Path
  from src.transformer.transformer_utils import *
  from src.transformer.metrics import CorrectedBAcc, CorrectedF1, CorrectedMCC, AUL
  import torchmetrics
label_desc: Use image node_id 13 for calling the FFN obj's underlying member method code with example usage: obj.log_metrics(predictions, targets, loss, stage, on_step, on_epoch) without return types