Keras线性回归模型训练Loss为NaN问题排查求助
解决Keras线性回归模型训练时Loss持续为NaN的问题
我看你在用airfoil_self_noise.csv数据集构建Keras回归模型时,遇到了训练过程中Loss一直显示为NaN的问题。这种情况在回归任务里很常见,核心原因几乎都是数据未做尺度预处理,再结合SGD优化器的特性导致的。咱们一步步来解决:
问题根源分析
- 特征尺度差异过大:airfoil_self_noise数据集里的特征(比如频率、攻角、弦长等)数值范围可能相差几个数量级。SGD优化器对输入数据的尺度非常敏感,未归一化的话很容易引发梯度爆炸,进而让Loss变成NaN。
- 学习率设置过高:SGD默认的学习率是0.01,如果数据没做预处理,这个学习率可能太大,导致模型参数更新幅度过大,直接溢出成NaN。
- 虽然你用了ReLU激活函数,但它本身不是直接原因,不过数据尺度问题会放大ReLU的潜在问题(比如神经元饱和)。
具体解决方案
1. 必须做:数据标准化/归一化
这是解决这类问题最有效的步骤,用StandardScaler把特征缩放到均值为0、方差为1的范围:
from sklearn.preprocessing import StandardScaler # 初始化标准化器,仅在训练集上拟合(避免数据泄露) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) # 测试集直接用训练集的参数转换 X_test_scaled = scaler.transform(X_test)
2. 可选:降低SGD学习率
如果标准化后还是有问题,可以尝试降低学习率,让参数更新更平稳:
from keras.optimizers import SGD # 把学习率从默认的0.01降到0.001 sgd_optimizer = SGD(learning_rate=0.001) p.compile(loss='mean_squared_error', optimizer=sgd_optimizer)
3. 排查数据异常值
先确认数据里有没有NaN或无穷大值,避免脏数据影响训练:
# 检查缺失值 print(df.isnull().sum()) # 查看特征的统计分布,确认是否有极端异常值 print(df.describe())
如果发现异常值,可以选择删除对应样本或用中位数/均值填充。
4. 可选:简化模型调试
如果不确定是数据还是模型的问题,可以先试试最简单的线性模型,验证Loss是否正常:
p = Sequential() # 直接输出单个值,模拟线性回归 p.add(Dense(units=1, input_dim=5)) p.compile(loss='mean_squared_error', optimizer='sgd') p.fit(X_train_scaled, y_train, epochs=10, batch_size=32)
修改后的完整代码示例
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD path='/Users/admin/Desktop/airfoil_self_noise.csv' df=pd.read_csv(path,sep='\t',header=None) y=df[5] # 目标变量 df2=df.iloc[:,:-1] # 特征变量 # 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split(df2, y, test_size=0.2) # 数据标准化 scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # 构建模型 p = Sequential() p.add(Dense(units=20, activation='relu', input_dim=5)) p.add(Dense(units=20, activation='relu')) p.add(Dense(units=1)) # 配置优化器与损失函数 sgd_optimizer = SGD(learning_rate=0.001) p.compile(loss='mean_squared_error', optimizer=sgd_optimizer) # 训练模型 p.fit(X_train_scaled, y_train, epochs=10, batch_size=32)
按照上面的步骤处理后,你的模型Loss应该就能正常收敛,不会再出现NaN的情况了。
内容的提问来源于stack exchange,提问作者Rahul Deora
相关产品推荐
相关产品推荐

