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

使用GridSearchCV调优Keras模型报错:未实现get_params方法

问题:使用GridSearchCV调优Keras Sequential模型报错

我编写了以下Python代码,尝试用scikit-learn的GridSearchCV对Keras Sequential模型进行超参数调优:

import numpy as np
import tensorflow as tf
from sklearn.preprocessing import minmax_scale
from sklearn.model_selection import GridSearchCV, KFold

# Extract the main and side frequency factors concentractions and catalyst concentrations from the data
main_freq_factors = np.array(FreqFac['Main frequency factors concentraction (l/(mol*s))'])
side_freq_factors = np.array(FreqFac['Side frequency factors concentraction (1/s)'])
catalyst_conc = np.array(FreqFac.iloc[:,1].values)

# Scale the data using the min-max scaler
main_freq_factors_scaled = minmax_scale(main_freq_factors)
side_freq_factors_scaled = minmax_scale(side_freq_factors)
catalyst_conc_scaled = minmax_scale(catalyst_conc)

# Combine the scaled data into a single array
X = catalyst_conc_scaled
y = np.column_stack((main_freq_factors_scaled, side_freq_factors_scaled))


X_train, X_test, y_train, y_test = train_test_split(Xsc, Ysc, test_size=0.33, random_state=42)

# Define the model
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, activation='relu', input_shape=(1,)))
model.add(tf.keras.layers.Dense(1, activation='linear'))

# Compile the model with the mean squared error loss function and Adam optimization algorithm
model.compile(loss='mean_squared_error', optimizer='adam')

# Define the grid of hyperparameters to search
param_grid = {
    'epochs': [50, 100, 150],
    'batch_size': [32, 64, 128]
}

# Create a K-fold cross-validation generator
kfold = KFold(n_splits=5, shuffle=True, random_state=42)

# Create a grid search object using the model, param_grid, and kfold
grid_search = GridSearchCV(model, param_grid, cv=kfold, scoring='neg_mean_squared_error', return_train_score=True)

# Fit the grid search object to the data
grid_search.fit(catalyst_conc.reshape(-1, 1), main_freq_factors)

# Print the results of the grid search
print(grid_search.best_params_)

运行时出现如下错误:

Cannot clone object '<keras.engine.sequential.Sequential object at 0x7eff87f72580>' (type <class 'keras.engine.sequential.Sequential'>): it does not seem to be a scikit-learn estimator as it does not implement a 'get_params' methods.

请问我哪里操作出错了?


解决方法

错误核心原因:Keras的Sequential模型本身不是scikit-learn兼容的estimator,它没有实现scikit-learn要求的get_params()和set_params()方法,导致GridSearchCV无法对其进行克隆和参数调优。

解决步骤如下:

  1. 导入兼容包装器
    添加KerasRegressor导入(你的场景是回归任务,对应MSE损失):

    from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
    
  2. 将模型定义封装为函数
    GridSearchCV需要每次调参时重新构建模型,因此必须把模型定义写成可调用函数:

    def build_model():
        model = tf.keras.Sequential()
        model.add(tf.keras.layers.Dense(32, activation='relu', input_shape=(1,)))
        model.add(tf.keras.layers.Dense(1, activation='linear'))
        model.compile(loss='mean_squared_error', optimizer='adam')
        return model
    
  3. 用KerasRegressor包装模型
    将模型转换为scikit-learn兼容的estimator:

    model = KerasRegressor(build_fn=build_model, verbose=0)
    

    verbose=0用于屏蔽训练过程日志,方便聚焦GridSearch结果。

  4. 修正代码中的变量不一致问题
    原代码存在几处变量不匹配:

    • 定义了X = catalyst_conc_scaled,但后续用Xsc做数据集划分,需统一为X和y
    • fit时使用未缩放的catalyst_conc,建议改用已缩放的X保持数据一致性

修正后的完整代码

import numpy as np
import tensorflow as tf
from sklearn.preprocessing import minmax_scale
from sklearn.model_selection import GridSearchCV, KFold, train_test_split
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor

# 提取数据
main_freq_factors = np.array(FreqFac['Main frequency factors concentraction (l/(mol*s))'])
side_freq_factors = np.array(FreqFac['Side frequency factors concentraction (1/s)'])
catalyst_conc = np.array(FreqFac.iloc[:,1].values)

# 数据缩放
main_freq_factors_scaled = minmax_scale(main_freq_factors)
side_freq_factors_scaled = minmax_scale(side_freq_factors)
catalyst_conc_scaled = minmax_scale(catalyst_conc)

# 组合特征与标签(若需多输出预测,将y改为二维数组,模型输出层改为Dense(2))
X = catalyst_conc_scaled
y = main_freq_factors_scaled

# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

# 定义模型构建函数
def build_model():
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(32, activation='relu', input_shape=(1,)))
    model.add(tf.keras.layers.Dense(1, activation='linear'))
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model

# 包装模型为scikit-learn兼容estimator
model = KerasRegressor(build_fn=build_model, verbose=0)

# 超参数网格
param_grid = {
    'epochs': [50, 100, 150],
    'batch_size': [32, 64, 128]
}

# K折交叉验证生成器
kfold = KFold(n_splits=5, shuffle=True, random_state=42)

# 构建GridSearchCV
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=kfold, scoring='neg_mean_squared_error', return_train_score=True)

# 拟合数据
grid_search.fit(X.reshape(-1, 1), y)

# 输出最佳参数
print(grid_search.best_params_)

补充说明:如果你的任务是多输出回归(同时预测主、副频率因子),需要将模型输出层改为Dense(2),并将y设置为np.column_stack((main_freq_factors_scaled, side_freq_factors_scaled)),保证模型输出与标签维度匹配。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:45:40