如何使用 Keras 为稀疏数据集实现自定义损失函数

数据挖掘 喀拉斯 张量流
2022-02-19 03:27:18

我的数据集由一个空闲系统组成,该系统有时会接收请求。我试图通过时钟来预测这些瞬间。由于请求是稀疏分布的(我已经强迫它们持续一段时间,所以它们不会变得太稀疏),我想创建一个新的损失函数,如果它只对所有内容给出零预测,就会惩罚模型. 我的实施尝试只是对标准 logits 的惩罚:

def sparse_penalty_logits(y_true, y_pred):
    penalty = 10
    if y_true != 0:
        loss = -penalty*K.sum((y_true*K.log(y_pred) + (1 - y_true)*K.log(1 - y_pred)))
    else:
        loss = -K.sum((y_true*K.log(y_pred) + (1 - y_true)*K.log(1 - y_pred)))

    return loss

这是正确的吗?(我也试过了tensorflow)。每次我运行它时,我要么得到很多NaN' 作为损失,要么得到根本不是二进制的预测。我想知道我在设置模型时是否做错了,因为binary_crossentropy也不能正常工作。我的模型是这样的(目标由带有0's 或1's 的列表示):

model = Sequential()
model.add(Dense(100, activation = 'relu', input_shape = (train.shape[1],)))
model.add(Dense(100, activation = 'relu'))
model.add(Dense(100, activation = 'relu'))
model.add(Dense(1, activation = 'sigmoid'))

model.compile(optimizer = 'adam', loss = sparse_penalty_logits)

如果我运行它,正如我所说的,我会得到非常奇怪的结果(男孩,我觉得我搞砸了真的很糟糕......):

根本不是二进制的。 孩子,我是不是搞砸了……

1个回答

从您所面临的上述问题来看,这似乎是一个梯度爆炸的问题。梯度爆炸问题可以通过以下方式识别:

  • 该模型无法在您的训练数据上获得牵引力(例如损失不佳)。
  • 模型不稳定,导致从更新到更新损失变化较大。
  • 模型损失在训练期间变为NaN 。

更多关于爆炸梯度问题的信息可以在这篇文章中找到

我建议您在代码中使用一些梯度裁剪技术,这将在模型训练期间消除NaN生成。