loss函数的选择是个很大的命题,最近在做3D医学图像分割,我这里只是记录一下我用过的loss函数。
- Binary Cross Entropy Loss
交叉熵损失比较常用,代码实现:
from keras import backend as K
def binary_crossentropy(y_true, y_pred):
return K.mean(K.binary_crossentropy(y_pred, y_true), axis=-1)
- Dice Loss
Dice Loss好像是V-Net中提出来的,Dice系数是评价分割结果好坏常用的指标,主要是计算两个区间的Dice距离来度量区间的相似度,其范围在0到1之间。
keras 实现代码如下:
def dice_coef(y_true, y_pred, smooth=1):
intersection = K.sum(y_true * y_pred, axis=[1,2,3])
union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])
return K.mean( (2. * intersection + smooth) / (union + smooth), axis=0)
def dice_coef_loss(y_true, y_pred):
1 - dice_coef(y_true, y_pred, smooth=1)
- BCE + Dice Loss
就是交叉熵和Dice损失的结合,我使用的时候没有给两个损失加权重,可以尝试加权重,系数需要自己试试。
K.mean(binary_crossentropy(y_true,y_pred))+ dice_loss(y_true,y_pred)
- Focal Loss
Focal Loss 是Kaiming 提出来的
论文给出来:Focal Loss for Dense Object Detection https://arxiv.org/pdf/1708.02002.pdf
目前在图像分割上只是适应于二分类。
实现代码:https://github.com/mkocabas/focal-loss-keras
from keras import backend as K
'''
Compatible with tensorflow backend
'''
def focal_loss(gamma=2., alpha=.25):
def focal_loss_fixed(y_true, y_pred):
pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
return -K.sum(alpha * K.pow(1. - pt_1, gamma) * K.log(pt_1))-K.sum((1-alpha) * K.pow( pt_0, gamma) * K.log(1. - pt_0))
return focal_loss_fixed
不过使用focal loss 调参可能比较麻烦一些。
- Tversky Loss
Tversky loss function for image segmentation using 3D fully convolutional deep networks
https://arxiv.org/pdf/1706.05721.pdf
代码实现:
def tversky(y_true, y_pred):
y_true_pos = K.flatten(y_true)
y_pred_pos = K.flatten(y_pred)
true_pos = K.sum(y_true_pos * y_pred_pos)
false_neg = K.sum(y_true_pos * (1-y_pred_pos))
false_pos = K.sum((1-y_true_pos)*y_pred_pos)
alpha = 0.7
return (true_pos + smooth)/(true_pos + alpha*false_neg + (1-alpha)*false_pos + smooth)
def tversky_loss(y_true, y_pred):
return 1 - tversky(y_true,y_pred)
- Focal Tversky Loss
A NOVEL FOCAL TVERSKY LOSS FUNCTION WITH IMPROVED ATTENTION U-NET FOR LESION SEGMENTATION
https://arxiv.org/pdf/1810.07842.pdf
代码实现:
https://github.com/nabsabraham/focal-tversky-unet/blob/master/losses.py?1565513088365
def tversky(y_true, y_pred):
y_true_pos = K.flatten(y_true)
y_pred_pos = K.flatten(y_pred)
true_pos = K.sum(y_true_pos * y_pred_pos)
false_neg = K.sum(y_true_pos * (1-y_pred_pos))
false_pos = K.sum((1-y_true_pos)*y_pred_pos)
alpha = 0.7
return (true_pos + smooth)/(true_pos + alpha*false_neg + (1-alpha)*false_pos + smooth)
def tversky_loss(y_true, y_pred):
return 1 - tversky(y_true,y_pred)
def focal_tversky(y_true,y_pred):
pt_1 = tversky(y_true, y_pred)
gamma = 0.75
return K.pow((1-pt_1), gamma)
目前用过的就是这些,后续还会继续记录,并且把各个损失函数的优缺点加上。