pytorch loss 出现nan,原因之一,计算图中存在torch.sqrt或者 **0.5,以及如何解决

本文探讨了在PyTorch中使用sqrt函数可能导致的梯度为inf问题,尤其是在loss函数计算中。通过两个解决方案避免了该问题:一是避免直接开方运算;二是向平方和中添加极小值防止分母为零。提供了测试代码示例。
部署运行你感兴趣的模型镜像

今天写一个loss函数

dist=torch.sqrt(x*x+y*y)
loss=soomthL1loss(dist,gt_dist)

我随便写的几句示意代码,这样会导致在第一个iteration之后出现nan,第一次iteration之内,还是可以看到loss不为nan的。

解决办法:

     1、不开方,因为开方的求导会出现在分母上,因此需要避免分母为0!

     2、torch.sqrt(x*x+0.000001)增加一个 很小的 “一瞥西漏”

给大家个测试代码:

import torch
a = torch.zeros(1,requireds_grad = True)
b = torch.sqrt(a)
b.backward()
print(a.grad)
#得到tensor([inf]),看到inf就知道,一般来说没办法传递了,为什么是一般来说,因为用过darknet的yolo的话,里面出现inf还是可以训练的(可能我记错了)


#修改下:
import torch
a = torch.zeros(1,requireds_grad = True)
b = torch.sqrt(a+0.001)
b.backward()
print(a.grad)
#tensor([15.814])

 

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

pytorch部分代码如下:train_loss, train_acc = train(model_ft, DEVICE, train_loader, optimizer, epoch,model_ema) for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device, non_blocking=True), Variable(target).to(device,non_blocking=True) # 3、将数据输入mixup_fn生成mixup数据 samples, targets = mixup_fn(data, target) # 4、将上一步生成的数据输入model,输出预测结果,再计算loss output = model(samples) # 5、梯度清零(将loss关于weight的导数变成0) optimizer.zero_grad() # 6、若使用混合精度 if use_amp: with torch.cuda.amp.autocast(): # 开启混合精度 loss = torch.nan_to_num(criterion_train(output, targets)) # 计算loss scaler.scale(loss).backward() # 梯度放大 torch.nn.utils.clip_grad_norm_(model.parameters(), CLIP_GRAD) if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks or global_forward_hooks or global_forward_pre_hooks): return forward_call(*input, **kwargs) class LDAMLoss(nn.Module): def init(self, cls_num_list, max_m=0.5, weight=None, s=30): super(LDAMLoss, self).init() m_list = 1.0 / np.sqrt(np.sqrt(cls_num_list)) m_list = m_list * (max_m / np.max(m_list)) m_list = torch.cuda.FloatTensor(m_list) self.m_list = m_list assert s > 0 self.s = s self.weight = weight def forward(self, x, target): index = torch.zeros_like(x, dtype=torch.uint8) target = torch.clamp(target, 0, index.size(1) - 1) index.scatter(1, target.data.view(-1, 1).type(torch.int64), 1) index_float = index.type(torch.cuda.FloatTensor) batch_m = torch.matmul(self.m_list[None, :], index_float.transpose(0,1)) batch_m = batch_m.view((-1, 1)) x_m = x - batch_m output = torch.where(index, x_m, x) return F.cross_entropy(self.s*output, target, weight=self.weight) 报错:RuntimeError: Expected index [112, 1] to be smaller than self [16, 7] apart from dimension 1 帮我看看如何修改源代码
06-10
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值