首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于真实的非零预测更高的损失惩罚

对于真实的非零预测更高的损失惩罚
EN

Stack Overflow用户
提问于 2019-08-23 00:31:46
回答 1查看 2.1K关注 0票数 6

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

使用平均平方误差损失,这导致网络只预测零,我不觉得奇怪。

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

我已经尝试过这个损失函数,并打算实现我已经猜到的可以在上面工作的东西。这是一种均方误差损失,其中对非零目标的预测惩罚较少(w=0.1)。

代码语言:javascript
复制
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

该网络可以学习,而不被困在-零的预测。然而,这个解决方案似乎相当不干净的。是否有更好的方法来处理这类问题?对改进定制丢失功能有什么建议吗?欢迎您提出任何建议,谢谢!

最好的,卢卡斯

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-23 00:44:01

不确定还有什么比你做过的定制损失更好的东西,但是有一种更干净的方法:

代码语言:javascript
复制
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选项中获利,比如添加示例权重和其他东西。

在编译时选择权重:

代码语言:javascript
复制
model.compile(loss = weightedLoss(0.1), ...)

如果数组中有整个数据,则可以:

代码语言:javascript
复制
w = K.mean(y_train)
w = w / (1 - w) #this line compesates the lack of the 90% weights for class 1

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

  • 将您的y转换为每个输出的2类问题。Shape = (batch, originalClasses, 2).

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

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

代码语言:javascript
复制
newY = np.stack([1-oldY, oldY], axis=-1)    

调整模型以输出此新形状。

代码语言:javascript
复制
...
model.add(Dense(2*classes))
model.add(Reshape((classes,2)))
model.add(Activation('softmax'))

确保您正在使用softmaxcategorical_crossentropy作为损失。

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57618482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档