训练U-net时loss出现负值

原因:没有对作为标签的的图像矩阵做归一化,导致标签的图像矩阵其取值范围不在[0, 1]之间。

原因解释可见:tf.nn.sigmoid_cross_entropy_with_logits出现负数

原文链接:http://blog.sina.com.cn/s/blog_6ca0f5eb0102xjxd.html

tf.nn.sigmoid_cross_entropy_with_logits

使用这个loss函数,出现loss出现负数的情况,在理论情况下,这个函数应该是不会存在负数的情况,查看这个函数的具体表达为:

该函数定义为:

tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)

x = logits, z = labels

这个函数实际的内部实现的式子是下式:

max(x, 0) - x * z + log(1 + exp(-abs(x)))

其中max(x,0)和log(1+exp(-abs(x)))部分都是大于零的,因而如果这个函数出现负数的情况,一定是x*z部分的问题,x*z为正数的话,那么该式子才可能是负数,而对于x*z为证书有两种情况

1.x>0且z>0,上式可以化简为:

x*(1-z)+log(1+exp(-x)),这种情况下,1-z<0则可能发生此式子为负数,也就是z>1的情况;

2.x<0且z<0,上式可以化简为:

-x*z+log(1+exp(x))=log(exp(-xz))+log(1+exp(x))=x(1-2z),这种情况在z<0且x<0的情况下,此式子绝对为负数

综合上述例子中,x取任意值都可能,但是一般情况下z的取值范围为0<=z<=1,但是上述出现负数的情况,都是z不是在正常的取值范围内,导致了情况发生,因而可以发现,如果该函数输出值为负数,那么一定是z,也就是说labels出现了异常(超出了设计的取值范围[0,1]导致的)。

因而,解决问题的办法也很简单,就是检查labels输入的取值范围是否在[0,1]之间。而经过检查代码中出现这样的问题是,labels同样来自于模型输出,在模型训练过程中,最后一层并没有加sigmoid的处理,导致作为labels的输入时,输入数据越界而产生了负数的loss。

 

你可能感兴趣的:(Neural,Networks,深度学习,unet,图像分割,tensorflow)