Repository: Project-MONAI/MONAI
File: monai/metrics/generalized_dice.py (Python)

Code before:
    loss function for highly unbalanced segmentations. DLMIA 2017.

    The inputs `y_pred` and `y` are expected to be one-hot, binarized batch-first tensors, i.e., NCHW[D].

    Example of the typical execution steps of this metric class follows :py:class:`monai.metrics.metric.Cumulative`.

    Args:
        include_background: Whether to include the background class (assumed to be in channel 0) in the
            score computation. Defaults to True.
        reduction: Define mode of reduction to the metrics. Available reduction modes:
           {``"none"``, ``"mean"``, ``"sum"``, ``"mean_batch"``, ``"sum_batch"``,
            ``"mean_channel"``, ``"sum_channel"``}, default to ``"mean"``. if "none", will not do reduction.
        weight_type: {``"square"``, ``"simple"``, ``"uniform"``}. Type of function to transform
            ground truth volume into a weight factor. Defaults to ``"square"``.

    Raises:
        ValueError: When the `reduction` is not one of MetricReduction enum.
    """

    @deprecated_arg_default(
        "reduction",
        old_default=MetricReduction.MEAN_BATCH,
        new_default=MetricReduction.MEAN,
        since="1.3.3",
        replaced="1.3.3",
        msg_suffix="Old versions computed `mean` when `mean_batch` was provided due to bug in reduction",
    )
    def __init__(
        self,
        include_background: bool = True,
        reduction: MetricReduction | str = MetricReduction.MEAN,
        weight_type: Weight | str = Weight.SQUARE,
    ) -> None:
        super().__init__()
        self.include_background = include_background
        self.reduction = look_up_option(reduction, MetricReduction)
        self.weight_type = look_up_option(weight_type, Weight)
        self.sum_over_classes = self.reduction == MetricReduction.SUM or self.reduction == MetricReduction.MEAN

    def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor) -> torch.Tensor:  # type: ignore[override]
        """
        Computes the Generalized Dice Score and returns a tensor with its per image values.

        Args:
            y_pred (torch.Tensor): Binarized segmentation model output. It must be in one-hot format and in the NCHW[D] format,
                where N is the batch dimension, C is the channel dimension, and the remaining are the spatial dimensions.
            y (torch.Tensor): Binarized ground-truth. It must be in one-hot format and have the same shape as `y_pred`.

        Returns:
            torch.Tensor: Generalized Dice Score averaged across batch and class


Review comment (bug):
Instead of immediately updating the default behavior, we need to provide users with some time to adapt to this change. We should also issue a warning to inform users that the mean_batch behavior is no longer the same as before, since it previously calculated the mean. If users want to retain the previous behavior, they will need to explicitly set the parameter to "mean".
```suggestion
        since="1.4.0",
        replaced="1.5.0",
        msg_suffix="Old versions computed `mean` when `mean_batch` was provided due to bug in reduction， If you want to retain the old behavior (calculating the mean), please explicitly set the parameter to 'mean'.",
```

cc @ericspod

Code after:
    loss function for highly unbalanced segmentations. DLMIA 2017.

    The inputs `y_pred` and `y` are expected to be one-hot, binarized batch-first tensors, i.e., NCHW[D].

    Example of the typical execution steps of this metric class follows :py:class:`monai.metrics.metric.Cumulative`.

    Args:
        include_background: Whether to include the background class (assumed to be in channel 0) in the
            score computation. Defaults to True.
        reduction: Define mode of reduction to the metrics. Available reduction modes:
            {``"none"``, ``"mean"``, ``"sum"``, ``"mean_batch"``, ``"sum_batch"``,
            ``"mean_channel"``, ``"sum_channel"``}, default to ``"mean"``. if "none", will not do reduction.
        weight_type: {``"square"``, ``"simple"``, ``"uniform"``}. Type of function to transform
            ground truth volume into a weight factor. Defaults to ``"square"``.

    Raises:
        ValueError: When the `reduction` is not one of MetricReduction enum.
    """

    @deprecated_arg_default(
        "reduction",
        old_default=MetricReduction.MEAN_BATCH,
        new_default=MetricReduction.MEAN,
        since="1.4.0",
        replaced="1.5.0",
        msg_suffix=(
            "Old versions computed `mean` when `mean_batch` was provided due to bug in reduction， "
            "If you want to retain the old behavior (calculating the mean), please explicitly set the parameter to 'mean'."
        ),
    )
    def __init__(
        self,
        include_background: bool = True,
        reduction: MetricReduction | str = MetricReduction.MEAN_BATCH,
        weight_type: Weight | str = Weight.SQUARE,
    ) -> None:
        super().__init__()
        self.include_background = include_background
        self.reduction = look_up_option(reduction, MetricReduction)
        self.weight_type = look_up_option(weight_type, Weight)
        self.sum_over_classes = self.reduction in {
            MetricReduction.SUM,
            MetricReduction.MEAN,
            MetricReduction.MEAN_CHANNEL,
            MetricReduction.SUM_CHANNEL,
        }

    def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor) -> torch.Tensor:  # type: ignore[override]
        """
        Computes the Generalized Dice Score and returns a tensor with its per image values.