针对tensorflow 出现nan的问题解决,transformer训练出现nan的问题总结

探讨在TensorFlow环境下,使用GPU和CPU进行模型训练时遇到的NAN问题及解决方案,涉及logits异常值处理和参数设置的重要性。

1通过自己的经历发现出现nan的一种情况是本身数据可能存在比较大的数据导致的

先说明一下我运用的是韩国大佬https://github.com/Kyubyong/transformer.git的代码,来做了一个闲聊的问答模

  情况说明:

          由于在之前一直在用tensortflow-gpu ,在之前服务器通过问答数据处理好之后,运行这个模型,没有报错,并且运行成功,效果好不错。

        更换公司后,服务器发生变化,但是环境仍然一致,都是python3.5的  tensorflow==1.12.0 ,环境是gpu,

     训练就莫名出现训练nan的问题。如图所示:

但是之前明明是好的,为什么换了一台机器就不行了,奇怪的不行,当然。具体原因具体对待,

 第一步:我把训练环境全部转变为和之前的服务器一模一样,(唯一不一样的就是,我知道之前那服务机器训练,虽然安装的是tensorflow-gpu==1.12.0,但是实际训练莫名其妙自己用的是cpu,后台就怎么搞都不行,其他代码仍然是gpu能够使用,后来就没有管),更换之后仍然是一样的nan问题。

第二步:根据网上和自己的经验,出现nan更多原因在于最终预测输出

logits = tf.einsum('ntd,dk->ntk', dec, weights)  # (N, T2, vocab_size)

logits中出现的异常值导致的。从而导致

ce = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=y_)

训练出现nan的原因,

     第一种改法就是把异常值用

tf.clip_by_value(logits,1e-8,1.0) 替代logits,这样就会把异常数值去掉,结果也确实解决了出现nan的问题,但是刚开是从损失10.56降低到9.6左右就不在降低。训练了一天的时间,通过预测,不管输出什么样的语句,返回结果都是同一个词语。这说明一个问题tf.clip_by_value(logits,1e-8,1.0)只能解决的是在模型正常情况的非常稀疏的异常值,说明预测大部分结果都在正常分布情况下才可以用。

第二步 :

logits = tf.einsum('ntd,dk->ntk', dec, weights) # (N, T2, vocab_size)在这个代码中增加替换为:

# logits = tf.nn.relu(tf.einsum('ntd,dk->ntk', dec, weights))  # (N, T2, vocab_size)relu函数能够把所有数值映射为整数,结果也同样解决了nan的问题,而且损失从10下降到6多,但是预测结果还是啥也不是,

第三部:通过以上方法说明,如果以上方法都解决不了问题,这说明,你的预测结果大部分都不是正常数值。要从根源上解决。但是代码并没有报错,实在是无法找到问题。也是偶然机会,既然唯一和上一次服务器不一样的就是一个是gpu跑的一个是cpu跑的,那么就把本机的tensorflow改成cpu,然后运行,结果让人狗血的事情出现,报错:如图所示:

骂娘的心都有了,擦,gpu和cpu不一样,虽然google很厉害,但还是要骂一句,能不能对包的返回结果负责,这难道不是bug,gpu找不到错误的原因,整整浪费了三天,本来模型就没有什么改动,结果从上图就可以知道是由于是实际的初始化词表是130000之多的词语,但是我的代码在初始化embedding时候的vocab_size设置为1500,导致找不到词向量。估计gpu版本的直接把没有在词汇表的做啥样的处理?

         反正擦浪费三天,仅此记住,很搞笑的说,以后出现问题,把tensorflow换换gpu和cpu换一下,哈哈啊,终于解决了还是。难受,大费周章

 

 

 

 

 

 

 

 

 

<think>好的,我现在要解决用户的问题,关于深度学习训练中损失函数出现NaN的原因及解决方案。首先,我需要回忆一下之前学过的相关知识,并结合用户提供的引用内容来整理答案。 用户提到了引用[1]和引用[2],其中引用[1]详细列举了NaN出现的多种原因,比如学习率过高、梯度爆炸、除零或对数问题等。引用[2]则给出了YOLO8训练中的具体解决方法,比如修改rect参数。我需要将这些信息整合起来,按照用户的要求,用清晰的结构回答,并生成相关问题。 首先,我要确定回答的结构。用户希望分点说明原因和解决方案,可能需要先列出主要原因,再给出对应的解决办法。此外,需要引用提供的材料中的例子,比如梯度爆炸的处理方法,学习率调整,输入数据检查等。 接下来,我需要确保每个原因和解决方案都对应正确。例如,学习率过高可能导致梯度更新过大,进而导致数值溢出,这时候降低学习率是一个解决办法。梯度爆炸可以通过梯度截断来解决,这在引用[1]中提到了。除零或对数问题需要检查输入数据是否有零或负数,特别是在使用交叉熵损失或类似函数时。 另外,输入数据的问题,比如归一化不正确或缺失值,也可能导致NaN。这时需要检查数据预处理步骤。网络结构设计错误,如层之间的不兼容,也可能引发问题,比如某些激活函数对输入范围有要求。 在解决方案部分,除了针对每个原因的具体措施,还可以建议逐步排查的方法,比如先检查学习率,再检查数据,然后看梯度等。这样用户可以根据步骤一步步解决问题。 生成相关问题的时候,需要围绕损失函数NaN的可能原因和解决办法展开,比如如何调试,梯度截断的作用,数据预处理的重要性等。这些问题应该帮助用户进一步理解问题的各个方面。 最后,要确保回答符合格式要求,使用中文,行内公式用$...$,独立公式用$$...$$,并且正确引用标记。需要检查是否有遗漏的要点,以及引用是否正确对应。</think>### 深度学习训练中损失函数出现NaN的原因及解决方案 #### 一、常见原因及解决方法 1. **学习率过高** 当学习率设置过高时,参数更新步长过大可能导致梯度爆炸或数值溢出,最终产生NaN。 **解决方案**: - 逐步降低学习率(通常减少1-10倍)直至训练稳定[^1] - 使用学习率预热(learning rate warmup)或自适应优化器(如Adam) 2. **梯度爆炸** 常见于RNN、Transformer等网络,梯度值指数级增长导致计算溢出。 **解决方案**: - 添加梯度截断(gradient clipping),限制梯度最大范数 例如在PyTorch中: ```python torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) ``` - 使用权重正则化(L2正则化) 3. **数值计算问题** - **除零错误**: 如softmax计算未做数值稳定处理 **解决方案**: 在softmax计算前减去输入最大值: $$ \text{softmax}(x_i) = \frac{e^{x_i - \max(x)}}{\sum_{j} e^{x_j - \max(x)}} $$ - **非法输入对数**: 如计算$\log(0)$或$\log(-x)$ **解决方案**: 添加微小值$\epsilon=1e-8$:$\log(x + \epsilon)$ 4. **输入数据异常** - 数据包含NaN/INF值或异常大/小值 - 数据未归一化(如像素值范围0-255未缩放到0-1) **解决方案**: - 检查数据预处理流程 - 添加数据标准化:$x_{\text{norm}} = \frac{x - \mu}{\sigma}$ 5. **网络结构缺陷** - 激活函数与层输出不匹配(如ReLU输出负数给对数运算) - 损失函数定义错误 **解决方案**: - 检查网络各层的输出范围 - 使用数值稳定的损失函数实现 #### 二、诊断流程 1. **逐步缩小问题范围** ```mermaid graph TD A[出现NaN] --> B{检查输入数据} B -->|正常| C{检查学习率} C -->|正常| D{检查梯度} D -->|正常| E[检查数值稳定性] ``` 2. **工具辅助诊断** - PyTorch的`torch.autograd.detect_anomaly()` - TensorFlow的`tf.debugging.enable_check_numerics()` #### 三、典型代码修复示例 YOLOv8训练时验证阶段报错修正[^2]: ```python # 修改ultralytics/models/yolo/detect/train.py class DetectionTrainer: def build_dataset(self, img_path, mode='train'): rect = mode == 'val' # 原代码 rect = False # 修改后 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值