pytorch训练网络时候出现loss nan的几种情况及解决方法

训练深度学习网络的过程中出现 loss nan总是让人觉得头疼,本人这次是在pytorch的半精度amp.autocast, amp.GradScaler训练时候出现了loss nan。

loss nan 常见的一般几种情况有:

lr学习率设置的过大,导致loss nan,调小lr;

训练数据中有脏数据,也会导致loss,这个需要自己排查,batch设置为1,遍历所有训练数据遇到nan就打印数据路径再退出;

if np.isnan(loss):
    sys.exit()

网络计算过程中可能存在nan,但这种可能比较少见。等等;

计算loss时候出现nan,特别是众多交叉熵损失中,核心原因应该是log(0)导致的。

笔者是在pytorch的半精度amp.autocast, amp.GradScale训练时候出现了loss nan,而且Lr设置合理,且没有脏数据,想到应该是半精度把一些很小的数表示为0了,计算loss时候把输出fp16—> fp32,问题解决。

out = out.float()

下面用交叉熵损失验证了一下fp16,fp64的结果


import numpy as np
import os 

out = np.array([0.00000001]).astype(np.float16)   
lab = np.array([0]).astype(np.float16)   
loss = lab * np.log(out) - (1-lab) * np.log(1-out)
print(loss)

# [nan]

out = np.array([0.00000001]).astype(np.float64)   
lab = np.array([0]).astype(np.float64)   
loss = lab * np.log(out) - (1-lab) * np.log(1-out)
print(loss)

#[1.00000001e-08]

后面的思考,因为已经用了amp.autocast, amp.GradScale为啥还会在训练到一半的时候出现这个问题呢

scaler = GradScaler()
with autocast():
    out = model(inputs)
    out = out.float()
    loss = criterion(out, labels)
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

应该是再回传中如果计算loss 时,出现了除以0的情况以及loss过大,被半精度判断为inf这种情况会被捕捉到,但是因为半精度的原因导致网络的输出变为nan,这时scaler.scale(loss).backward()没法捕获,因为回传的梯度并不是nan,这时候scaler.step(optimizer)也没法处理,因为已经是nan再加一个极小的eps仍然是nan,所以直接在loss计算前out = out.float()。

后续更新:

训练后又出现loss nan了,查了一下发现计算loss前,网络的输出层已经全部是nan了,输出层fp32也不好使了, 直接去掉混合精度训练一了百了,宁愿慢一点,也不愿loss nan。

MAPE(Mean Absolute Percentage Error)是一种衡量预测值与真实值之间误差指标,通常用于评估回归模型的性能。在PyTorch中计算MAPE可以使用以下代码实现: ```python def masked_mape(preds, labels, null_val=np.nan): if np.isnan(null_val): mask = ~torch.isnan(labels) else: mask = (labels!=null_val) mask = mask.float() mask /= torch.mean((mask)) mask = torch.where(torch.isnan(mask), torch.zeros_like(mask), mask) loss = torch.abs((preds-labels)/labels) loss = loss * mask loss = torch.where(torch.isnan(loss), torch.zeros_like(loss), loss) return torch.mean(loss) ``` 这个函数接受两个参数`preds`和`labels`分别表示预测值和真实值,并可选的参数`null_val`用于指定无效值的情况。函数首先根据是否存在无效值来生成掩码,然后将掩码归一化,并用掩码乘以误差计算得到一个带有掩码的误差张量,最后取平均值作为MAPE值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [几种MAPE的实现方式](https://blog.csdn.net/liangdaojun/article/details/105330007)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【偷偷卷死小伙伴Pytorch20天-day10-高阶API示范】](https://blog.csdn.net/qaqlalala/article/details/123090417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值