tensorflow - Keras - 自定义损失函数 - 倒角距离

标签 tensorflow machine-learning neural-network deep-learning keras

我正在尝试使用自定义损失函数进行对象分割,如下定义:

def chamfer_loss_value(y_true, y_pred):           

    # flatten the batch 
    y_true_f = K.batch_flatten(y_true)
    y_pred_f = K.batch_flatten(y_pred)

    # ==========
    # get chamfer distance sum

    // error here
    y_pred_mask_f = K.cast(K.greater_equal(y_pred_f,0.5), dtype='float32')

    finalChamferDistanceSum = K.sum(y_pred_mask_f * y_true_f, axis=1, keepdims=True)  

    return K.mean(finalChamferDistanceSum)

def chamfer_loss(y_true, y_pred):   
    return chamfer_loss_value(y_true, y_pred)

y_pred_f是我的U-net的结果。 y_true_f是地面实况标签掩码上欧几里得距离变换的结果 x如下图:

distTrans = ndimage.distance_transform_edt(1 - x)

要计算倒角距离,请将预测图像(理想情况下是具有 1 和 0 的掩模)与地面真实距离变换相乘,然后对所有像素进行简单求和。为此,我需要一个面具 y_pred_mask_f通过阈值化y_pred_f ,然后乘以 y_true_f ,并对所有像素求和。

y_pred_f在 [0,1] 中提供连续的值范围,我收到错误 None type not supportedy_true_mask_f的评价。我知道损失函数必须是可微的,并且 greater_equalcast不是。但是,Keras 中有没有办法规避这个问题呢?也许在 Tensorflow 中使用一些解决方法?

最佳答案

嗯,这很棘手。你的错误背后的原因是你的损失和你的网络之间没有持续的依赖。为了计算损失的梯度对于网络,如果您的输出大于 0.5,您的损失必须计算指标的梯度(因为这是您的最终损失值和来自网络的输出 y_pred 之间的唯一连接)。这是不可能的,因为该指标是部分恒定且不连续的。

可能的解决方案 - 平滑您的指标:

def chamfer_loss_value(y_true, y_pred):           

    # flatten the batch 
    y_true_f = K.batch_flatten(y_true)
    y_pred_f = K.batch_flatten(y_pred)

    y_pred_mask_f = K.sigmoid(y_pred_f - 0.5)

    finalChamferDistanceSum = K.sum(y_pred_mask_f * y_true_f, axis=1, keepdims=True)  

    return K.mean(finalChamferDistanceSum)

由于 sigmoid 是阶跃函数的连续版本。如果您的输出来自 sigmoid - 您只需使用 y_pred_f 而不是 y_pred_mask_f

关于tensorflow - Keras - 自定义损失函数 - 倒角距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48613573/

相关文章:

python - 预测全零

machine-learning - 乒乓球机器人神经网络的建议

matlab - 选择用于图像识别的神经网络变量

python - tensorflow如何忽略未定义的标志

tensorflow - 填充张量有什么影响?

python - 具有两个预训练 ResNet 50 的连体神经网络 - 测试模型时出现奇怪的行为

machine-learning - "Oracle"在机器学习中意味着什么?

python neurolab - 我们可以用许多输入部分进行增量训练吗?

neural-network - 神经网络 - 输入值

python - 将代码从 Tensorflow 1 迁移到 Tensorflow 2 时,如何处理属性错误 : 'Adam' object has no attribute 'compute_gradient' ?