海浪能数据集神经网络训练:MSE与Val-loss过高问题求助
海浪能数据集神经网络训练MSE过高问题解决
问题背景
我有一个大型海浪能数据集,正在用它开展神经网络训练实践,但模型的MSE(均方误差)和Val-loss(验证损失)数值极高,达到约12万亿。已尝试用相关矩阵筛选特征、两步拆分数据集、搭建含3个隐藏层的网络并加入正则化,但问题仍未解决。
核心问题诊断
MSE达到天文数字的主要原因是目标变量未做缩放处理,同时数据流程存在多处疏漏:
- 仅对特征做了重复缩放,完全忽略了目标变量
Total_Power的量级问题 - 缺失值处理代码被注释,NaN会导致模型训练异常
- 学习率过低导致收敛极慢,正则化过度限制了模型拟合能力
- 重复的特征缩放操作打乱了特征分布
针对性修复方案
1. 目标变量必须做缩放
目标变量数值量级大时,MSE会被直接放大。需对y做标准化/归一化,训练后再逆变换还原真实尺度。
2. 清理冗余的特征缩放
移除重复的scale调用,统一使用一种缩放器(如StandardScaler或MinMaxScaler)。
3. 处理缺失值
启用缺失值填充,推荐用均值/中位数替代0值填充,避免引入偏差。
4. 优化模型与训练参数
- 简化网络结构,先移除正则化观察拟合效果
- 提高学习率至
0.001,加快收敛速度 - 启用早停机制,避免无效训练并保留最优权重
修复后完整代码
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error from tensorflow import keras from tensorflow.keras import layers # 加载数据 perth_49 = pd.read_csv(r'WEC_Perth_49.csv') sydney_49 = pd.read_csv(r'WEC_sydney_49.csv') perth_100 = pd.read_csv(r'WEC_perth_100.csv') sydney_100 = pd.read_csv(r'WEC_sydney_100.csv') # 合并数据集 merged_data = pd.concat([perth_49, sydney_49, perth_100, sydney_100]) # 定义目标变量 target_variable = 'Total_Power' # 定义候选特征 features = [f'X{i}' for i in range(1, 101)] + [f'Y{i}' for i in range(1, 101)] + [f'Power{i}' for i in range(1, 101)] + ['qW'] # 计算相关矩阵 correlation_matrix = merged_data[features + [target_variable]].corr() # 按与目标变量的相关性降序排列 correlation_with_target = correlation_matrix[target_variable].sort_values(ascending=False) print("与目标变量的相关性:") print(correlation_with_target) # 选择相关性最高的前4个特征(排除目标变量本身) top_features = correlation_with_target.head(5).index.tolist()[1:5] # 筛选特征与目标变量 selected_data = merged_data[top_features + [target_variable]] # 处理缺失值:用均值填充 selected_data.fillna(selected_data.mean(), inplace=True) # 拆分特征与目标变量 X = selected_data[top_features].values y = selected_data[target_variable].values.reshape(-1, 1) # 拆分训练、验证、测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42) print("训练集大小:", len(X_train)) print("验证集大小:", len(X_val)) print("测试集大小:", len(X_test)) # 特征缩放:使用StandardScaler scaler_X = StandardScaler() X_train_scaled = scaler_X.fit_transform(X_train) X_val_scaled = scaler_X.transform(X_val) X_test_scaled = scaler_X.transform(X_test) # 目标变量缩放 scaler_y = StandardScaler() y_train_scaled = scaler_y.fit_transform(y_train) y_val_scaled = scaler_y.transform(y_val) y_test_scaled = scaler_y.transform(y_test) # 搭建简化版神经网络 model = keras.Sequential([ layers.Dense(64, activation='relu', input_shape=(len(top_features),)), layers.Dense(32, activation='relu'), layers.Dense(1) ]) # 编译模型:调整学习率 optimizer = keras.optimizers.Adam(learning_rate=0.001) model.compile(optimizer=optimizer, loss='mean_squared_error') # 启用早停 early_stopping = keras.callbacks.EarlyStopping(monitor='val_loss', patience=15, restore_best_weights=True) # 训练模型 history = model.fit(X_train_scaled, y_train_scaled, epochs=200, batch_size=64, validation_data=(X_val_scaled, y_val_scaled), callbacks=[early_stopping]) # 逆变换回原始尺度,计算真实MSE predictions_scaled = model.predict(X_test_scaled) predictions = scaler_y.inverse_transform(predictions_scaled) y_test_original = scaler_y.inverse_transform(y_test_scaled) # 计算测试集均方误差(原始尺度) mse = mean_squared_error(y_test_original, predictions) print("测试集均方误差(原始尺度):", mse) # 打印缩放后的测试损失 loss_scaled = model.evaluate(X_test_scaled, y_test_scaled) print("测试集损失(缩放后):", loss_scaled)
额外优化建议
- 检查
Total_Power的分布,若存在极端异常值,先做截断或对数变换再缩放 - 尝试保留更多高相关特征(如前10个),或用PCA进行特征降维
- 加入
BatchNormalization层,帮助模型稳定收敛 - 若需要正则化,可逐步降低L2正则系数(如
0.0001)并观察效果
内容的提问来源于stack exchange,提问作者Hadis Yousefi
相关产品推荐
相关产品推荐

