两层TensorFlow模型训练正常,三层模型出现NaN损失值求助
问题描述
使用TensorFlow构建神经网络时,两层模型训练正常,但新增一层后损失值直接变为NaN。
正常运行的两层模型代码
import tensorflow as tf model = tf.keras.Sequential([ tf.keras.layers.Dense(10), tf.keras.layers.Dense(1) ]) model.compile(loss=tf.keras.losses.mae, optimizer=tf.keras.optimizers.SGD(), metrics=["mae"]) model.fit(X_train, y_train, epochs=100)
其中X_train形状为(1070,11),y_train形状为(1070,),训练输出正常:
Epoch 1/100 34/34 [==============================] - 1s 2ms/step - loss: 8602.7510 - mae: 8602.7510 Epoch 2/100 34/34 [==============================] - 0s 2ms/step - loss: 7890.7075 - mae: 7890.7075 ...
出现NaN的三层模型代码
仅新增一层Dense,其余代码不变:
model = tf.keras.Sequential([ tf.keras.layers.Dense(10), tf.keras.layers.Dense(10), tf.keras.layers.Dense(1) ])
训练输出全为NaN:
Epoch 1/100 34/34 [==============================] - 1s 3ms/step - loss: nan - mae: nan Epoch 2/100 34/34 [==============================] - 0s 2ms/step - loss: nan - mae: nan ...
尝试更换层大小无效,怀疑是形状或训练稳定性问题,寻求原因与解决方法。
解决思路与方案
核心原因:多层线性模型的数值不稳定性
你的三层模型所有Dense层默认使用线性激活函数,线性层叠加本质还是线性变换,会导致输出数值快速放大甚至溢出(变成inf),后续计算MAE时就会产生NaN。两层模型时数值还未达到溢出阈值,所以能正常训练。此外还有几个辅助因素可能加剧这个问题:
1. 添加非线性激活函数(最关键)
给中间的Dense层加上非线性激活,比如ReLU,打破线性叠加的数值放大效应:
model = tf.keras.Sequential([ tf.keras.layers.Dense(10, activation='relu'), tf.keras.layers.Dense(10, activation='relu'), tf.keras.layers.Dense(1) ])
2. 降低学习率
SGD默认学习率0.01对多层模型可能过高,参数更新幅度过大直接导致NaN,调小学习率:
optimizer=tf.keras.optimizers.SGD(learning_rate=0.001)
3. 标准化输入数据
如果输入特征的数值范围差异大(比如有的特征是几千,有的是0.1),多层模型会放大这种差异,导致训练不稳定。用标准化把特征缩放到均值为0、方差为1的范围:
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) # 训练时传入标准化后的特征 model.fit(X_train_scaled, y_train, epochs=100)
4. 更换权重初始化方式
默认的权重初始化可能在多层场景下产生过大的初始值,导致第一次前向传播就溢出。改用He初始化(适配ReLU激活):
model = tf.keras.Sequential([ tf.keras.layers.Dense(10, activation='relu', kernel_initializer='he_normal'), tf.keras.layers.Dense(10, activation='relu', kernel_initializer='he_normal'), tf.keras.layers.Dense(1) ])
内容的提问来源于stack exchange,提问作者user1479670
相关产品推荐
相关产品推荐

