class_docstr: Creates a criterion that computes MSSIM + L1 loss.
  
  According to [1], we compute the MS_SSIM + L1 loss as follows:
  
  .. math::
      \text{loss}(x, y) = \alpha \cdot \mathcal{L_{MSSIM}}(x,y)+(1 - \alpha) \cdot G_\alpha \cdot \mathcal{L_1}(x,y)
  
  Where:
      - :math:`\alpha` is the weight parameter.
      - :math:`x` and :math:`y` are the reconstructed and true reference images.
      - :math:`\mathcal{L_{MSSIM}}` is the MS-SSIM loss.
      - :math:`G_\alpha` is the sigma values for computing multi-scale SSIM.
      - :math:`\mathcal{L_1}` is the L1 loss.
  
  Reference:
      [1]: https://research.nvidia.com/sites/default/files/pubs/2017-03_Loss-Functions-for/NN_ImgProc.pdf#page11
  
  Args:
      sigmas: gaussian sigma values.
      data_range: the range of the images.
      K: k values.
      alpha : specifies the alpha value
      compensation: specifies the scaling coefficient.
      reduction : Specifies the reduction to apply to the
       output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction will be applied,
       ``'mean'``: the sum of the output will be divided by the number of elements
       in the output, ``'sum'``: the output will be summed.
  
  Returns:
      The computed loss.
  
  Shape:
      - Input1: :math:`(N, C, H, W)`.
      - Input2: :math:`(N, C, H, W)`.
      - Output: :math:`(N, H, W)` or scalar if reduction is set to ``'mean'`` or ``'sum'``.
  
  Examples:
      >>> input1 = torch.rand(1, 3, 5, 5)
      >>> input2 = torch.rand(1, 3, 5, 5)
      >>> criterion = kornia.losses.MS_SSIMLoss()
      >>> loss = criterion(input1, input2)
docstr: Compute MS_SSIM loss.
  
  Args:
      img1: the predicted image with shape :math:`(B, C, H, W)`.
      img2: the target image with a shape of :math:`(B, C, H, W)`.
  
  Returns:
      Estimated MS-SSIM_L1 loss.
docstr_tok: ["Compute","MS_SSIM","loss",".","Args",":","img1",":","the","predicted","image","with","shape",":","math",":","`","(","B",",","C",",","H",",","W",")","`",".","img2",":","the","target","image","with","a","shape","of",":","math",":","`","(","B",",","C",",","H",",","W",")","`",".","Returns",":","Estimated","MS-SSIM_L1","loss","."]
code: def forward(
      self, img1: torch.Tensor, img2: torch.Tensor
  ) -> torch.Tensor:
      """Compute MS_SSIM loss.
  
      Args:
          img1: the predicted image with shape :math:`(B, C, H, W)`.
          img2: the target image with a shape of :math:`(B, C, H, W)`.
  
      Returns:
          Estimated MS-SSIM_L1 loss.
      """
      if not isinstance(img1, torch.Tensor):
          raise TypeError(
              f"Input type is not a torch.Tensor. Got {type(img1)}"
          )
  
      if not isinstance(img2, torch.Tensor):
          raise TypeError(
              f"Output type is not a torch.Tensor. Got {type(img2)}"
          )
  
      if not len(img1.shape) == len(img2.shape):
          raise ValueError(
              f"Input shapes should be same. Got {type(img1)} and {type(img2)}."
          )
  
      g_masks: torch.Tensor = torch.jit.annotate(
          torch.Tensor, self._g_masks
      )
  
      CH: int = img1.shape[-3]
      mux = F.conv2d(img1, g_masks, groups=CH, padding=self.pad)
      muy = F.conv2d(img2, g_masks, groups=CH, padding=self.pad)
      mux2 = mux * mux
      muy2 = muy * muy
      muxy = mux * muy
  
      sigmax2 = (
          F.conv2d(img1 * img1, g_masks, groups=CH, padding=self.pad)
          - mux2
      )
      sigmay2 = (
          F.conv2d(img2 * img2, g_masks, groups=CH, padding=self.pad)
          - muy2
      )
      sigmaxy = (
          F.conv2d(img1 * img2, g_masks, groups=CH, padding=self.pad)
          - muxy
      )
  
      lc = (2 * muxy + self.C1) / (mux2 + muy2 + self.C1)
      cs = (2 * sigmaxy + self.C2) / (sigmax2 + sigmay2 + self.C2)
      lM = lc[:, -1, :, :] * lc[:, -2, :, :] * lc[:, -3, :, :]
      PIcs = cs.prod(dim=1)
  
      # Compute MS-SSIM loss
      loss_ms_ssim = 1 - lM * PIcs
  
      # TODO: pass pointer to function e.g. to make more custom with mse, cosine, etc.
      # Compute L1 loss
      loss_l1 = F.l1_loss(img1, img2, reduction="none")
  
      # Compute average l1 loss in 3 channels
      gaussian_l1 = F.conv2d(
          loss_l1, g_masks[-CH:], groups=CH, padding=self.pad
      ).mean(1)
  
      # Compute MS-SSIM + L1 loss
      loss = (
          self.alpha * loss_ms_ssim
          + (1 - self.alpha) * gaussian_l1 / self.DR
      )
      loss = self.compensation * loss
  
      if self.reduction == "mean":
          loss = torch.mean(loss)
      elif self.reduction == "sum":
          loss = torch.sum(loss)
      elif self.reduction == "none":
          pass
      else:
          raise NotImplementedError(
              f"Invalid reduction mode: {self.reduction}"
          )
      return loss
  
file_path: kornia/kornia/losses/ms_ssim.py
imports: from __future__ import annotations
  from typing import Optional
  import torch
  import torch.nn.functional
  from torch import nn
label_desc: Use image node_id 4 for calling the MS_SSIMLoss obj's underlying member method code with example usage: obj.forward(img1, img2) and returns: loss