Beispiel #1
0
    def __init__(
        self,
        data_range: Optional[float] = None,
        base: float = 10.0,
        reduction: Literal["elementwise_mean", "sum", "none",
                           None] = "elementwise_mean",
        dim: Optional[Union[int, Tuple[int, ...]]] = None,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        if dim is None and reduction != "elementwise_mean":
            rank_zero_warn(
                f"The `reduction={reduction}` will not have any effect when `dim` is None."
            )

        if dim is None:
            self.add_state("sum_squared_error",
                           default=tensor(0.0),
                           dist_reduce_fx="sum")
            self.add_state("total", default=tensor(0), dist_reduce_fx="sum")
        else:
            self.add_state("sum_squared_error", default=[])
            self.add_state("total", default=[])

        if data_range is None:
            if dim is not None:
                # Maybe we could use `torch.amax(target, dim=dim) - torch.amin(target, dim=dim)` in PyTorch 1.7 to
                # calculate `data_range` in the future.
                raise ValueError(
                    "The `data_range` must be given when `dim` is not None.")

            self.data_range = None
            self.add_state("min_target",
                           default=tensor(0.0),
                           dist_reduce_fx=torch.min)
            self.add_state("max_target",
                           default=tensor(0.0),
                           dist_reduce_fx=torch.max)
        else:
            self.add_state("data_range",
                           default=tensor(float(data_range)),
                           dist_reduce_fx="mean")
        self.base = base
        self.reduction = reduction
        self.dim = tuple(dim) if isinstance(dim, Sequence) else dim
Beispiel #2
0
    def __init__(
        self,
        num_classes: Optional[int] = None,
        pos_label: Optional[int] = None,
        average: Optional[str] = 'macro',
        max_fpr: Optional[float] = None,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
        dist_sync_fn: Callable = None,
    ):
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
            dist_sync_fn=dist_sync_fn,
        )

        self.num_classes = num_classes
        self.pos_label = pos_label
        self.average = average
        self.max_fpr = max_fpr

        allowed_average = (None, 'macro', 'weighted', 'micro')
        if self.average not in allowed_average:
            raise ValueError(
                f'Argument `average` expected to be one of the following: {allowed_average} but got {average}'
            )

        if self.max_fpr is not None:
            if not isinstance(max_fpr, float) or not 0 < max_fpr <= 1:
                raise ValueError(
                    f"`max_fpr` should be a float in range (0, 1], got: {max_fpr}"
                )

            if _TORCH_LOWER_1_6:
                raise RuntimeError(
                    '`max_fpr` argument requires `torch.bucketize` which is not available below PyTorch version 1.6'
                )

        self.mode = None
        self.add_state("preds", default=[], dist_reduce_fx=None)
        self.add_state("target", default=[], dist_reduce_fx=None)

        rank_zero_warn(
            'Metric `AUROC` will save all targets and predictions in buffer.'
            ' For large datasets this may lead to large memory footprint.')
Beispiel #3
0
    def __init__(
        self,
        ratio: Union[int, float] = 4,
        reduction: Literal["elementwise_mean", "sum", "none",
                           None] = "elementwise_mean",
        **kwargs: Any,
    ) -> None:
        super().__init__(**kwargs)
        rank_zero_warn(
            "Metric `UniversalImageQualityIndex` will save all targets and"
            " predictions in buffer. For large datasets this may lead"
            " to large memory footprint.")

        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")
        self.ratio = ratio
        self.reduction = reduction
Beispiel #4
0
    def __init__(
        self,
        reorder: bool = False,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        self.reorder = reorder

        self.add_state("x", default=[], dist_reduce_fx="cat")
        self.add_state("y", default=[], dist_reduce_fx="cat")

        rank_zero_warn(
            "Metric `AUC` will save all targets and predictions in buffer."
            " For large datasets this may lead to large memory footprint."
        )
def _precision_recall_curve_update(
    preds: Tensor,
    target: Tensor,
    num_classes: Optional[int] = None,
    pos_label: Optional[int] = None,
) -> Tuple[Tensor, Tensor, int, Optional[int]]:
    if len(preds.shape) == len(target.shape):
        if pos_label is None:
            rank_zero_warn('`pos_label` automatically set 1.')
            pos_label = 1
        if num_classes is not None and num_classes != 1:
            # multilabel problem
            if num_classes != preds.shape[1]:
                raise ValueError(
                    f'Argument `num_classes` was set to {num_classes} in'
                    f' metric `precision_recall_curve` but detected {preds.shape[1]}'
                    ' number of classes from predictions'
                )
            preds = preds.transpose(0, 1).reshape(num_classes, -1).transpose(0, 1)
            target = target.transpose(0, 1).reshape(num_classes, -1).transpose(0, 1)
        else:
            # binary problem
            preds = preds.flatten()
            target = target.flatten()
            num_classes = 1

    # multi class problem
    elif len(preds.shape) == len(target.shape) + 1:
        if pos_label is not None:
            rank_zero_warn(
                'Argument `pos_label` should be `None` when running'
                f' multiclass precision recall curve. Got {pos_label}'
            )
        if num_classes != preds.shape[1]:
            raise ValueError(
                f'Argument `num_classes` was set to {num_classes} in'
                f' metric `precision_recall_curve` but detected {preds.shape[1]}'
                ' number of classes from predictions'
            )
        preds = preds.transpose(0, 1).reshape(num_classes, -1).transpose(0, 1)
        target = target.flatten()

    else:
        raise ValueError("preds and target must have same number of dimensions, or one additional dimension for preds")

    return preds, target, num_classes, pos_label
Beispiel #6
0
def _squad_update(
    preds: Dict[str, str],
    target: List[Dict[str, List[Dict[str, List[Dict[str, Any]]]]]],
) -> Tuple[Tensor, Tensor, Tensor]:
    """Compute F1 Score and Exact Match for a collection of predictions and references.

    Args:
        preds:
            A dictionary mapping an `id` to the predicted `answer`.
        target:
            A list of dictionary mapping `paragraphs` to list of dictionary mapping `qas` to a list of dictionary
            containing `id` and list of all possible `answers`.

    Return:
        Tuple containing F1 score, Exact match score and total number of examples.

    Example:
        >>> from torchmetrics.functional.text.squad import _squad_update
        >>> preds = [{"prediction_text": "1976", "id": "56e10a3be3433e1400422b22"}]
        >>> target = [{"answers": {"answer_start": [97], "text": ["1976"]}, "id": "56e10a3be3433e1400422b22"}]
        >>> preds_dict = {pred["id"]: pred["prediction_text"] for pred in preds}
        >>> targets_dict = [
        ...     dict(paragraphs=[dict(qas=[dict(answers=[
        ...         {"text": txt} for txt in tgt["answers"]["text"]], id=tgt["id"]) for tgt in target
        ...     ])])
        ... ]
        >>> _squad_update(preds_dict, targets_dict)
        (tensor(1.), tensor(1.), tensor(1))
    """
    f1 = tensor(0.0)
    exact_match = tensor(0.0)
    total = tensor(0)
    for article in target:
        for paragraph in article["paragraphs"]:
            for qa in paragraph["qas"]:
                total += 1
                if qa["id"] not in preds:
                    rank_zero_warn(f"Unanswered question {qa['id']} will receive score 0.")
                    continue
                ground_truths = list(map(lambda x: x["text"], qa["answers"]))  # type: ignore
                pred = preds[qa["id"]]  # type: ignore
                exact_match += _metric_max_over_ground_truths(_compute_exact_match_score, pred, ground_truths)
                f1 += _metric_max_over_ground_truths(_compute_f1_score, pred, ground_truths)

    return f1, exact_match, total
Beispiel #7
0
        def wrapped_func(*args, **kwargs):
            if not self._update_called:
                rank_zero_warn(
                    f"The ``compute`` method of metric {self.__class__.__name__}"
                    " was called before the ``update`` method which may lead to errors,"
                    " as metric states have not yet been updated.", UserWarning
                )

            # return cached value
            if self._computed is not None:
                return self._computed

            with self.sync_context(
                dist_sync_fn=self.dist_sync_fn, should_sync=self._to_sync, restore_cache=self._restore_cache
            ):
                self._computed = compute(*args, **kwargs)

            return self._computed
Beispiel #8
0
def _confusion_matrix_compute(confmat: torch.Tensor, normalize: Optional[str] = None) -> torch.Tensor:
    allowed_normalize = ('true', 'pred', 'all', 'none', None)
    assert normalize in allowed_normalize, \
        f"Argument average needs to one of the following: {allowed_normalize}"
    confmat = confmat.float()
    if normalize is not None and normalize != 'none':
        if normalize == 'true':
            cm = confmat / confmat.sum(axis=1, keepdim=True)
        elif normalize == 'pred':
            cm = confmat / confmat.sum(axis=0, keepdim=True)
        elif normalize == 'all':
            cm = confmat / confmat.sum()
        nan_elements = cm[torch.isnan(cm)].nelement()
        if nan_elements != 0:
            cm[torch.isnan(cm)] = 0
            rank_zero_warn(f'{nan_elements} nan values found in confusion matrix have been replaced with zeros.')
        return cm
    return confmat
Beispiel #9
0
    def __init__(
        self,
        num_classes: Optional[int] = None,
        pos_label: Optional[int] = None,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        self.num_classes = num_classes
        self.pos_label = pos_label

        self.add_state("preds", default=[], dist_reduce_fx=None)
        self.add_state("target", default=[], dist_reduce_fx=None)

        rank_zero_warn(
            "Metric `ROC` will save all targets and predictions in buffer."
            " For large datasets this may lead to large memory footprint.")
Beispiel #10
0
    def __init__(
        self,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
    ):
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
        )

        rank_zero_warn(
            'Metric `PearsonCorrcoef` will save all targets and predictions in buffer.'
            ' For large datasets this may lead to large memory footprint.')

        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")
Beispiel #11
0
    def __init__(
        self,
        kernel_size: Sequence[int] = (11, 11),
        sigma: Sequence[float] = (1.5, 1.5),
        reduction: Literal["elementwise_mean", "sum", "none", None] = "elementwise_mean",
        data_range: Optional[float] = None,
        k1: float = 0.01,
        k2: float = 0.03,
        betas: Tuple[float, ...] = (0.0448, 0.2856, 0.3001, 0.2363, 0.1333),
        normalize: Literal["relu", "simple", None] = None,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)
        rank_zero_warn(
            "Metric `MS_SSIM` will save all targets and"
            " predictions in buffer. For large datasets this may lead"
            " to large memory footprint."
        )

        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")

        all_kernel_ints = all(isinstance(ks, int) for ks in kernel_size)
        if not isinstance(kernel_size, Sequence) or len(kernel_size) != 2 or not all_kernel_ints:
            raise ValueError(
                "Argument `kernel_size` expected to be an sequence of size 2 where each element is an int"
                f" but got {kernel_size}"
            )
        self.kernel_size = kernel_size
        self.sigma = sigma
        self.data_range = data_range
        self.k1 = k1
        self.k2 = k2
        self.reduction = reduction
        if not isinstance(betas, tuple):
            raise ValueError("Argument `betas` is expected to be of a type tuple.")
        if isinstance(betas, tuple) and not all(isinstance(beta, float) for beta in betas):
            raise ValueError("Argument `betas` is expected to be a tuple of floats.")
        self.betas = betas
        if normalize and normalize not in ("relu", "simple"):
            raise ValueError("Argument `normalize` to be expected either `None` or one of 'relu' or 'simple'")
        self.normalize = normalize
Beispiel #12
0
def _r2score_compute(
    sum_squared_error: Tensor,
    sum_error: Tensor,
    residual: Tensor,
    total: Tensor,
    adjusted: int = 0,
    multioutput: str = "uniform_average",
) -> Tensor:
    mean_error = sum_error / total
    diff = sum_squared_error - sum_error * mean_error
    raw_scores = 1 - (residual / diff)

    if multioutput == "raw_values":
        r2score = raw_scores
    elif multioutput == "uniform_average":
        r2score = torch.mean(raw_scores)
    elif multioutput == "variance_weighted":
        diff_sum = torch.sum(diff)
        r2score = torch.sum(diff / diff_sum * raw_scores)
    else:
        raise ValueError(
            'Argument `multioutput` must be either `raw_values`,'
            f' `uniform_average` or `variance_weighted`. Received {multioutput}.'
        )

    if adjusted < 0 or not isinstance(adjusted, int):
        raise ValueError('`adjusted` parameter should be an integer larger or'
                         ' equal to 0.')

    if adjusted != 0:
        if adjusted > total - 1:
            rank_zero_warn(
                "More independent regressions than data points in"
                " adjusted r2 score. Falls back to standard r2 score.",
                UserWarning)
        elif adjusted == total - 1:
            rank_zero_warn(
                "Division by zero in adjusted r2 score. Falls back to"
                " standard r2 score.", UserWarning)
        else:
            r2score = 1 - (1 - r2score) * (total - 1) / (total - adjusted - 1)
    return r2score
Beispiel #13
0
    def __init__(
            self,
            feature: Union[str, int, torch.nn.Module] = 'logits_unbiased',
            splits: int = 10,
            compute_on_step: bool = False,
            dist_sync_on_step: bool = False,
            process_group: Optional[Any] = None,
            dist_sync_fn: Callable[[Tensor], List[Tensor]] = None) -> None:
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
            dist_sync_fn=dist_sync_fn,
        )

        rank_zero_warn(
            'Metric `IS` will save all extracted features in buffer.'
            ' For large datasets this may lead to large memory footprint.',
            UserWarning)

        if isinstance(feature, (str, int)):
            if not _TORCH_FIDELITY_AVAILABLE:
                raise ValueError(
                    'IS metric requires that Torch-fidelity is installed.'
                    'Either install as `pip install torchmetrics[image]`'
                    ' or `pip install torch-fidelity`')
            valid_int_input = ('logits_unbiased', 64, 192, 768, 2048)
            if feature not in valid_int_input:
                raise ValueError(
                    f'Integer input to argument `feature` must be one of {valid_int_input},'
                    f' but got {feature}.')

            self.inception = NoTrainInceptionV3(name='inception-v3-compat',
                                                features_list=[str(feature)])
        elif isinstance(feature, torch.nn.Module):
            self.inception = feature
        else:
            raise TypeError('Got unknown input to argument `feature`')

        self.splits = splits
        self.add_state("features", [], dist_reduce_fx=None)
Beispiel #14
0
        def wrapped_func(*args: Any, **kwargs: Any) -> Any:
            if not self._update_called:
                rank_zero_warn(
                    f"The ``compute`` method of metric {self.__class__.__name__}"
                    " was called before the ``update`` method which may lead to errors,"
                    " as metric states have not yet been updated.",
                    UserWarning)

            # return cached value
            if self._computed is not None:
                return self._computed

            # compute relies on the sync context manager to gather the states across processes and apply reduction
            # if synchronization happened, the current rank accumulated states will be restored to keep
            # accumulation going if ``should_unsync=True``,
            with self.sync_context(dist_sync_fn=self.dist_sync_fn,
                                   should_sync=self._to_sync,
                                   should_unsync=self._should_unsync):
                self._computed = compute(*args, **kwargs)

            return self._computed
Beispiel #15
0
    def __init__(
        self,
        data_range: Optional[float] = None,
        base: float = 10.0,
        reduction: str = 'elementwise_mean',
        dim: Optional[Union[int, Tuple[int, ...]]] = None,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
    ):
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
        )

        if dim is None and reduction != 'elementwise_mean':
            rank_zero_warn(f'The `reduction={reduction}` will not have any effect when `dim` is None.')

        if dim is None:
            self.add_state("sum_squared_error", default=tensor(0.0), dist_reduce_fx="sum")
            self.add_state("total", default=tensor(0), dist_reduce_fx="sum")
        else:
            self.add_state("sum_squared_error", default=[])
            self.add_state("total", default=[])

        if data_range is None:
            if dim is not None:
                # Maybe we could use `torch.amax(target, dim=dim) - torch.amin(target, dim=dim)` in PyTorch 1.7 to
                # calculate `data_range` in the future.
                raise ValueError("The `data_range` must be given when `dim` is not None.")

            self.data_range = None
            self.add_state("min_target", default=tensor(0.0), dist_reduce_fx=torch.min)
            self.add_state("max_target", default=tensor(0.0), dist_reduce_fx=torch.max)
        else:
            self.register_buffer("data_range", tensor(float(data_range)))
        self.base = base
        self.reduction = reduction
        self.dim = tuple(dim) if isinstance(dim, Sequence) else dim
Beispiel #16
0
    def __init__(
        self,
        num_classes: Optional[int] = None,
        pos_label: Optional[int] = None,
        average: Optional[str] = "macro",
        max_fpr: Optional[float] = None,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        self.num_classes = num_classes
        self.pos_label = pos_label
        self.average = average
        self.max_fpr = max_fpr

        allowed_average = (None, "macro", "weighted", "micro")
        if self.average not in allowed_average:
            raise ValueError(
                f"Argument `average` expected to be one of the following: {allowed_average} but got {average}"
            )

        if self.max_fpr is not None:
            if not isinstance(max_fpr, float) or not 0 < max_fpr <= 1:
                raise ValueError(
                    f"`max_fpr` should be a float in range (0, 1], got: {max_fpr}"
                )

            if _TORCH_LOWER_1_6:
                raise RuntimeError(
                    "`max_fpr` argument requires `torch.bucketize` which is not available below PyTorch version 1.6"
                )

        self.mode: DataType = None  # type: ignore
        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")

        rank_zero_warn(
            "Metric `AUROC` will save all targets and predictions in buffer."
            " For large datasets this may lead to large memory footprint.")
Beispiel #17
0
    def __init__(
        self,
        feature: Union[int, torch.nn.Module] = 2048,
        reset_real_features: bool = True,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        rank_zero_warn(
            "Metric `FrechetInceptionDistance` will save all extracted features in buffer."
            " For large datasets this may lead to large memory footprint.",
            UserWarning,
        )

        if isinstance(feature, int):
            if not _TORCH_FIDELITY_AVAILABLE:
                raise ModuleNotFoundError(
                    "FrechetInceptionDistance metric requires that `Torch-fidelity` is installed."
                    " Either install as `pip install torchmetrics[image]` or `pip install torch-fidelity`."
                )
            valid_int_input = [64, 192, 768, 2048]
            if feature not in valid_int_input:
                raise ValueError(
                    f"Integer input to argument `feature` must be one of {valid_int_input}, but got {feature}."
                )

            self.inception = NoTrainInceptionV3(name="inception-v3-compat", features_list=[str(feature)])
        elif isinstance(feature, torch.nn.Module):
            self.inception = feature
        else:
            raise TypeError("Got unknown input to argument `feature`")

        if not isinstance(reset_real_features, bool):
            raise ValueError("Argument `reset_real_features` expected to be a bool")
        self.reset_real_features = reset_real_features

        self.add_state("real_features", [], dist_reduce_fx=None)
        self.add_state("fake_features", [], dist_reduce_fx=None)
Beispiel #18
0
    def __init__(
        self,
        kernel_size: Sequence[int] = (11, 11),
        sigma: Sequence[float] = (1.5, 1.5),
        reduction: Literal["elementwise_mean", "sum", "none", None] = "elementwise_mean",
        data_range: Optional[float] = None,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)
        rank_zero_warn(
            "Metric `UniversalImageQualityIndex` will save all targets and"
            " predictions in buffer. For large datasets this may lead"
            " to large memory footprint."
        )

        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")
        self.kernel_size = kernel_size
        self.sigma = sigma
        self.data_range = data_range
        self.reduction = reduction
Beispiel #19
0
        def wrapped_func(*args, **kwargs):
            if not self._update_called:
                rank_zero_warn(
                    f"The ``compute`` method of metric {self.__class__.__name__}"
                    " was called before the ``update`` method which may lead to errors,"
                    " as metric states have not yet been updated.",
                    UserWarning)

            # return cached value
            if self._computed is not None:
                return self._computed

            dist_sync_fn = self.dist_sync_fn
            if dist_sync_fn is None and torch.distributed.is_available(
            ) and torch.distributed.is_initialized():
                # User provided a bool, so we assume DDP if available
                dist_sync_fn = gather_all_tensors

            synced = False
            cache = []
            if self._to_sync and dist_sync_fn is not None:
                # cache prior to syncing
                cache = {
                    attr: getattr(self, attr)
                    for attr in self._defaults.keys()
                }

                # sync
                self._sync_dist(dist_sync_fn)
                synced = True

            self._computed = compute(*args, **kwargs)
            if synced:
                # if we synced, restore to cache so that we can continue to accumulate un-synced state
                for attr, val in cache.items():
                    setattr(self, attr, val)

            return self._computed
Beispiel #20
0
    def __init__(
        self,
        num_classes: int,
        threshold: float = 0.5,
        average: str = "micro",
        multilabel: bool = False,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
    ):
        if multilabel is not False:
            rank_zero_warn(f'The `multilabel={multilabel}` parameter is unused and will not have any effect.')

        super().__init__(
            num_classes=num_classes,
            beta=1.0,
            threshold=threshold,
            average=average,
            multilabel=multilabel,
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
        )
Beispiel #21
0
def _reflection_pad_3d(inputs: Tensor, pad_h: int, pad_w: int,
                       pad_d: int) -> Tensor:
    """Reflective padding of 3d input.

    Args:
        inputs: tensor to pad, should be a 3D tensor of shape ``[N, C, H, W, D]``
        pad_w: amount of padding in the height dimension
        pad_h: amount of padding in the width dimension
        pad_d: amount of padding in the depth dimension

    Returns:
        padded input tensor
    """
    if _TORCH_GREATER_EQUAL_1_10:
        inputs = F.pad(inputs, (pad_h, pad_h, pad_w, pad_w, pad_d, pad_d),
                       mode="reflect")
    else:
        rank_zero_warn(
            "An older version of pyTorch is used. For optimal speed, please upgrade to at least pyTorch 1.10."
        )
        for dim, pad in enumerate([pad_h, pad_w, pad_d]):
            inputs = _single_dimension_pad(inputs, dim + 2, pad)
    return inputs
Beispiel #22
0
    def __init__(self,
                 p: int = 1,
                 reduction: Literal["elementwise_mean", "sum",
                                    "none"] = "elementwise_mean",
                 **kwargs: Any) -> None:
        super().__init__(**kwargs)
        rank_zero_warn(
            "Metric `SpectralDistortionIndex` will save all targets and"
            " predictions in buffer. For large datasets this may lead"
            " to large memory footprint.")

        if not isinstance(p, int) or p <= 0:
            raise ValueError(
                f"Expected `p` to be a positive integer. Got p: {p}.")
        self.p = p
        ALLOWED_REDUCTION = ("elementwise_mean", "sum", "none")
        if reduction not in ALLOWED_REDUCTION:
            raise ValueError(
                f"Expected argument `reduction` be one of {ALLOWED_REDUCTION} but got {reduction}"
            )
        self.reduction = reduction
        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")
Beispiel #23
0
    def __init__(
        self,
        reorder: bool = False,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
        dist_sync_fn: Callable = None,
    ) -> None:
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
            dist_sync_fn=dist_sync_fn,
        )

        self.reorder = reorder

        self.add_state("x", default=[], dist_reduce_fx="cat")
        self.add_state("y", default=[], dist_reduce_fx="cat")

        rank_zero_warn(
            'Metric `AUC` will save all targets and predictions in buffer.'
            ' For large datasets this may lead to large memory footprint.')
    def __init__(
        self,
        num_classes: Optional[int] = None,
        pos_label: Optional[int] = None,
        compute_on_step: bool = True,
        dist_sync_on_step: bool = False,
        process_group: Optional[Any] = None,
    ):
        super().__init__(
            compute_on_step=compute_on_step,
            dist_sync_on_step=dist_sync_on_step,
            process_group=process_group,
        )

        self.num_classes = num_classes
        self.pos_label = pos_label

        self.add_state("preds", default=[], dist_reduce_fx=None)
        self.add_state("target", default=[], dist_reduce_fx=None)

        rank_zero_warn(
            'Metric `PrecisionRecallCurve` will save all targets and predictions in buffer.'
            ' For large datasets this may lead to large memory footprint.')
Beispiel #25
0
def _confusion_matrix_compute(confmat: Tensor,
                              normalize: Optional[str] = None) -> Tensor:
    allowed_normalize = ('true', 'pred', 'all', 'none', None)
    if normalize not in allowed_normalize:
        raise ValueError(
            f"Argument average needs to one of the following: {allowed_normalize}"
        )
    if normalize is not None and normalize != 'none':
        confmat = confmat.float(
        ) if not confmat.is_floating_point() else confmat
        if normalize == 'true':
            confmat = confmat / confmat.sum(axis=1, keepdim=True)
        elif normalize == 'pred':
            confmat = confmat / confmat.sum(axis=0, keepdim=True)
        elif normalize == 'all':
            confmat = confmat / confmat.sum()

        nan_elements = confmat[torch.isnan(confmat)].nelement()
        if nan_elements != 0:
            confmat[torch.isnan(confmat)] = 0
            rank_zero_warn(
                f'{nan_elements} nan values found in confusion matrix have been replaced with zeros.'
            )
    return confmat
Beispiel #26
0
    def __init__(
        self,
        num_classes: Optional[int] = None,
        pos_label: Optional[int] = None,
        average: Optional[str] = "macro",
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        self.num_classes = num_classes
        self.pos_label = pos_label
        allowed_average = ("micro", "macro", "weighted", None)
        if average not in allowed_average:
            raise ValueError(f"Expected argument `average` to be one of {allowed_average}" f" but got {average}")
        self.average = average

        self.add_state("preds", default=[], dist_reduce_fx="cat")
        self.add_state("target", default=[], dist_reduce_fx="cat")

        rank_zero_warn(
            "Metric `AveragePrecision` will save all targets and predictions in buffer."
            " For large datasets this may lead to large memory footprint."
        )
Beispiel #27
0
    def __init__(
        self,
        feature: Union[str, int, torch.nn.Module] = "logits_unbiased",
        splits: int = 10,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        rank_zero_warn(
            "Metric `InceptionScore` will save all extracted features in buffer."
            " For large datasets this may lead to large memory footprint.",
            UserWarning,
        )

        if isinstance(feature, (str, int)):
            if not _TORCH_FIDELITY_AVAILABLE:
                raise ModuleNotFoundError(
                    "InceptionScore metric requires that `Torch-fidelity` is installed."
                    " Either install as `pip install torchmetrics[image]` or `pip install torch-fidelity`."
                )
            valid_int_input = ("logits_unbiased", 64, 192, 768, 2048)
            if feature not in valid_int_input:
                raise ValueError(
                    f"Integer input to argument `feature` must be one of {valid_int_input},"
                    f" but got {feature}.")

            self.inception = NoTrainInceptionV3(name="inception-v3-compat",
                                                features_list=[str(feature)])
        elif isinstance(feature, torch.nn.Module):
            self.inception = feature
        else:
            raise TypeError("Got unknown input to argument `feature`")

        self.splits = splits
        self.add_state("features", [], dist_reduce_fx=None)
Beispiel #28
0
    def __init__(
        self,
        feature: Union[str, int, torch.nn.Module] = 2048,
        subsets: int = 100,
        subset_size: int = 1000,
        degree: int = 3,
        gamma: Optional[float] = None,  # type: ignore
        coef: float = 1.0,
        reset_real_features: bool = True,
        compute_on_step: Optional[bool] = None,
        **kwargs: Dict[str, Any],
    ) -> None:
        super().__init__(compute_on_step=compute_on_step, **kwargs)

        rank_zero_warn(
            "Metric `Kernel Inception Distance` will save all extracted features in buffer."
            " For large datasets this may lead to large memory footprint.",
            UserWarning,
        )

        if isinstance(feature, (str, int)):
            if not _TORCH_FIDELITY_AVAILABLE:
                raise ModuleNotFoundError(
                    "Kernel Inception Distance metric requires that `Torch-fidelity` is installed."
                    " Either install as `pip install torchmetrics[image]` or `pip install torch-fidelity`."
                )
            valid_int_input = ("logits_unbiased", 64, 192, 768, 2048)
            if feature not in valid_int_input:
                raise ValueError(
                    f"Integer input to argument `feature` must be one of {valid_int_input}," f" but got {feature}."
                )

            self.inception: Module = NoTrainInceptionV3(name="inception-v3-compat", features_list=[str(feature)])
        elif isinstance(feature, Module):
            self.inception = feature
        else:
            raise TypeError("Got unknown input to argument `feature`")

        if not (isinstance(subsets, int) and subsets > 0):
            raise ValueError("Argument `subsets` expected to be integer larger than 0")
        self.subsets = subsets

        if not (isinstance(subset_size, int) and subset_size > 0):
            raise ValueError("Argument `subset_size` expected to be integer larger than 0")
        self.subset_size = subset_size

        if not (isinstance(degree, int) and degree > 0):
            raise ValueError("Argument `degree` expected to be integer larger than 0")
        self.degree = degree

        if gamma is not None and not (isinstance(gamma, float) and gamma > 0):
            raise ValueError("Argument `gamma` expected to be `None` or float larger than 0")
        self.gamma = gamma

        if not (isinstance(coef, float) and coef > 0):
            raise ValueError("Argument `coef` expected to be float larger than 0")
        self.coef = coef

        if not isinstance(reset_real_features, bool):
            raise ValueError("Arugment `reset_real_features` expected to be a bool")
        self.reset_real_features = reset_real_features

        # states for extracted features
        self.add_state("real_features", [], dist_reduce_fx=None)
        self.add_state("fake_features", [], dist_reduce_fx=None)
Beispiel #29
0
def peak_signal_noise_ratio(
    preds: Tensor,
    target: Tensor,
    data_range: Optional[float] = None,
    base: float = 10.0,
    reduction: Literal["elementwise_mean", "sum", "none",
                       None] = "elementwise_mean",
    dim: Optional[Union[int, Tuple[int, ...]]] = None,
) -> Tensor:
    """Computes the peak signal-to-noise ratio.

    Args:
        preds: estimated signal
        target: groun truth signal
        data_range: the range of the data. If None, it is determined from the data (max - min).
            ``data_range`` must be given when ``dim`` is not None.
        base: a base of a logarithm to use
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean (default)
            - ``'sum'``: takes the sum
            - ``'none'`` or None``: no reduction will be applied

        dim:
            Dimensions to reduce PSNR scores over provided as either an integer or a list of integers. Default is
            None meaning scores will be reduced across all dimensions.

    Return:
        Tensor with PSNR score

    Raises:
        ValueError:
            If ``dim`` is not ``None`` and ``data_range`` is not provided.

    Example:
        >>> from torchmetrics.functional import peak_signal_noise_ratio
        >>> pred = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
        >>> target = torch.tensor([[3.0, 2.0], [1.0, 0.0]])
        >>> peak_signal_noise_ratio(pred, target)
        tensor(2.5527)

    .. note::
        Half precision is only support on GPU for this metric
    """
    if dim is None and reduction != "elementwise_mean":
        rank_zero_warn(
            f"The `reduction={reduction}` will not have any effect when `dim` is None."
        )

    if data_range is None:
        if dim is not None:
            # Maybe we could use `torch.amax(target, dim=dim) - torch.amin(target, dim=dim)` in PyTorch 1.7 to calculate
            # `data_range` in the future.
            raise ValueError(
                "The `data_range` must be given when `dim` is not None.")

        data_range = target.max() - target.min()
    else:
        data_range = tensor(float(data_range))
    sum_squared_error, n_obs = _psnr_update(preds, target, dim=dim)
    return _psnr_compute(sum_squared_error,
                         n_obs,
                         data_range,
                         base=base,
                         reduction=reduction)
Beispiel #30
0
def _confusion_matrix_compute(confmat: Tensor,
                              normalize: Optional[str] = None) -> Tensor:
    """Computes confusion matrix based on the normalization mode.

    Args:
        confmat: Confusion matrix without normalization
        normalize: Normalization mode for confusion matrix. Choose from
            - ``None`` or ``'none'``: no normalization (default)
            - ``'true'``: normalization over the targets (most commonly used)
            - ``'pred'``: normalization over the predictions
            - ``'all'``: normalization over the whole matrix

    Example:
        >>> # binary case
        >>> target = torch.tensor([1, 1, 0, 0])
        >>> preds = torch.tensor([0, 1, 0, 0])
        >>> confmat = _confusion_matrix_update(preds, target, num_classes=2)
        >>> _confusion_matrix_compute(confmat)
        tensor([[2, 0],
                [1, 1]])

        >>> # multiclass case
        >>> target = torch.tensor([2, 1, 0, 0])
        >>> preds = torch.tensor([2, 1, 0, 1])
        >>> confmat = _confusion_matrix_update(preds, target, num_classes=3)
        >>> _confusion_matrix_compute(confmat)
        tensor([[1, 1, 0],
                [0, 1, 0],
                [0, 0, 1]])

        >>> # multilabel case
        >>> target = torch.tensor([[0, 1, 0], [1, 0, 1]])
        >>> preds = torch.tensor([[0, 0, 1], [1, 0, 1]])
        >>> confmat = _confusion_matrix_update(preds, target, num_classes=3, multilabel=True)
        >>> _confusion_matrix_compute(confmat)
        tensor([[[1, 0], [0, 1]],
                [[1, 0], [1, 0]],
                [[0, 1], [0, 1]]])
    """

    allowed_normalize = ("true", "pred", "all", "none", None)
    if normalize not in allowed_normalize:
        raise ValueError(
            f"Argument average needs to one of the following: {allowed_normalize}"
        )
    if normalize is not None and normalize != "none":
        confmat = confmat.float(
        ) if not confmat.is_floating_point() else confmat
        if normalize == "true":
            confmat = confmat / confmat.sum(axis=1, keepdim=True)
        elif normalize == "pred":
            confmat = confmat / confmat.sum(axis=0, keepdim=True)
        elif normalize == "all":
            confmat = confmat / confmat.sum()

        nan_elements = confmat[torch.isnan(confmat)].nelement()
        if nan_elements != 0:
            confmat[torch.isnan(confmat)] = 0
            rank_zero_warn(
                f"{nan_elements} nan values found in confusion matrix have been replaced with zeros."
            )
    return confmat