code: def tversky_loss(
      pred: torch.Tensor,
      target: torch.Tensor,
      alpha: float,
      beta: float,
      eps: float = 1e-8,
  ) -> torch.Tensor:
      r"""Criterion that computes Tversky Coefficient loss.
  
      According to :cite:`salehi2017tversky`, we compute the Tversky Coefficient as follows:
  
      .. math::
  
          \text{S}(P, G, \alpha; \beta) =
            \frac{|PG|}{|PG| + \alpha |P \setminus G| + \beta |G \setminus P|}
  
      Where:
         - :math:`P` and :math:`G` are the predicted and ground truth binary
           labels.
         - :math:`\alpha` and :math:`\beta` control the magnitude of the
           penalties for FPs and FNs, respectively.
  
      Note:
         - :math:`\alpha = \beta = 0.5` => dice coeff
         - :math:`\alpha = \beta = 1` => tanimoto coeff
         - :math:`\alpha + \beta = 1` => F beta coeff
  
      Args:
          pred: logits tensor with shape :math:`(N, C, H, W)` where C = number of classes.
          target: labels tensor with shape :math:`(N, H, W)` where each value
            is :math:`0 ≤ targets[i] ≤ C-1`.
          alpha: the first coefficient in the denominator.
          beta: the second coefficient in the denominator.
          eps: scalar for numerical stability.
  
      Return:
          the computed loss.
  
      Example:
          >>> N = 5  # num_classes
          >>> pred = torch.randn(1, N, 3, 5, requires_grad=True)
          >>> target = torch.empty(1, 3, 5, dtype=torch.long).random_(N)
          >>> output = tversky_loss(pred, target, alpha=0.5, beta=0.5)
          >>> output.backward()
      """
      if not isinstance(pred, torch.Tensor):
          raise TypeError(
              f"pred type is not a torch.Tensor. Got {type(pred)}"
          )
  
      if not len(pred.shape) == 4:
          raise ValueError(
              f"Invalid pred shape, we expect BxNxHxW. Got: {pred.shape}"
          )
  
      if not pred.shape[-2:] == target.shape[-2:]:
          raise ValueError(
              f"pred and target shapes must be the same. Got: {pred.shape} and {target.shape}"
          )
  
      if not pred.device == target.device:
          raise ValueError(
              f"pred and target must be in the same device. Got: {pred.device} and {target.device}"
          )
  
      # compute softmax over the classes axis
      pred_soft: torch.Tensor = F.softmax(pred, dim=1)
  
      # create the labels one hot tensor
      target_one_hot: torch.Tensor = one_hot(
          target,
          num_classes=pred.shape[1],
          device=pred.device,
          dtype=pred.dtype,
      )
  
      # compute the actual dice score
      dims = (1, 2, 3)
      intersection = torch.sum(pred_soft * target_one_hot, dims)
      fps = torch.sum(pred_soft * (-target_one_hot + 1.0), dims)
      fns = torch.sum((-pred_soft + 1.0) * target_one_hot, dims)
  
      numerator = intersection
      denominator = intersection + alpha * fps + beta * fns
      tversky_loss = numerator / (denominator + eps)
  
      return torch.mean(-tversky_loss + 1.0)
  
file_path: kornia/kornia/losses/tversky.py
imports: from __future__ import annotations
  import torch
  import torch.nn.functional
  from torch import nn
  from kornia.utils.one_hot import one_hot
label_desc: Use image node_id 1 for calling a global function with example usage: tversky_loss(pred, target, alpha, beta, eps) and returns: torch