自定义pytorch损失函数使得训练过程中出现nan

问题:

BCE的定义:-ylogp - (1-y)log(1-p),而如果我们用下面这种方式写出来:

loss = - target * torch.log(pred) - (1-target) * torch.log(1-pred)

可能会出现损失函数nan和inf的情况。

我自定义一个加权的BCE损失的时候就出现这个问题,于是查找pytorch官方的BCE文档,发现这样一句话:
Our solution is thatBCELoss clamps its log function outputs to be greater than or equal to -100. This way, we can always have a finite loss value and a linear backward method.

大意:就是进行了截断,来防止log()计算的时候可能出现问题,因为对于一个很小的数x而言(刚开始训练,可能predict的值相当大或小),虽然理论上log(x)是能计算的,但是计算机有精度限制,所以没法实现这么理想的情况。所以会出现nan和inf的情况,这样导致梯度无法回传。

解决方法:

加入一个截断:

pred = torch.clamp(pred, min=1e-7, max=1-1e-7)
loss = - target * torch.log(pred) - (1-target) * torch.log(1-pred)

如果截断范围是[1e-8, 1-1e-8],nan和inf还是会出现,所以就用1e-7了,而且与原生的BCELoss效果基本一致,差异在1e-3以下的量级。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值