真正的非零预测的损失惩罚更高

2023-11-22

我正在构建一个深度回归网络(CNN)来从图像(7,11)预测(1000,1)目标向量。目标通常由大约90% 为零并且只有10 %非零值。目标中(非)零值的分布因样本而异(即不存在全局类别不平衡)。

使用均方误差损失,这导致网络仅预测零,我对此并不感到惊讶。

我最好的猜测是编写一个自定义损失函数,它对非零值的错误的惩罚比对零值的预测的惩罚更多。

我尝试了这个损失函数,目的是实现我猜想的可以在上面工作的功能。它是一种均方误差损失,其中非零目标的预测受到的惩罚较小(w=0.1)。

def my_loss(y_true, y_pred):
    # weights true zero predictions less than true nonzero predictions
    w = 0.1
    y_pred_of_nonzeros = tf.where(tf.equal(y_true, 0), y_pred-y_pred, y_pred)
    return K.mean(K.square(y_true-y_pred_of_nonzeros)) + K.mean(K.square(y_true-y_pred))*w

网络能够学习而不会陷入只有零的预测。然而,这个解决方案似乎相当unclean。有没有更好的方法来处理此类问题?关于改进自定义损失函数有什么建议吗? 欢迎任何建议,先谢谢您!

最好的, 卢卡斯


不确定有什么比像你一样的自定义损失更好,但有一个更干净的方法:

def weightedLoss(w):

    def loss(true, pred):

        error = K.square(true - pred)
        error = K.switch(K.equal(true, 0), w * error , error)

        return error 

    return loss

您还可以return K.mean(error),但没有mean您仍然可以从其他 Keras 选项中受益,例如添加样本权重和其他内容。

编译时选择权重:

model.compile(loss = weightedLoss(0.1), ...)

如果数组中有全部数据,您可以执行以下操作:

w = K.mean(y_train)
w = w / (1 - w) #this line compesates the lack of the 90% weights for class 1

另一种可以避免使用自定义损失但需要更改数据和模型的解决方案是:

  • 改变你的y每个输出都转化为一个二类问题。形状=(batch, originalClasses, 2).

对于零值,使两个类中的第一个 = 1
对于 one 值,使两个类中的第二个 = 1

newY = np.stack([1-oldY, oldY], axis=-1)    

调整模型以输出这个新形状。

...
model.add(Dense(2*classes))
model.add(Reshape((classes,2)))
model.add(Activation('softmax'))

确保您使用的是softmax and a categorical_crossentropy作为损失。

然后使用参数class_weight={0: w, 1: 1} in fit.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

真正的非零预测的损失惩罚更高 的相关文章

随机推荐