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)))部分都是大于零的,因而如果这个函数出现负数的情况,一定是xz部分的问题,xz为正数的话,那么该式子才可能是负数,而对于xz为证书有两种情况
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。