【问题标题】:Custom loss function in NNNN 中的自定义损失函数
【发布时间】:2022-01-08 03:45:03
【问题描述】:

我正在尝试构建一个带有自定义损失函数的 simpleRNN 网络。我根据 25 个不同的特征预测 bmi。我的数据集不平衡并且有异常值,并且希望更好地预测异常值。相反,更好地预测异常值更为重要。 对于我的自定义损失函数,我添加了条件,如果损失大于 2 个单位,那么我想更多地惩罚这些观察结果。

import keras.backend as K

def custom_loss(y_true, y_pred):
    loss = K.abs(y_pred - y_true)
    wt = loss * 5

    loss_mae = K.switch((loss > 2),wt,loss)
    
    return loss_mae

model = Sequential()
model.add(SimpleRNN(units=64, input_shape=(25, 1), activation="relu"))
model.add(Dense(32, activation="linear")) 
model.add(Dropout(0.2))
model.add(Dense(1, activation="linear"))
model.compile(loss=custom_loss, optimizer='adam')
model.add(Dropout(0.1))
model.summary()
model.fit(train_x, train_y)

运行此代码后的示例预测

preds=[[16.015867], [16.022823], [15.986835], [16.69895 ], [17.537468]]
actual=[[18.68], [24.35], [18.07], [15.2 ], [13.78]]

如您所见,对 2nd 和 5th obs 的预测仍然遥遥无期。我在代码中做错了吗?

【问题讨论】:

    标签: neural-network loss-function


    【解决方案1】:

    非常错误的一点是,您应该永远在输出神经元上出现 dropout。除此之外:

    • 隐藏层的激活函数不应该是线性的(model.add(Dense(32, activation="linear"))应该是model.add(Dense(32, activation="relu"))
    • 神经网络应该始终能够过度拟合您的训练数据,这应该是您在担心泛化之前的调试状态,因此:
      • 不要使用 dropout(这只会使拟合变得更加困难,一旦您担心泛化问题就可以尝试一下)
      • 您的网络有点小,请尝试扩大网络,看看您的预测是否有所改善
      • 总体而言,MAE 是比 MSE 表现更差的学习信号,它也会自动惩罚很多异常值,为什么不使用它?
      • 考虑规范化您的数据,如果输入和目标都在一定范围内,最好在 [-1, 1] 或 [0, 1] 范围内,神经网络可以很好地使用其默认初始化。

    【讨论】:

    • 感谢@lejlot 的投入。在发布问题并修复它后,我确实意识到我的辍学错误。我还使用 minmaxscalar 进行标准化。我采纳了您的所有建议,但遗憾的是没有任何改进。我又增加了 6 层,只使用了 mae。您还有什么建议可以改进吗?
    • 我建议您不要添加层,而是将每个层做得更大。我也很困惑,为什么要使用RNN来完成这个任务,这里没有时间,没有可变长度维度,这看起来像是普通MLP的任务。
    • 这是我的项目要求,因此使用 RNN。您还认为日志转换在这里有帮助吗?我的数据有偏差,但我在其他网站/博客上读到,NN 标准化数据是首选。
    • 要求与否,从普通网络开始会回答问题是否与模型或数据/代码有关。
    猜你喜欢
    • 2019-02-13
    • 2020-02-28
    • 2020-12-19
    • 2017-04-04
    • 2017-12-18
    • 2020-03-27
    • 2020-11-16
    • 2019-05-27
    • 2020-02-02
    相关资源
    最近更新 更多