class_docstr: Differentiable global mutual information loss via Parzen windowing method.
  
  Reference:
      https://dspace.mit.edu/handle/1721.1/123142, Section 3.1, equation 3.1-3.5, Algorithm 1
class_docstr_tok: ["Differentiable","global","mutual","information","loss","via","Parzen","windowing","method",".","Reference",":","https",":","\/\/dspace.mit.edu\/handle\/1721.1\/123142",",","Section","3.1",",","equation","3.1-3.5",",","Algorithm","1"]
docstr: Args:
      pred: the shape should be B[NDHW].
      target: the shape should be same as the pred shape.
  Raises:
      ValueError: When ``self.reduction`` is not one of ["mean", "sum", "none"].
docstr_tok: ["Args",":","pred",":","the","shape","should","be","B","[","NDHW","]",".","target",":","the","shape","should","be","same","as","the","pred","shape",".","Raises",":","ValueError",":","When","``","self.reduction","``","is","not","one","of","[","``","mean","''",",","``","sum","''",",","``","none","''","]","."]
code: def forward(
      self, pred: torch.Tensor, target: torch.Tensor
  ) -> torch.Tensor:
      """
      Args:
          pred: the shape should be B[NDHW].
          target: the shape should be same as the pred shape.
      Raises:
          ValueError: When ``self.reduction`` is not one of ["mean", "sum", "none"].
      """
      if target.shape != pred.shape:
          raise ValueError(
              f"ground truth has differing shape ({target.shape}) from pred ({pred.shape})"
          )
      wa, pa, wb, pb = self.parzen_windowing(
          pred, target
      )  # (batch, num_sample, num_bin), (batch, 1, num_bin)
  
      pab = torch.bmm(wa.permute(0, 2, 1), wb.to(wa)).div(
          wa.shape[1]
      )  # (batch, num_bins, num_bins)
      papb = torch.bmm(
          pa.permute(0, 2, 1), pb.to(pa)
      )  # (batch, num_bins, num_bins)
      mi = torch.sum(
          pab
          * torch.log(
              (pab + self.smooth_nr) / (papb + self.smooth_dr)
              + self.smooth_dr
          ),
          dim=(1, 2),
      )  # (batch)
  
      if self.reduction == LossReduction.SUM.value:
          return torch.sum(
              mi
          ).neg()  # sum over the batch and channel ndims
      if self.reduction == LossReduction.NONE.value:
          return mi.neg()
      if self.reduction == LossReduction.MEAN.value:
          return torch.mean(
              mi
          ).neg()  # average over the batch and channel ndims
      raise ValueError(
          f'Unsupported reduction: {self.reduction}, available options are ["mean", "sum", "none"].'
      )
  
imports: from __future__ import annotations
  import torch
  from torch.nn import functional
  from torch.nn.modules.loss import _Loss
  from monai.networks.layers import gaussian_1d, separable_filtering
  from monai.utils import LossReduction
  from monai.utils.module import look_up_option
label_desc: Use image node_id 5 for calling the GlobalMutualInformationLoss obj's underlying member method code with example usage: obj.forward(pred, target) and returns: torch, mi, torch