神经网络回归模型R²逐轮下降问题排查求助
问题:神经网络回归循环中R²指标有序下降排查
我有5组不同数据集,需要用神经网络回归为每组数据计算评估指标。但发现每轮循环中R²指标呈有序下降趋势,确定代码存在问题但无法定位。已添加随机种子降低模型随机性,每轮循环后删除模型及指标变量避免叠加,但问题仍存在。
原代码
for sensor, sensorlol, name in zip(sensors, sensorslol, names): x_train, x_test, y_train, y_test = train_test_split(sensor, reference, test_size=0.2, random_state=42) x_trainl, x_testl, y_trainl, y_testl = train_test_split(sensorlol, referencelol, test_size=0.2, random_state=42) kf=KFold(7, shuffle=True, random_state=42) ann=MLPRegressor(hidden_layer_sizes=int(node), activation='relu', learning_rate='constant', learning_rate_init=initl, shuffle=False) ann.fit(x_train, y_train) m_predictionlol=cross_val_predict(ann, sensorlol, referencelol, cv=kf) R2lol=r2_score(referencelol, m_predictionlol) MAElol=mean_absolute_error(referencelol, m_predictionlol) RMSElol=mean_squared_error(referencelol, m_predictionlol) MBElol=np.mean(m_predictionlol-referencelol) r_2lol.append(R2lol) maelol.append(MAElol) rmselol.append(RMSElol) mbelol.append(MBElol) sumref=np.sum(referencelol) probref=referencelol/sumref sumtest=np.sum(m_predictionlol) probtest=m_predictionlol/sumtest KLlol=sum(rel_entr(probtest,probref)) kllol.append(KLlol) del m_predictionlol, sensorlol dataframe1=pd.DataFrame(list(zip(lst, r_2lol, maelol, rmselol, mbelol,kllol)), columns=['Sensor', 'R^2', 'MAE', 'RMSE', 'MBE','KL'])
运行结果
| Sensor | R^2 | MAE | RMSE | MBE | KL |
|---|---|---|---|---|---|
| I | 0.803568 | 1.776084 | 5.702426 | 0.097944 | 0.044695 |
| H | 0.739653 | 2.013070 | 7.557870 | 0.102656 | 0.053525 |
| L | 0.722556 | 2.074596 | 8.054198 | -0.143503 | 0.058237 |
| G | 0.696291 | 2.193398 | 8.816680 | 0.261528 | 0.062377 |
| J | 0.677972 | 2.251240 | 9.348475 | -0.000313 | 0.068745 |
问题定位与修正方案
1. 核心错误:模型提前训练导致参数继承
你在循环中先调用了ann.fit(x_train, y_train),之后再用同一个模型对象执行cross_val_predict。这会导致交叉验证时,模型不是从随机初始权重开始训练,而是基于之前训练好的权重继续迭代,后续数据集的模型训练会被前面数据集的训练结果污染,从而出现R²持续下降的趋势。
2. 模型初始化未控制随机性
MLPRegressor未设置random_state参数,即使KFold设置了随机种子,模型的初始权重仍会随机变化,无法保证每组数据集的模型初始化条件一致。
3. 可选优化:交叉验证逻辑对齐预期
当前代码中拆分了训练测试集,但后续交叉验证直接使用全量sensorlol和referencelol,若你的目标是评估模型在训练集上的泛化能力,应改用拆分后的训练集进行交叉验证。
修正后的代码
for sensor, sensorlol, name in zip(sensors, sensorslol, names): # 确认reference和referencelol与当前sensor匹配,避免全局变量错位 x_train, x_test, y_train, y_test = train_test_split(sensor, reference, test_size=0.2, random_state=42) x_trainl, x_testl, y_trainl, y_testl = train_test_split(sensorlol, referencelol, test_size=0.2, random_state=42) kf = KFold(n_splits=7, shuffle=True, random_state=42) # 为MLPRegressor添加random_state,确保每次初始化权重一致 ann = MLPRegressor(hidden_layer_sizes=int(node), activation='relu', learning_rate='constant', learning_rate_init=initl, shuffle=False, random_state=42) # 移除提前训练的fit调用,cross_val_predict会自动在每个fold完成训练和预测 m_predictionlol = cross_val_predict(ann, sensorlol, referencelol, cv=kf) # 指标计算逻辑保持不变 R2lol = r2_score(referencelol, m_predictionlol) MAElol = mean_absolute_error(referencelol, m_predictionlol) RMSElol = mean_squared_error(referencelol, m_predictionlol) MBElol = np.mean(m_predictionlol - referencelol) r_2lol.append(R2lol) maelol.append(MAElol) rmselol.append(RMSElol) mbelol.append(MBElol) sumref = np.sum(referencelol) probref = referencelol / sumref sumtest = np.sum(m_predictionlol) probtest = m_predictionlol / sumtest KLlol = sum(rel_entr(probtest, probref)) kllol.append(KLlol) dataframe1 = pd.DataFrame(list(zip(lst, r_2lol, maelol, rmselol, mbelol, kllol)), columns=['Sensor', 'R^2', 'MAE', 'RMSE', 'MBE','KL'])
额外检查点
- 确认
reference和referencelol是否为当前循环中sensor和sensorlol对应的目标变量,避免全局变量导致的数据集不匹配。 - 若
sensor和sensorlol是同一数据的不同版本,需明确交叉验证的目标数据集,确保评估逻辑符合实验设计。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

