docstr: Calculates the metrics for the model.
  
  Args:
      y (torch.Tensor): The target tensor
  
      y_hat (torch.Tensor): The predicted tensor
  
      tag (str): The tag to use for logging
  
  Returns:
      List[torch.Tensor]: The list of metric values
code: def calculate_metrics(
      self, y: torch.Tensor, y_hat: torch.Tensor, tag: str
  ) -> List[torch.Tensor]:
      """Calculates the metrics for the model.
  
      Args:
          y (torch.Tensor): The target tensor
  
          y_hat (torch.Tensor): The predicted tensor
  
          tag (str): The tag to use for logging
  
      Returns:
          List[torch.Tensor]: The list of metric values
      """
      metrics = []
      for metric, metric_str, prob_inp, metric_params in zip(
          self.metrics,
          self.hparams.metrics,
          self.hparams.metrics_prob_input,
          self.hparams.metrics_params,
      ):
          if self.hparams.task == "regression":
              _metrics = []
              for i in range(self.hparams.output_dim):
                  name = (
                      metric.func.__name__
                      if isinstance(metric, partial)
                      else metric.__name__
                  )
                  if (
                      name
                      == torchmetrics.functional.mean_squared_log_error.__name__
                  ):
                      # MSLE should only be used in strictly positive targets. It is undefined otherwise
                      _metric = metric(
                          torch.clamp(y_hat[:, i], min=0),
                          torch.clamp(y[:, i], min=0),
                          **metric_params,
                      )
                  else:
                      _metric = metric(
                          y_hat[:, i], y[:, i], **metric_params
                      )
                  if self.hparams.output_dim > 1:
                      self.log(
                          f"{tag}_{metric_str}_{i}",
                          _metric,
                          on_epoch=True,
                          on_step=False,
                          logger=True,
                          prog_bar=False,
                      )
                  _metrics.append(_metric)
              avg_metric = torch.stack(_metrics, dim=0).sum()
          else:
              y_hat = nn.Softmax(dim=-1)(y_hat.squeeze())
              if prob_inp:
                  avg_metric = metric(
                      y_hat, y.squeeze(), **metric_params
                  )
              else:
                  avg_metric = metric(
                      torch.argmax(y_hat, dim=-1),
                      y.squeeze(),
                      **metric_params,
                  )
          metrics.append(avg_metric)
          self.log(
              f"{tag}_{metric_str}",
              avg_metric,
              on_epoch=True,
              on_step=False,
              logger=True,
              prog_bar=True,
          )
      return metrics
  
imports: import importlib
  import warnings
  from abc import ABCMeta, abstractmethod
  from functools import partial
  from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
  import numpy
  import pytorch_lightning
  import torch
  import torch.nn
  import torchmetrics
  from omegaconf import DictConfig, OmegaConf
  from pandas import DataFrame
  from torch import Tensor
  from torch.optim import Optimizer
  from pytorch_tabular.models.common.heads import blocks
  from pytorch_tabular.models.common.layers import PreEncoded1dLayer
  from pytorch_tabular.utils import get_logger, reset_all_weights
label_desc: Use image node_id 11 for calling the BaseModel obj's underlying member method code with example usage: obj.calculate_metrics(y, y_hat, tag) and returns: metrics