Shortcuts

Source code for torch_uncertainty.metrics.regression.silog

from typing import Any

import torch
from torch import Tensor
from torchmetrics import Metric
from torchmetrics.utilities.data import dim_zero_cat


[docs]class SILog(Metric): def __init__(self, sqrt: bool = False, lmbda: float = 1.0, **kwargs: Any) -> None: r"""The Scale-Invariant Logarithmic Loss metric. .. math:: \text{SILog} = \frac{1}{N} \sum_{i=1}^{N} \left(\log(y_i) - \log(\hat{y_i})\right)^2 - \left(\frac{1}{N} \sum_{i=1}^{N} \log(y_i) \right)^2, where :math:`N` is the batch size, :math:`y_i` is a tensor of target values and :math:`\hat{y_i}` is a tensor of prediction. Return the square root of SILog by setting :attr:`sqrt` to `True`. Args: sqrt: If `True`, return the square root of the metric. Defaults to False. lmbda: The regularization parameter on the variance of error. Defaults to 1.0. kwargs: Additional keyword arguments, see `Advanced metric settings <https://torchmetrics.readthedocs.io/en/stable/pages/overview.html#metric-kwargs>`_. Reference: Depth Map Prediction from a Single Image using a Multi-Scale Deep Network. David Eigen, Christian Puhrsch, Rob Fergus. NeurIPS 2014. From Big to Small: Multi-Scale Local Planar Guidance for Monocular Depth Estimation. Jin Han Lee, Myung-Kyu Han, Dong Wook Ko and Il Hong Suh. (For :attr:`lmbda`) """ super().__init__(**kwargs) self.sqrt = sqrt self.lmbda = lmbda self.add_state( "log_dists", default=torch.tensor(0.0), dist_reduce_fx="sum", ) self.add_state( "sq_log_dists", default=torch.tensor(0.0), dist_reduce_fx="sum", ) self.add_state("total", default=torch.tensor(0), dist_reduce_fx="sum")
[docs] def update(self, pred: Tensor, target: Tensor) -> None: """Update state with predictions and targets. Args: pred (Tensor): A prediction tensor of shape (batch) target (Tensor): A tensor of ground truth labels of shape (batch) """ self.log_dists += torch.sum(pred.log() - target.log()) self.sq_log_dists += torch.sum((pred.log() - target.log()) ** 2) self.total += target.size(0)
[docs] def compute(self) -> Tensor: """Compute the Scale-Invariant Logarithmic Loss.""" log_dists = dim_zero_cat(self.log_dists) sq_log_dists = dim_zero_cat(self.sq_log_dists) out = sq_log_dists / self.total - self.lmbda * log_dists**2 / (self.total * self.total) if self.sqrt: return torch.sqrt(out) return out