Estou usando PyTorch
para um curso de reconhecimento facial e preciso calcular o valor MAPE.
Minha primeira tentativa foi com torchmetrics.MeanAbsolutePercentageError
classe, mas o resultado não faz sentido.
Por esse motivo, escrevi uma função para calculá-lo e parece funcionar bem.
Investigando um pouco, parece-me que o problema está relacionado à presença de 0
no array de valores verdade, mas não encontrei nada na torchmetrics
documentação.
Existe uma maneira de evitar esse problema em torchmetrics
?
É possível que o epsilon
valor na fórmula MAPE não esteja definido? Se for o caso, como posso atribuir um valor a ele?
Estou feliz em usar a outra função, mas estou curioso para entender o motivo desses resultados com torchmetrics
.
Estas são as 2 funções para calcular o MAPE:
def calculate_mape_torch(preds, targets):
"""Calculate MAPE using PyTorch method.
Args:
preds: array with ground truth values
targets: array with predictions from model
Returns:
MAPE
"""
if not isinstance(preds, torch.Tensor):
preds = torch.tensor(preds)
if not isinstance(targets, torch.Tensor):
targets = torch.tensor(targets)
mape = MeanAbsolutePercentageError()
return mape(preds, targets) * 100
def calculate_mape(preds, targets, epsilon=1):
"""Calculate the Mean Absolute Percentage Error.
Args:
preds: array with ground truth values
targets: array with predictions from model
epsilon: value to avoid divide by zero problem
Returns:
MAPE
"""
preds_flatten = preds.flatten("F")
targets_flatten = targets.flatten("F")
return np.sum(np.abs(targets_flatten - preds_flatten) / np.maximum(epsilon, targets_flatten)) / len(preds_flatten) * 100
Com estes valores:
y_true = np.array([[1, 0, 3], [4, 5, 6]])
y_pred = np.array([[3, 2, 2], [7, 3, 6]])
as 2 funções dão os resultados:
>>> calculate_mape(y_pred, y_true)
91.38888888888889
>>> calculate_mape_torch(y_pred, y_true)
tensor(28490084.)
Com estes valores:
y_true = np.array([[1, 2, 3], [4, 5, 6]])
y_pred = np.array([[3, 2, 2], [7, 3, 6]])
as 2 funções dão os resultados:
>>> calculate_mape(y_pred, y_true)
58.05555555555556
>>> calculate_mape_torch(y_pred, y_true)
tensor(58.0556)
Eles não fazem um bom trabalho de documentação, mas o código deles usa um valor de eps de
1.17e-06
. Usar seucalculate_mape
com este eps dá o mesmo resultado. Isso é apenas um resultado do escalonamento de eps para alvos de valor zero.Se todas as suas saídas forem valores int, talvez você queira considerar usar uma métrica de classificação em vez de uma métrica de regressão.