问题描述
搭建了一个非常简单的三层网络想做二分类预测,损失函数用的tf.keras.losses.BinaryCrossentropy(from_logits=True),结果从一开始loss就是nan
原因分析:
网上查了一下,可能的原因有以下几种
- 学习率设置过大导致训练过程中出现数值越界
排除:loss在一开始就是nan,尝试输入单样本,loss始终为nan - 输入数据异常,包含nan
排除:数据预处理阶段对所有nan值都做过默认值填充 - 输入数据差异过大,未归一化
排除:连续特征全部做过归一化,后续又乱七八糟添加了BN层LN层尝试,都没有效果 - 后续实在定位不出来,开始怀疑是不是数据集规模太小且正负样本比太低导致的,但这个推测没有任何依据,说服不了自己,大概率还是数据在某一个环节出现了异常值
解决方案:
因为结构特别简单,层数很少,loss=nan又大概率是数据异常导致的,于是就特别朴素地打印出每一层的数据结果,看看到底是在哪里出现了异常值
class customModel(Model):
def __init__(self, ...)
pass
def call(self, x):
...
x = self.u_fc1(x)
tf.print(x)
...
最终发现是embedding层就出现了异常值,embedding层主要对输入数据进行预处理:离散数据embedding和连续数据标准化,问题就出在部分连续数据全部为0,所以均值和方差都为0,标准化后就变nan了,后续剔除这部分数据后,loss恢复正常
总结
输入数据要确认好是否正常,不仅包括是否是nan,还要检查预处理过程
逐层排查不失为一种方法