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

使用GridSearchCV与KerasClassifier时遭遇AttributeError: 'super' object has no attribute 'sklearn_tags'错误

GridSearchCV与KerasClassifier时遭遇AttributeError: 'super' object has no attribute 'sklearn_tags'错误

嘿,我之前也踩过这个坑!这个错误的根源是你用了scikeras旧版本的写法——build_fn参数在scikeras 0.10.x及以上版本已经被移除了,改用model参数来传递你的模型构建逻辑。旧写法会导致GridSearchCV无法找到它需要的sklearn_tags属性,从而抛出这个AttributeError。

下面是针对你的代码的具体修改方案,我会把关键改动标出来:

1. 调整KerasClassifier的初始化

把原来依赖build_fn的写法改成用model参数直接传递你的create_model函数,同时注意参数的传递逻辑:

# 原来的错误写法
# model = KerasClassifier(layers=1, neurons=32, build_fn=create_model, verbose=1)

# 新的正确写法
model = KerasClassifier(
    model=create_model,  # 直接传递模型构建函数
    neurons=32,          # 模型函数的参数可以在这里设默认值
    layers=1,
    fit__epochs=50,      # fit方法的参数要加`fit__`前缀
    verbose=1
)

2. 修改GridSearchCV的参数网格

因为epochs是模型训练(fit方法)的参数,不是模型结构的参数,所以在param_grid里要给它加上fit__前缀,让GridSearchCV知道要把这个参数传递给fit方法:

# 原来的参数网格
# param_grid = {
#     'neurons': [16, 32, 64, 128],
#     'layers': [1, 2],
#     'epochs': [50, 100]
# }

# 修改后的参数网格
param_grid = {
    'neurons': [16, 32, 64, 128],
    'layers': [1, 2],
    'fit__epochs': [50, 100]  # 加fit__前缀
}

3. 可选:加入EarlyStopping回调(推荐)

你已经导入了EarlyStopping但没用到,可以把它也加入到训练流程里,同样用fit__callbacks的方式传递:

# 定义EarlyStopping回调
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# 更新KerasClassifier初始化,加入回调和验证集
model = KerasClassifier(
    model=create_model,
    neurons=32,
    layers=1,
    fit__epochs=50,
    fit__callbacks=[early_stopping],
    fit__validation_split=0.1,  # 给EarlyStopping用的验证集
    verbose=1
)

修改后的完整代码(关键部分)

# ... 前面的数据预处理代码保持不变 ...

# Define the model creation function
def create_model(neurons=32, layers=1):
    model = Sequential()
    model.add(Dense(neurons, activation='relu', input_shape=(X_train.shape[1],)))

    for _ in range(layers - 1):
        model.add(Dense(neurons, activation='relu'))

    model.add(Dense(1, activation='sigmoid'))
    model.compile(optimizer='adam', loss="binary_crossentropy", metrics=['accuracy'])

    return model

# 加入EarlyStopping(可选但推荐)
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# Create a Keras classifier - 修正写法
model = KerasClassifier(
    model=create_model,
    neurons=32,
    layers=1,
    fit__epochs=50,
    fit__callbacks=[early_stopping],
    fit__validation_split=0.1,
    verbose=1
)

# GridSearch parameters - 修正epochs的写法
param_grid = {
    'neurons': [16, 32, 64, 128],
    'layers': [1, 2],
    'fit__epochs': [50, 100]
}

# Perform grid search
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3, verbose=1)
grid_result = grid.fit(X_train, y_train)  # 现在应该不会报错了

# Print the best parameters
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))

为什么这样改能解决问题?

scikeras在新版本中重构了和scikit-learn的兼容逻辑,build_fn被移除后,必须用model参数传递模型构建逻辑。同时,它用前缀区分模型结构参数(直接写参数名,会传递给你的create_model函数)和训练过程参数(加fit__前缀,会传递给model.fit方法),这样GridSearchCV能正确识别并传递所有参数,也就不会找不到sklearn_tags属性了。

备注:内容来源于stack exchange,提问作者Me at Work

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:24:31