【问题标题】:How to add custom metric to keras? (Percent Mean Absolute Error)如何向 keras 添加自定义指标? (百分比平均绝对误差)
【发布时间】:2019-09-27 01:29:49
【问题描述】:

我正在尝试添加 平均绝对误差百分比 (pmae) 作为 keras 中的自定义指标。这被定义为(MAE 除以平均绝对 y 值乘以 100)。我试过了:

def pmae(y_true,y_pred):
    return K.mean(K.abs(y_pred - y_true)) / K.mean(K.abs(y_true)) * 100
...
model.compile(loss='mse', optimizer=Adam(),metrics=[pmae])

运行,但值相差许多数量级(当我查看 model.history.history.pmae 时)

工作的 numpy 版本(在测试样本上)是:

y_pred = model.predict(X_test)
pmae = abs(y_pred - y_test).mean() / abs(y_true).mean() * 100

我还尝试将 , axis=-1 添加到 K.mean() 调用中,但没有任何改进(如其他 stackoverflow 答案中所建议的那样)。有谁知道怎么回事?

资源

  1. keras website 以 y 的平均值为例:
import keras.backend as K

def mean_pred(y_true, y_pred):
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])
  1. 其他人在 stackoverflow 上回答了其他自定义指标(例如 Keras custom RMSLE metrichow to implement custom metric in keras?),但那里的回复并没有帮助我计算 pmae。

【问题讨论】:

  • 不能用faroit.com/keras-docs/1.1.1/metrics/…吗?我认为它们是一样的......
  • 该链接指的是 MAPE(平均绝对百分比误差),它是不同的 [mean(abs(percent(error)))]。我正在尝试计算 PMAE,或 [percent(mean(abs(error)))],它对来自个人观察的大百分比不太敏感。

标签: python tensorflow keras neural-network deep-learning


【解决方案1】:

让我们将您的实现与 Keras 中的 mean_absolute_percentage_error 进行比较:

def mean_absolute_percentage_error(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    diff = K.abs((y_true - y_pred) / K.clip(K.abs(y_true),
                                            K.epsilon(),
                                            None))
    return 100. * K.mean(diff, axis=-1)

基于此,以下内容应该适用于您的情况:

def percent_mean_absolute_error(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    diff = K.mean(K.abs((y_pred - y_true)) / K.mean(K.clip(K.abs(y_true),
                                                           K.epsilon(),
                                                           None)))
    return 100. * K.mean(diff)

您尝试的主要区别在于,这里y_truey_pred 都被强制转换为相同的数据类型,并且分母至少是K.epsilon()(即set to 1e-7 by default),所以错误不会出现如果y_true 接近0,则无穷大。

【讨论】:

  • 谢谢,这(几乎)有效。我只需要删除最后一行中的“axis = -1”,否则我会收到错误“ValueError: Invalid reduction dimension -1 for input with 0 dimensions. for 'metrics/pmae/Mean_2' (op: 'Mean' ) 输入形状:[]、[] 和计算输入张量:输入[1] = 。"您能解释一下为什么会这样吗?我尝试的解决方案有什么问题?
  • 很高兴我能帮上忙,我删除了错误的axis=-1。在不知道您输入的值的情况下,无法确定,但我认为关键区别在于分母在这里不能变为0。它始终至少为K.epsilon(),默认情况下设置为1e-7。如果y_true 接近0,这可以防止错误扩大到无穷大。
猜你喜欢
  • 2019-07-10
  • 1970-01-01
  • 2019-11-21
  • 2020-01-23
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 2020-05-28
  • 2019-01-02
相关资源
最近更新 更多