【问题标题】:Custom RMSE not the same as taking the root of built-in Keras MSE for same prediction自定义 RMSE 与取内置 Keras MSE 的根进行相同的预测不同
【发布时间】:2020-01-27 14:35:16
【问题描述】:

我已经定义了一个自定义的 RMSE 函数:

def rmse(y_pred, y_true):
    return K.sqrt(K.mean(K.square(y_pred - y_true)))

我正在根据 Keras 提供的均方误差对其进行评估:

keras.losses.mean_squared_error(y_true, y_pred)

对于某些(相同的)预测,我分别获得的 MSE 和 RMSE 指标值是:

mse: 115.7218 - rmse: 8.0966

现在,当我取 MSE 的根时,我得到10.7574,这显然高于自定义 RMSE 函数输出的 RMSE。我无法弄清楚为什么会这样,也没有找到关于这个特定主题的任何相关帖子。 RMSE 函数中是否存在我根本没有看到的错误?还是与 Keras 如何在 MSE 函数中定义 axis=-1 有某种关系(我还没有完全理解其用途)?

这里是我调用 RMSE 和 MSE 的地方:

model.compile(loss="mae", optimizer="adam", metrics=["mse", rmse])

所以我希望 MSE 的根与 RMSE 相同。

我最初在 Cross Validated 上问过这个问题,但因为离题而被搁置。

【问题讨论】:

  • 您的结果mse: 115.7218 - rmse: 8.0966 来自哪里? model.evaluate 或 model.fit 还是什么?请提供尽可能多的信息
  • 它们是来自 model.fit 的验证结果,在一个 epoch 完成后。以下是 model.evaluate 的一些预测结果:mse 60.0054 - rmse 6.8625。 MSE 的根是7.7463
  • 问题,为什么要一样?
  • 你是怎么做这个比较的?也许发布该代码将有助于解决问题。
  • @mka 你能解决这个问题吗?

标签: python machine-learning keras


【解决方案1】:

RMSE 损失函数中是否存在我根本没有的错误 看到?或者它是否与 Keras 如何在 MSE 损失函数(我还没有完全理解的目的)?

Keras 进行损失计算时,批次维度被保留,这就是axis=-1 的原因。返回值是张量。这是因为每个样本的损失可能必须在取平均值之前加权,具体取决于某些参数是否在 fit() 方法中传递,例如 sample_weight

这两种方法我得到了相同的结果。

from tensorflow import keras
import numpy as np
from keras import backend as K

def rmse(y_pred, y_true):
    return K.sqrt(K.mean(K.square(y_pred - y_true)))

l1 = keras.layers.Input(shape=(32))
l2 = keras.layers.Dense(10)(l1)
model = keras.Model(inputs=l1, outputs=l2)

train_examples = np.random.randn(5,32)
train_labels=np.random.randn(5,10)

MSE 方法

model.compile(loss='mse', optimizer='adam')
model.evaluate(train_examples, train_labels)

RMSE 方法

model.compile(loss=rmse, optimizer='adam')
model.evaluate(train_examples, train_labels)

输出

5/5 [==============================] - 0s 8ms/sample - loss: 1.9011
5/5 [==============================] - 0s 2ms/sample - loss: 1.3788

sqrt(1.9011) = 1.3788

【讨论】:

    【解决方案2】:

    尽管 sqrt(mse) 等于 rmse 对于 Manoj 的回答所显示的简单模型配置,但对于复杂模型配置,我遇到了这个问题,无法弄清楚为什么会发生这种情况。但是,如果有人非常需要将 rmse 作为指标进行监控,但在问题中面临同样的问题,我已经找到了一种解决方法。我使用 callbacks 中的 LambdaCallback 在每个 epoch 之后打印训练和验证的 rmse 并且它有效:

    def rmse(y_true, y_pred):
        return K.sqrt(K.mean(K.square(y_true - y_pred)))
    
    rmse_print_callback = keras.callbacks.LambdaCallback(on_epoch_end=lambda epoch,logs: 
                     print(f"rmse: {rmse(training_labels, model.predict(training_data)):.4f} - val_rmse: {rmse(validation_labels, model.predict(validation_data)):.4f}"))
    
    model.fit(training_data, training_labels, epochs= 100, callbacks=[rmse_print_callback])
    

    【讨论】:

      猜你喜欢
      • 2019-09-04
      • 1970-01-01
      • 2018-11-24
      • 2022-08-14
      • 1970-01-01
      • 2021-06-01
      • 2021-01-25
      • 2019-01-02
      • 2020-09-18
      相关资源
      最近更新 更多