diff --git a/torchts/nn/loss.py b/torchts/nn/loss.py index 9fcecda1..b1256dac 100644 --- a/torchts/nn/loss.py +++ b/torchts/nn/loss.py @@ -1,7 +1,7 @@ import torch -def masked_mae_loss(y_pred, y_true): +def masked_mae_loss(y_pred: torch.tensor, y_true: torch.tensor) -> torch.tensor: """Calculate masked mean absolute error loss Args: @@ -9,7 +9,7 @@ def masked_mae_loss(y_pred, y_true): y_true (torch.Tensor): True values Returns: - torch.Tensor: Loss + torch.Tensor: output loss """ mask = (y_true != 0).float() mask /= mask.mean() @@ -21,9 +21,7 @@ def masked_mae_loss(y_pred, y_true): return loss.mean() -def mis_loss( - y_pred: torch.tensor, y_true: torch.tensor, interval: float -) -> torch.tensor: +def mis_loss(y_pred: torch.tensor, y_true: torch.tensor, interval: float) -> torch.tensor: """Calculate MIS loss Args: @@ -32,7 +30,7 @@ def mis_loss( interval (float): confidence interval (e.g. 0.95 for 95% confidence interval) Returns: - torch.tensor: output losses + torch.tensor: output loss """ alpha = 1 - interval lower = y_pred[:, 0::2] @@ -46,7 +44,7 @@ def mis_loss( return loss -def quantile_loss(y_pred: torch.tensor, y_true: torch.tensor, quantile: float) -> float: +def quantile_loss(y_pred: torch.tensor, y_true: torch.tensor, quantile: float) -> torch.tensor: """Calculate quantile loss Args: @@ -55,9 +53,48 @@ def quantile_loss(y_pred: torch.tensor, y_true: torch.tensor, quantile: float) - quantile (float): quantile (e.g. 0.5 for median) Returns: - float: output losses + torch.tensor: output loss """ + assert 0 < quantile < 1, "Quantile must be in (0, 1)" errors = y_true - y_pred loss = torch.max((quantile - 1) * errors, quantile * errors) loss = torch.mean(loss) return loss + + +def log_loss(y_pred: torch.tensor, y_true: torch.tensor) -> torch.tensor: + """Ensure the predictions are in the range (0, 1) + Args: + y_pred (torch.tensor): Predicted values + y_true (torch.tensor): True values + + Returns: + torch.tensor: output loss + """ + y_pred = torch.clamp(y_pred, 1e-7, 1 - 1e-7) + return -torch.mean(y_true * torch.log(y_pred) + (1 - y_true) * torch.log(1 - y_pred)) + + +def mape_loss(y_pred: torch.tensor, y_true: torch.tensor) -> torch.tensor: + """Calculate mean absolute percentage loss + Args: + y_pred (torch.tensor): Predicted values + y_true (torch.tensor): True values + + Returns: + torch.tensor: output loss + """ + return torch.mean(torch.abs((y_true - y_pred) / y_true)) * 100 + + +def smape_loss(y_pred: torch.tensor, y_true: torch.tensor) -> torch.tensor: + """Calculate symmetric mean absolute percentage loss + Args: + y_pred (torch.tensor): Predicted values + y_true (torch.tensor): True values + + Returns: + torch.tensor: output loss + """ + denominator = (torch.abs(y_true) + torch.abs(y_pred)) / 2.0 + return torch.mean(torch.abs(y_true - y_pred) / denominator) * 100