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

LSTM多对多模型交叉验证遇3D数组MSE报错,求解决方案

问题解决:LSTM多对多模型交叉验证中的3D数组适配及代码修正

核心问题有两个:一是sklearn的mean_squared_error不支持3D数组输入,二是你的交叉验证代码逻辑错误,未正确使用KFold划分的索引。

1. 3D数组导致MSE计算报错的解决

你的y_train1和y_test1形状为(N,1,9),而模型最后一层Dense(y_train1.shape[2])输出的是(N,9),两者维度不匹配,同时sklearn的metrics仅支持≤2D的输入。有两种解决方式:

  • 调整目标变量维度:直接去掉y中多余的中间维度,使其与模型输出一致:
    y_train1 = y_train1.reshape(-1, 9)
    y_test1 = y_test1.reshape(-1, 9)
    
  • 保留3D形状时转换计算:如果需要保留原维度,可临时将数组reshape为2D后计算MSE:
    score = np.sqrt(metrics.mean_squared_error(pred.reshape(-1,9), y_test.reshape(-1,9)))
    

2. 交叉验证逻辑的修正

你的代码未使用KFold生成的train/test索引,等于每个fold都在训练完整训练集、测试完整测试集,这不是真正的交叉验证。正确做法是在训练集内部划分验证fold,测试集留到最后做最终评估:

修正后的完整代码

from sklearn.model_selection import KFold
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from sklearn import metrics
import numpy as np
import pandas as pd

# 调整目标变量维度,适配模型输出和sklearn metrics
y_train1 = y_train1.reshape(-1, 9)
y_test1 = y_test1.reshape(-1, 9)

# 初始化KFold交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=42)
oos_y = []
oos_pred = []

fold = 0
for train_idx, val_idx in kf.split(X_train1):
    fold += 1
    print(f"Fold #{fold}")
        
    # 使用KFold索引划分训练/验证子集
    x_train, x_val = X_train1[train_idx], X_train1[val_idx]
    y_train, y_val = y_train1[train_idx], y_train1[val_idx]
    
    # 构建模型
    model = Sequential()
    model.add(LSTM(128, activation='relu', input_shape=(X_train1.shape[1], X_train1.shape[2]), return_sequences=True))
    model.add(LSTM(64, activation='relu', return_sequences=False))
    model.add(Dropout(0.2))
    model.add(Dense(y_train1.shape[1]))  # 现在y是(样本数,9),shape[1]对应特征数9
    model.compile(optimizer='adam', loss='mse', metrics=['mae'])
    model.summary()
    
    # 训练模型,用验证子集做验证
    history = model.fit(x_train, y_train, epochs=1, batch_size=16, validation_data=(x_val, y_val), verbose=1)
    
    # 验证集预测
    pred = model.predict(x_val)

    oos_y.append(y_val)
    oos_pred.append(pred)    

    # 计算当前fold的RMSE
    score = np.sqrt(metrics.mean_squared_error(pred, y_val))
    print(f"Fold score (RMSE): {score}")

# 计算交叉验证整体RMSE
oos_y = np.concatenate(oos_y)
oos_pred = np.concatenate(oos_pred)
cv_score = np.sqrt(metrics.mean_squared_error(oos_pred, oos_y))
print(f"Cross-Validation Average RMSE: {cv_score}")    

# 最终用测试集评估模型
test_pred = model.predict(X_test1)
test_score = np.sqrt(metrics.mean_squared_error(test_pred, y_test1))
print(f"Test Set RMSE: {test_score}")

# 保存结果(按需启用)
# oos_y_df = pd.DataFrame(oos_y)
# oos_pred_df = pd.DataFrame(oos_pred)
# oosDF = pd.concat([df, oos_y_df, oos_pred_df], axis=1)
# oosDF.to_csv(filename_write, index=False)

总结

不需要手动编写交叉验证函数,只需完成两步:

  • 调整目标变量维度,使其匹配模型输出并满足sklearn metrics的输入要求;
  • 正确使用KFold生成的索引划分训练/验证子集,实现真正的交叉验证。

内容的提问来源于stack exchange,提问作者Tan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:55:18