You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorchMetrics MAPE值异常偏高问题排查与方案咨询

关于torchmetrics计算MAPE异常的问题及解决

在人脸识别课程作业中使用PyTorch计算MAPE值时,使用torchmetrics.MeanAbsolutePercentageError类得到的结果毫无意义,但自行编写带epsilon参数的MAPE计算函数结果正常。经排查推测问题源于真实值数组中存在0,但未在torchmetrics官方文档中找到相关说明。现需解答:

  1. torchmetrics中是否有方法规避该问题?
  2. MAPE公式中的epsilon是否未设置,若未设置该如何指定其值?
  3. torchmetrics计算结果异常的原因是什么?

计算函数代码

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

测试案例1

y_true = np.array([[1, 0, 3], [4, 5, 6]])
y_pred = np.array([[3, 2, 2], [7, 3, 6]])

结果:

>>> calculate_mape(y_pred, y_true)
91.38888888888889

>>> calculate_mape_torch(y_pred, y_true)
tensor(28490084.)

测试案例2

y_true = np.array([[1, 2, 3], [4, 5, 6]])
y_pred = np.array([[3, 2, 2], [7, 3, 6]])

结果:

>>> calculate_mape(y_pred, y_true)
58.05555555555556

>>> calculate_mape_torch(y_pred, y_true)
tensor(58.0556)

问题原因

当真实值(targets)中存在0时,torchmetrics.MeanAbsolutePercentageError的默认计算逻辑会直接执行abs(pred - target)/target,此时除以0会产生无穷大(inf)值,无穷大参与后续均值计算后,最终得到异常的超大数值(如测试案例1中的28490084.)。而自定义函数通过np.maximum(epsilon, targets_flatten)将分母最小限制为epsilon,避免了除以0的情况,因此结果正常。

解决方法

1. 使用torchmetrics内置参数规避问题

较新版本的torchmetrics为MeanAbsolutePercentageError类提供了ignore_zero参数,设置为True时会自动忽略真实值为0的样本,避免除以0的计算:

from torchmetrics import MeanAbsolutePercentageError

def calculate_mape_torch_fixed(preds, targets):
    if not isinstance(preds, torch.Tensor):
        preds = torch.tensor(preds)
    if not isinstance(targets, torch.Tensor):
        targets = torch.tensor(targets)
    
    # 忽略真实值为0的样本
    mape = MeanAbsolutePercentageError(ignore_zero=True)
    return mape(preds, targets) * 100

测试案例1使用该函数会得到合理结果(忽略0样本后计算)。

2. 自定义带epsilon的计算逻辑

如果需要保留所有样本(包括真实值为0的),可以手动实现带epsilon的MAPE计算,类似自定义函数的逻辑:

import torch

def calculate_mape_torch_with_epsilon(preds, targets, epsilon=1):
    if not isinstance(preds, torch.Tensor):
        preds = torch.tensor(preds)
    if not isinstance(targets, torch.Tensor):
        targets = torch.tensor(targets)
    
    abs_error = torch.abs(preds - targets)
    # 将分母限制为不小于epsilon,避免除以0
    relative_error = abs_error / torch.maximum(torch.tensor(epsilon, device=targets.device), targets)
    mape = torch.mean(relative_error) * 100
    return mape

该函数可以指定任意epsilon值,解决除以0的问题。

3. 版本注意事项

早期版本的torchmetrics可能没有ignore_zero参数,建议升级到最新稳定版;若无法升级,直接使用自定义带epsilon的计算逻辑即可。

内容的提问来源于stack exchange,提问作者cicciodevoto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:37:35