【问题标题】:Higher loss penalty for true non-zero predictions真正的非零预测的损失惩罚更高
【发布时间】:2019-12-28 07:37:46
【问题描述】:

我正在构建一个深度回归网络 (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

网络能够学习而不会陷入仅零预测的困境。然而,这个解决方案似乎很不干净。有没有更好的方法来处理这类问题?关于改进自定义损失函数的任何建议? 欢迎任何建议,提前谢谢!

最好, 卢卡斯

【问题讨论】:

  • 嗨 Lukas,感谢您提出这个问题!我正在处理类似的问题。我可以问一下您的目标值的范围以及您是否对目标向量单元格使用了任何类型的归一化?在我的问题中,向量单元具有不同的比例,因此我必须独立地对每个目标向量单元进行归一化,以获得更平衡的损失。你遇到过类似的问题吗?谢谢!
  • 您好,dogadikbayir!是的,我将目标向量归一化为 0 和 1 之间。我的输出向量是同质的,具有相同的比例,因此我没有同样的问题。个人标准化似乎很好,但是,您面临的问题是什么?最好的,卢卡斯
  • 感谢您的回复!由于我的目标向量单元格值可能相差几个数量级,因此损失函数只支持较大幅度值的贡献。通过独立标准化每个单元格,我提高了性能。我只是想知道您是否有类似的问题并有更好的解决方案:)

标签: tensorflow keras deep-learning loss-function loss


【解决方案1】:

不确定有什么比像您所做的那样自定义损失更好的方法,但有一种更清洁的方法:

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 转换为每个输出的 2 类问题。形状 = (batch, originalClasses, 2)。

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

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

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

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

确保您使用softmax 和categorical_crossentropy 作为损失。

然后在fit 中使用参数class_weight={0: w, 1: 1}。

【讨论】:

    猜你喜欢
    • 2021-12-16
    • 1970-01-01
    • 2021-12-18
    • 2020-07-18
    • 2014-09-22
    • 2021-04-01
    • 2019-03-12
    • 2021-01-14
    • 2020-09-01
    相关资源
    最近更新 更多