Spaces:
Sleeping
Sleeping
| # This source code is provided for the purposes of scientific reproducibility | |
| # under the following limited license from Element AI Inc. The code is an | |
| # implementation of the N-BEATS model (Oreshkin et al., N-BEATS: Neural basis | |
| # expansion analysis for interpretable time series forecasting, | |
| # https://arxiv.org/abs/1905.10437). The copyright to the source code is | |
| # licensed under the Creative Commons - Attribution-NonCommercial 4.0 | |
| # International license (CC BY-NC 4.0): | |
| # https://creativecommons.org/licenses/by-nc/4.0/. Any commercial use (whether | |
| # for the benefit of third parties or internally in production) requires an | |
| # explicit license. The subject-matter of the N-BEATS model and associated | |
| # materials are the property of Element AI Inc. and may be subject to patent | |
| # protection. No license to patents is granted hereunder (whether express or | |
| # implied). Copyright © 2020 Element AI Inc. All rights reserved. | |
| """ | |
| Loss functions for PyTorch. | |
| """ | |
| import torch as t | |
| import torch.nn as nn | |
| import numpy as np | |
| import pdb | |
| def divide_no_nan(a, b): | |
| """ | |
| a/b where the resulted NaN or Inf are replaced by 0. | |
| """ | |
| result = a / b | |
| result[result != result] = .0 | |
| result[result == np.inf] = .0 | |
| return result | |
| class mape_loss(nn.Module): | |
| def __init__(self): | |
| super(mape_loss, self).__init__() | |
| def forward(self, insample: t.Tensor, freq: int, | |
| forecast: t.Tensor, target: t.Tensor, mask: t.Tensor) -> t.float: | |
| """ | |
| MAPE loss as defined in: https://en.wikipedia.org/wiki/Mean_absolute_percentage_error | |
| :param forecast: Forecast values. Shape: batch, time | |
| :param target: Target values. Shape: batch, time | |
| :param mask: 0/1 mask. Shape: batch, time | |
| :return: Loss value | |
| """ | |
| weights = divide_no_nan(mask, target) | |
| return t.mean(t.abs((forecast - target) * weights)) | |
| class smape_loss(nn.Module): | |
| def __init__(self): | |
| super(smape_loss, self).__init__() | |
| def forward(self, insample: t.Tensor, freq: int, | |
| forecast: t.Tensor, target: t.Tensor, mask: t.Tensor) -> t.float: | |
| """ | |
| sMAPE loss as defined in https://robjhyndman.com/hyndsight/smape/ (Makridakis 1993) | |
| :param forecast: Forecast values. Shape: batch, time | |
| :param target: Target values. Shape: batch, time | |
| :param mask: 0/1 mask. Shape: batch, time | |
| :return: Loss value | |
| """ | |
| return 200 * t.mean(divide_no_nan(t.abs(forecast - target), | |
| t.abs(forecast.data) + t.abs(target.data)) * mask) | |
| class mase_loss(nn.Module): | |
| def __init__(self): | |
| super(mase_loss, self).__init__() | |
| def forward(self, insample: t.Tensor, freq: int, | |
| forecast: t.Tensor, target: t.Tensor, mask: t.Tensor) -> t.float: | |
| """ | |
| MASE loss as defined in "Scaled Errors" https://robjhyndman.com/papers/mase.pdf | |
| :param insample: Insample values. Shape: batch, time_i | |
| :param freq: Frequency value | |
| :param forecast: Forecast values. Shape: batch, time_o | |
| :param target: Target values. Shape: batch, time_o | |
| :param mask: 0/1 mask. Shape: batch, time_o | |
| :return: Loss value | |
| """ | |
| masep = t.mean(t.abs(insample[:, freq:] - insample[:, :-freq]), dim=1) | |
| masked_masep_inv = divide_no_nan(mask, masep[:, None]) | |
| return t.mean(t.abs(target - forecast) * masked_masep_inv) | |