Keras - 自定义损失功能 - 倒角距离

Eag*_*gle 3 machine-learning neural-network deep-learning keras tensorflow

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

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)
Run Code Online (Sandbox Code Playgroud)

y_pred_f是我的U-net的结果.y_true_f是地面真实标签掩码上的欧氏距离变换的结果,x如下所示:

distTrans = ndimage.distance_transform_edt(1 - x)
Run Code Online (Sandbox Code Playgroud)

为了计算距离倒角,则相乘的预测图像(理想地,与1和0掩模)与地面实况距离变换,并简单地总结在所有像素.要做到这一点,我需要y_pred_mask_f通过阈值处理获得一个掩码y_pred_f,然后乘以y_true_f,并对所有像素求和.

y_pred_f在[0,1]中提供连续的值范围,我None type not supported在评估时得到误差y_true_mask_f.我知道损失函数必须是可微,且greater_equalcast都没有.但是,在克拉斯有没有办法规避这个?也许在Tensorflow中使用一些解决方法?

Mar*_*jko 7

嗯,这很棘手.您的错误背后的原因是您的损失与您的网络之间没有持续的依赖关系.为了计算损失与网络相关的梯度,如果输出大于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)
Run Code Online (Sandbox Code Playgroud)

作为sigmoid步进功能的连续版本.如果您的输出来自sigmoid- 您可以简单地使用y_pred_f而不是y_pred_mask_f.