Tensorflow 参数训练过程中变成nan | parameter nan

最近写的网络,然后感觉是没问题的,但是训练过程中,有时候会所有参数都变成nan

第一次出现这个问题,我用的正态分布初始化,默认方差1,然后改成0.01好了 当时猜测是梯度爆炸了

第二次出现这个问题,是我迭代了很多轮之后忽然某一轮出现了这个问题,初始化方式uniform初始化,初始参数范围 [-1/hidden_dim, 1/hidden_dim] , lr 5/10w

解决方法再这里看到的:

https://stackoverflow.com/questions/33712178/tensorflow-nan-bug  

也就是,写网络的时候,对梯度要做clip,如果是交叉熵,因为有log的计算,在log之前也要保证log(x) x的值不能太小,也需要做clip

cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y_conv,1e-10,1.0)))

另外一个有意思的点,就是tensorflow,我load没有加clip的model 然后可以用加了clip的继续训练(我只在交叉熵的那边加了clip)。应该是因为Tf的load model只是把Variable按照load的model设定了。这点使得修复bug很方便。


### 解决机器学习模型训练时损失函数变为NaN的问题 #### 学习率设置不当 过高的学习率可能导致梯度爆炸,使得参数更新幅度过大,进而导致损失函数中的某些计算超出数值范围而变成NaN。建议逐步降低学习率来观察效果,在PyTorch环境中通常将初始设定的学习率减少1到10倍可能有效[^3]。 #### 数据预处理不足 数据集中存在异常值或极端值可能会引起模型内部运算溢出,特别是当输入特征尺度差异较大时更容易发生此类现象。对于大规模分类任务而言,如果类别数目非常多(例如达到数千级别),那么使用交叉熵作为损失函数时确实有可能因为极小的概率估计而导致`log(0)`的情况出现,这会直接引发NaN的结果[^2]。因此,确保数据已经经过标准化/归一化处理,并且检查是否有不合理的大数或负数混入其中是非常重要的预防措施之一[^1]。 #### 初始化策略欠佳 权重初始化方式的选择也会影响收敛过程的稳定性。不恰当的初始化方案容易造成网络层间激活值迅速增大或者缩小至接近于零的状态,最终累积下来形成NaN输出。针对这个问题,推荐采用Xavier/Glorot均匀分布或是He正态分布等方式来进行合理的权值赋初值操作。 #### 数值稳定性的优化技巧 为了提高数值计算的鲁棒性,可以在实现具体算法的过程中加入一些额外的设计考量: - **Softmax+LogSumExp**:在多类别的场景下应用softmax配合log-sum-exp trick能够有效地缓解由于指数项过大带来的不稳定因素; - **Clip Gradient**:通过裁剪梯度范数防止其变得太大,从而保护反向传播阶段不会被破坏掉正常的参数调整方向; ```python import torch.nn as nn from torch.optim import Adam model = YourModel() criterion = nn.CrossEntropyLoss() # 使用Cross Entropy Loss optimizer = Adam(model.parameters(), lr=0.001) for epoch in range(num_epochs): for inputs, labels in dataloader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) if not torch.isnan(loss).any(): loss.backward() # Clip gradients to prevent exploding gradient problem nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值