使用KerasRegressor执行cross_val_score报错,请求技术支持
KerasRegressor结合cross_val_score交叉验证报错解决
问题概述
使用keras.wrappers.scikit_learn.KerasRegressor配合sklearn.model_selection.cross_val_score做交叉验证时,出现两个问题:
- 收到
KerasRegressor已弃用的警告,提示改用Sci-Keras; - 10次交叉拟合全部失败,触发
FitFailedWarning,核心错误为ValueError: The first argument to Layer.call must always be passed.
错误原因
- KerasRegressor参数误用:KerasRegressor要求传入返回Keras模型的构建函数,而非已实例化并编译好的模型对象。直接传入已构建的模型时,KerasRegressor会尝试将其作为函数调用,导致Layer的call方法参数缺失,触发报错。
- 输入维度不匹配:代码中第二个模型设置了
input_dim=2,但实际训练数据X_train的特征维度是1,存在适配问题。 - API弃用:官方已废弃
keras.wrappers.scikit_learn.KerasRegressor,推荐使用Sci-Keras实现。
修复方案
方案1:修正原KerasRegressor的使用方式
将模型构建逻辑封装为函数,传给KerasRegressor,同时修正输入维度:
import pandas as pd import numpy as np import seaborn as sns from tensorflow import keras import matplotlib.pyplot as plt from keras.wrappers.scikit_learn import KerasRegressor from sklearn.model_selection import cross_val_score, train_test_split from sklearn.preprocessing import MinMaxScaler # 生成数据 np.random.seed(0) m = 100 X = np.linspace(0, 10, m).reshape(m,1) y = X + np.random.randn(m, 1) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) scaler = MinMaxScaler() X_train= scaler.fit_transform(X_train) X_test = scaler.transform(X_test) # 数据可视化 print('X维度:', X.shape) print('y维度:', y.shape) plt.scatter(X,y) plt.show() # 定义模型构建函数 def build_model(): model = keras.Sequential([ keras.layers.Dense(4, activation='relu', input_dim=1), # 修正input_dim为1 keras.layers.Dense(2, activation='relu'), keras.layers.Dense(1, activation='relu') ]) opt = keras.optimizers.Adam() model.compile(optimizer=opt, loss='mse') return model # 初始化KerasRegressor,传入构建函数 regressor = KerasRegressor(build_fn=build_model, batch_size=10, verbose=1, epochs=1000) # 执行交叉验证 val_score = cross_val_score(regressor, X_train, y_train, cv=10) print("交叉验证得分:", val_score)
方案2:改用Sci-Keras(推荐,解决弃用警告)
Sci-Keras是官方推荐的替代方案,更贴合sklearn生态:
- 安装Sci-Keras:
pip install scikeras - 修改代码中的导入和模型封装:
import pandas as pd import numpy as np import seaborn as sns from tensorflow import keras import matplotlib.pyplot as plt from scikeras.wrappers import KerasRegressor # 替换导入 from sklearn.model_selection import cross_val_score, train_test_split from sklearn.preprocessing import MinMaxScaler # 生成数据部分同上 np.random.seed(0) m = 100 X = np.linspace(0, 10, m).reshape(m,1) y = X + np.random.randn(m, 1) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) scaler = MinMaxScaler() X_train= scaler.fit_transform(X_train) X_test = scaler.transform(X_test) # 数据可视化 print('X维度:', X.shape) print('y维度:', y.shape) plt.scatter(X,y) plt.show() # 定义模型构建函数 def build_model(): model = keras.Sequential([ keras.layers.Dense(4, activation='relu', input_dim=1), keras.layers.Dense(2, activation='relu'), keras.layers.Dense(1, activation='relu') ]) opt = keras.optimizers.Adam() model.compile(optimizer=opt, loss='mse') return model # 初始化Sci-Keras的KerasRegressor regressor = KerasRegressor(model=build_model, batch_size=10, verbose=1, epochs=1000) # 执行交叉验证 val_score = cross_val_score(regressor, X_train, y_train, cv=10) print("交叉验证得分:", val_score)
关键注意点
- 确保模型输入维度与训练数据特征数一致;
- KerasRegressor(无论原版本还是Sci-Keras)要求传入模型构建逻辑,而非已实例化的模型;
- 优先使用Sci-Keras替代已废弃的原KerasRegressor API,避免后续版本兼容性问题。
内容的提问来源于stack exchange,提问作者fares rs
相关产品推荐
相关产品推荐

