时序天气预测中Epoch损失、MAE及验证损失为NaN的问题求解
时序模型训练损失为NaN的解决方案
问题背景
将TensorFlow官方时序建模教程的模型迁移到自定义数据集后,训练时Epoch的loss、mean absolute error及validation loss均为NaN,原教程数据集损失值正常。自定义数据集规模约为原教程的一半,包含40余个地点、15分钟间隔的同期观测数据,batch size设为4654(原教程为1534),除基线模型外其余模型无法生成预测。
原训练函数定义:
MAX_EPOCHS = 20 def compile_and_fit(model, window, patience=2): early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=patience, mode='min') model.compile(loss=tf.keras.losses.MeanSquaredError(), optimizer=tf.keras.optimizers.Adam(), metrics=[tf.keras.metrics.MeanAbsoluteError()]) history = model.fit(window.train, epochs=MAX_EPOCHS, validation_data=window.val, callbacks=[early_stopping]) return history
尝试过的修改:
opt = tf.keras.optimizers.Adam(0.001, clipnorm=1.) model.compile(loss=["mse", "mse"], loss_weights=[0.9, 0.1], optimizer=opt)
解决方法
数据预处理排查
- 检查数据集是否存在NaN/无穷值:用
tf.math.is_nan()或numpy.isnan()遍历训练集、验证集的特征与标签,发现异常值后采用均值/中位数填充、时间序列插值或删除对应样本处理。 - 强制特征归一化/标准化:时序数据特征数值差异过大会引发梯度爆炸,对所有特征使用
StandardScaler做标准化,或MinMaxScaler做归一化,将特征值压缩到[-1,1]或[0,1]区间。 - 校验标签数值范围:若标签值过大,MSE损失会瞬间溢出变为NaN,确认标签的数值分布,必要时对标签做缩放处理。
- 检查数据集是否存在NaN/无穷值:用
训练配置调整
- 降低学习率:Adam默认0.001的学习率可能过高,尝试调整为
1e-4甚至更小,如tf.keras.optimizers.Adam(learning_rate=1e-4)。 - 缩小batch size:当前4654的batch size过大,易导致单次梯度计算数值不稳定,尝试调整为1024、512等合理值,平衡计算效率与数值稳定性。
- 优化梯度裁剪:除了
clipnorm=1.,可尝试clipvalue=0.5,或同时启用两种裁剪方式,避免梯度爆炸导致参数更新后出现NaN。 - 匹配损失函数与输出层:若为多输出模型,确保每个输出层的激活函数与损失函数适配,回归任务避免使用sigmoid这类限制输出范围的激活函数,防止与真实标签差距过大引发损失溢出。
- 降低学习率:Adam默认0.001的学习率可能过高,尝试调整为
模型结构校验
- 检查层输出维度:用
model.summary()确认各层输出形状是否符合预期,排查维度不匹配导致的损失计算错误;必要时在模型中添加中间层输出打印,定位数值异常的环节。 - 规避不稳定操作:对可能产生极大值的层用
tf.clip_by_value()限制输出范围;若使用自定义层,检查是否存在除以0、对0取对数等会生成NaN的操作。
- 检查层输出维度:用
内容的提问来源于stack exchange,提问作者Shweta Kiran
相关产品推荐
相关产品推荐

