自定义交叉熵损失函数的几个问题

交叉熵损失函数本身的公式比较简单,

但是在实际定义的时候需要注意exp(x)函数的溢出问题,

exp(x)函数在numpy或者说tensorflow的底层实现上,当x过大的时候会产生溢出,过小的时候直接范围近似值0

所以我们在定义交叉熵损失函数的时候需要注意这一点;

1.当模型返回的值是sigmoid函数映射过后的值,这里假设输入交叉熵的为x,那么我们计算的就是

     

 -(y*np.log(x)+(1-y)*np.log(1-x))  

但是log(0)是没有意义的,如果当输入的x为0,就会出现输出的loss为nan,

这里需要把这个异常点给处理点,这篇文章列举了几个方法:https://blog.csdn.net/wo334499/article/details/52067353

 

2. 直接把sigmoid的计算也包含在交叉熵损失函数中的时候,这里假设模型的输入还是为x,只不过这个x没有经过sigmoid映射,那么交叉熵损失函数为;

-(y*np.log(sigmoid(x))+(1-y)*np.log(1-sigmoid(x)))

我们还是会遇到1中写的问题,但是这里我们可以先对这个公式进行优化

 -(y*log(sigmoid(x))+(1-y)*log(1-sigmoid(x))))
=y*-log(1/1+exp(-x))+(1-y)*-log(exp(-x)/(1+exp(-x)))
=y*log(1+exp(-x))+(1-y)*(-log(exp(-x))+log(1+exp(-x)))
=y*log(1+exp(-x))+(1-y)*x+(1-y)log(1+exp(-x)))
=log(1+exp(-x))+(1-y)*x

这样就简单很多了,但是我们最上面说了,exp(x)函数在x很大的时候会溢出,所以上面的公式中,因为输入exp()的-x,所以x很小的时候会溢出。因此针对x<0的时候单独再优化一下,按如下

  log(1+exp(-x))+(1-y)*x
=log(1+exp(-x))+log(exp(x))-y*x
=log(exp(x)+1)-y*x

这样的话就可以跳过因为输入exp()函数的值过大而溢出的问题,因此输入exp()的值很小的时候是会趋向于0的,输出的值直接约等于0。

所以把上面两个合并起来就可以得到最终的公式:

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

这个方法是在看tensorflow源码的时候看到的,感觉还可以。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值