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

KerasRegressor报__call__属性缺失:ANN回归模型调参问题

KerasRegressor结合GridSearchCV调参报错的解决方法

问题背景

构建数值预测用的ANN回归模型,使用GridSearchCV做超参数调优时触发错误:AttributeError: 'KerasRegressor' object has no attribute '__call__'。代码定义了含三层隐藏层的ANN,通过KerasRegressor封装后传入GridSearchCV,调用fit方法时出错。

原代码示例

def create_model(optimizer = 'rmsprop', units = 16, learning_rate = 0.001):
    ann = Sequential() # Initialising ANN
    ann.add(tf.keras.layers.Dense(units = units, activation = "relu")) # Adding First Hidden Layer
    ann.add(tf.keras.layers.Dense(units = units, activation = "relu")) # Adding Second Hidden Layer
    ann.add(tf.keras.layers.Dense(units = units, activation = "relu")) # Adding Third Hidden Layer
    ann.add(tf.keras.layers.Dense(units = 1)) # Adding Output Layer   
    ann.compile(optimizer = optimizer, loss = 'mean_absolute_error') # Compiling ANN
    return ann

ann = KerasRegressor(model = create_model, 
                     verbose = 0, 
                     learning_rate = 0.001, 
                     units = 16
                     )
 
optimizers = ['rmsprop', 'adam', 'SGD']
epoch_values = [10, 25, 50, 100, 150, 200]
batches = [10, 20, 30, 40, 50, 100, 1000]
units = [16, 32, 64, 128, 256]
lr_values = [0.001, 0.01, 0.1, 0.2, 0.3]

hyperparameters = dict(optimizer = optimizers, 
                        epochs = epoch_values, 
                        batch_size = batches, 
                        units = units,
                        learning_rate = lr_values
                        )

grid = GridSearchCV(estimator = ann, cv = 5, param_grid = hyperparameters)

history = grid.fit(X_train, 
                   Y_train, 
                   batch_size = 32, 
                   validation_data = (X_test, Y_test), 
                   epochs = 100
                   ) # Fitting ANN

报错详情

...
92 elif (not isinstance(self.build_fn, types.FunctionType) and
93       not isinstance(self.build_fn, types.MethodType)):
94   legal_params_fns.append(self.build_fn.__call__)

AttributeError: 'KerasRegressor' object has no attribute '__call__'

数据集维度

  • X.shape -> (10, 2066)
  • Y.shape -> (10, 4)
  • X_train.shape -> (8, 2066)
  • X_test.shape -> (2, 2066)
  • Y_train.shape -> (8, 4)
  • Y_test.shape -> (2, 4)

报错原因与修复方案

核心错误原因

KerasRegressor的参数传递错误:原代码用了model=create_model,但scikit-learn封装Keras模型的正确参数名是build_fn=create_model,旧版Keras wrapper通过该参数指定模型构建函数,传错参数导致内部识别异常。

另外还有两个隐性问题:

  1. 模型输出层维度不匹配:Y数据是4维输出,但原代码输出层定义为Dense(units=1),后续训练会触发维度不匹配错误。
  2. GridSearchCV的fit方法重复传入batch_size和epochs,这些参数应该交给GridSearchCV通过param_grid遍历调优,重复传入会导致逻辑冲突。

修复后的完整代码

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import GridSearchCV
import tensorflow as tf

def create_model(optimizer='rmsprop', units=16, learning_rate=0.001):
    ann = Sequential()
    # 三层隐藏层
    ann.add(Dense(units=units, activation="relu"))
    ann.add(Dense(units=units, activation="relu"))
    ann.add(Dense(units=units, activation="relu"))
    # 输出层改为4维,匹配Y数据的维度
    ann.add(Dense(units=4))   
    # 实例化带学习率的优化器,避免字符串传参无法生效
    if optimizer == 'SGD':
        optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate)
    elif optimizer == 'adam':
        optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
    elif optimizer == 'rmsprop':
        optimizer = tf.keras.optimizers.RMSprop(learning_rate=learning_rate)
    
    ann.compile(optimizer=optimizer, loss='mean_absolute_error')
    return ann

# 正确初始化KerasRegressor:使用build_fn参数指定模型构建函数
ann = KerasRegressor(build_fn=create_model, verbose=0)

# 超参数网格(可根据需求调整规模)
optimizers = ['rmsprop', 'adam', 'SGD']
epoch_values = [10, 25, 50]
batches = [10, 20, 30]
units = [16, 32, 64]
lr_values = [0.001, 0.01]

hyperparameters = dict(
    optimizer=optimizers,
    epochs=epoch_values,
    batch_size=batches,
    units=units,
    learning_rate=lr_values
)

grid = GridSearchCV(estimator=ann, cv=5, param_grid=hyperparameters)

# GridSearchCV的fit无需传入batch_size和epochs,由param_grid控制调优
history = grid.fit(X_train, Y_train, validation_data=(X_test, Y_test))

关键修复点说明

  1. KerasRegressor参数修正:将model=create_model改为build_fn=create_model,符合scikit-learn封装Keras模型的参数规范。
  2. 输出层维度匹配:把输出层Dense(units=1)改为Dense(units=4),与Y数据的4维输出对应。
  3. 优化器与学习率兼容:实例化优化器并传入learning_rate参数,避免直接传字符串导致学习率参数无法生效。
  4. 清理fit冗余参数:移除fit中的batch_size和epochs,让GridSearchCV通过param_grid完成参数遍历。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:52:20