You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

神经网络回归模型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'])

运行结果

SensorR^2MAERMSEMBEKL
I0.8035681.7760845.7024260.0979440.044695
H0.7396532.0130707.5578700.1026560.053525
L0.7225562.0745968.054198-0.1435030.058237
G0.6962912.1933988.8166800.2615280.062377
J0.6779722.2512409.348475-0.0003130.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:10:18