Keras 中的 RMSE/RMSLE 损失函数

Posted

技术标签:

【中文标题】Keras 中的 RMSE/RMSLE 损失函数【英文标题】:RMSE/ RMSLE loss function in Keras 【发布时间】:2017-10-06 21:35:34 【问题描述】:

我尝试参加我的第一次 Kaggle 比赛,其中RMSLE 被指定为所需的损失函数。因为我没有找到如何实现这个loss function 我试图满足于RMSE。我知道这是过去 Keras 的一部分,有没有办法在最新版本中使用它,也许通过 backend 自定义功能?

这是我设计的神经网络:

from keras.models import Sequential
from keras.layers.core import Dense , Dropout
from keras import regularizers

model = Sequential()
model.add(Dense(units = 128, kernel_initializer = "uniform", activation = "relu", input_dim = 28,activity_regularizer = regularizers.l2(0.01)))
model.add(Dropout(rate = 0.2))
model.add(Dense(units = 128, kernel_initializer = "uniform", activation = "relu"))
model.add(Dropout(rate = 0.2))
model.add(Dense(units = 1, kernel_initializer = "uniform", activation = "relu"))
model.compile(optimizer = "rmsprop", loss = "root_mean_squared_error")#, metrics =["accuracy"])

model.fit(train_set, label_log, batch_size = 32, epochs = 50, validation_split = 0.15)

我尝试了在 GitHub 上找到的自定义 root_mean_squared_error 函数,但据我所知,语法不是必需的。我认为y_truey_pred 必须在传递给return 之前定义,但我不知道具体如何,我刚开始用python 编程,我的数学真的不是那么好......

from keras import backend as K

def root_mean_squared_error(y_true, y_pred):
        return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1)) 

我收到以下错误:

ValueError: ('Unknown loss function', ':root_mean_squared_error')

感谢您的想法,感谢您的每一个帮助!

【问题讨论】:

您定义的 root_mean_squared_error 似乎等同于 keras 中的 'mse'(均方误差)。仅供参考。 【参考方案1】:

当您使用自定义损失时,您需要将其不带引号,因为您传递的是函数对象,而不是字符串:

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

model.compile(optimizer = "rmsprop", loss = root_mean_squared_error, 
              metrics =["accuracy"])

【讨论】:

工作得很好,非常感谢您指出这个错误。我真的没有那样想,因为我对编程有点陌生。您根本不知道如何编辑此自定义函数以计算均方根对数误差,对吗? 它给了我未知的损失函数:root_mean_squared_error @Jitesh 请不要做这样的 cmets,用源代码提出你自己的问题。 @Jitesh 您可能在函数名称周围加上引号。您需要将函数对象传递给编译函数,而不是其名称。 此代码给出与 MAE 相同的值,而不是 RMSE(请参阅下面的答案)。【参考方案2】:

根据以下问题,接受的答案包含一个错误,导致 RMSE 实际上是 MAE:

https://github.com/keras-team/keras/issues/10706

正确的定义应该是

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

【讨论】:

非常感谢您的评论!我花了很多时间试图弄清楚为什么我的 RMSE 结果(使用上面的代码)与 MAE 相同。【参考方案3】:

如果你每晚使用最新的 tensorflow,虽然文档中没有 RMSE,但source code 中有一个tf.keras.metrics.RootMeanSquaredError()

示例用法:

model.compile(tf.compat.v1.train.GradientDescentOptimizer(learning_rate),
              loss=tf.keras.metrics.mean_squared_error,
              metrics=[tf.keras.metrics.RootMeanSquaredError(name='rmse')])

【讨论】:

当我尝试将其用作损失函数时出现错误:AttributeError: 'RootMeanSquaredError' object has no attribute '__name__',即使我使用了 name 参数。【参考方案4】:

我更喜欢重用 Keras 的部分工作

from keras.losses import mean_squared_error

def root_mean_squared_error(y_true, y_pred):
    return K.sqrt(mean_squared_error(y_true, y_pred))

model.compile(optimizer = "rmsprop", loss = root_mean_squared_error, 
          metrics =["accuracy"])

【讨论】:

需要注意的一点是,这个损失函数的流形可能会趋于无穷大(因为平方根),训练可能会失败。 我刚试了这个函数,得到这个无限损失^_^ 大声笑,是的,如果在训练中的某个时刻平方根返回无限,那么你的所有训练都会失败【参考方案5】:

您可以像其他答案中显示的 RMSE 一样执行 RMSLE,您还需要合并日志功能:

from tensorflow.keras import backend as K

def root_mean_squared_log_error(y_true, y_pred):
    return K.sqrt(K.mean(K.square(K.log(1+y_pred) - K.log(1+y_true))))

【讨论】:

注意 y_pred 和 y_true 需要是浮点值 -> K.sqrt(K.mean(K.square(K.log(float(y_pred+1)) - K.log(float(y_true+1)))))【参考方案6】:

就像以前一样,但使用 Keras 后端的 RMSLE 更简化(直接)版本:

import tensorflow as tf
import tensorflow.keras.backend as K

def root_mean_squared_log_error(y_true, y_pred):
    msle = tf.keras.losses.MeanSquaredLogarithmicError()
    return K.sqrt(msle(y_true, y_pred)) 

【讨论】:

您可能需要添加更多解释。

以上是关于Keras 中的 RMSE/RMSLE 损失函数的主要内容,如果未能解决你的问题,请参考以下文章

Keras 中的自定义损失函数(IoU 损失函数)和梯度误差?

Keras 中的损失函数和度量有啥区别? [复制]

输出keras中的损失/成本函数

Keras 中的 .fit() 方法触发损失函数多少次

Keras 中的损失函数和批量大小

Keras 中的像素加权损失函数 - TensorFlow 2.0