图像分割的损失函数汇总(segmentation loss function review)
写在前面
图像分割是一个很基础的计算机视觉的问题,最近在我的研究方向中遇到的图像分割问题,就查阅了一些文献。由于我的项目主要用到的MRI图像,就自然而然的使用到了Unet1。使用的loss也是最原始的Dice系数。由于loss是需要一直减小的,而Dice系数则接近1越好。因此这里的一个trick就是将loss设置为_-Dice_。在实验的过程中,发现loss下降到-0.6之后就不再下降了。这是一个很差的结果,然后我将Validation set 的数据predict出segmentation Map,结果自然而然不好,大概能够给出要分割区域的位置,然而实际上边缘十分的粗糙,方方正正的(我想不明白这里面有什么玄学)。最终我决定从loss 函数入手去解决这个问题。因为我发现很多文章中提出对于分割来说,由于最终要得到的是segmentation Map,因此相当于就是对于每一个像素点的predictioin。这样的话一个重要的方面就是我们要分割的区域通常是占据小部分面积,这样就造成训练样例间的不均衡(这当然是有待考究的)。我想先从基本的Unet模型下手,通过尝试不同的loss function。看看实验结果会不会有什么改进。当然模型也是一个很重要的方面,我想接下来肯定要读论文进行一些总结的。
在CSDN上有许多很好的参考资源,而我参考就是其中一篇。从loss方面处理图像分割中数据极度不均衡的状况 --keras。2总结的很全面,我想我接下来的一些实验也会根据这篇Blog里面描述的一些内容并根据我的项目场景进行。3
Tversky_loss
"""
# Ref: salehi17, "Twersky loss function for image segmentation using 3D FCDN"
# -> the score is computed for each class separately and then summed
# alpha=beta=0.5 : dice coefficient
# alpha=beta=1 : tanimoto coefficient (also known as jaccard)
# alpha+beta=1 : produces set of F*-scores
# implemented by E. Moebel, 06/04/18
"""
def tversky_loss(y_true, y_pred):
alpha = 0.5
beta = 0.5
ones = K.ones(K.shape(y_true))
p0 = y_pred # proba that voxels are class i
p1 = ones-y_pred # proba that voxels are not class i
g0 = y_true
g1 = ones-y_true
num = K.sum(p0*g0, (0,1,2))
den = num + alpha*K.sum(p0*g1,(0,1,2)) + beta*K.sum(p1*g0,(0,1,