使用Scikeras+GridSearchCV报错:'super'对象无__sklearn_tags__属性
问题概述
在PyCharm的Jupyter Notebook中使用GridSearchCV对基于Keras构建的CNN模型进行网格搜索调参时,触发错误:AttributeError: 'super' object has no attribute '__sklearn_tags__'。此前针对RandomizedSearch的同类问题解决方案无效,目标是通过调参找出Adam、SGD、RMSProp等优化器中的最优选项。
环境依赖
pyspark==3.5.1 findspark seaborn scipy pyarrow pandas scikit-learn==1.5.2 matplotlib s3fs mlxtend pypdf==5.4.0 reportlab graphviz pydotplus tensorflow==2.16.1 keras==3.9.2 scikeras
报错栈
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[123], line 36 25 param_grid = { 26 'optimizer': ['adam', 'sgd'], 27 'learning_rate': [0.001], (...) 32 'beta_1': [0.9] 33 } 35 grid = GridSearchCV(estimator=model, param_grid=param_grid, cv=2, n_jobs=1) ---> 36 grid_result = grid.fit(x_train_normalized, y_train) AttributeError: 'super' object has no attribute '__sklearn_tags__'
解决方案
1. 升级scikeras到兼容版本
scikit-learn 1.5.x对模型包装器的__sklearn_tags__属性有强制要求,旧版scikeras未适配,执行以下命令安装兼容版本:
pip install scikeras==0.12.0
2. 修改KerasClassifier初始化方式
新版本scikeras不再推荐使用build_fn参数,改用model参数直接传入模型构建函数,同时调整参数传递逻辑,避免GridSearchCV传递无效参数给模型。
3. 扩展优化器支持
在模型构建函数中加入RMSProp优化器的处理逻辑,满足调参需求。
修改后的完整代码
导入部分
import boto3 import pandas as pd import re import time from sklearn.model_selection import train_test_split import concurrent.futures import tensorflow as tf from sklearn.preprocessing import normalize from scikeras.wrappers import KerasClassifier import numpy as np from keras.api.models import Sequential from keras.api.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout from keras.api.optimizers import Adam, SGD, RMSProp from sklearn.model_selection import GridSearchCV
网格搜索实现
def create_model2(optimizer='adam', learning_rate=0.001, dropout_rate=0.5, momentum=0.0, beta_1=0.9, rho=0.9): # 根据选择的优化器初始化对应实例 if optimizer == 'adam': opt = Adam(learning_rate=learning_rate, beta_1=beta_1) elif optimizer == 'sgd': opt = SGD(learning_rate=learning_rate, momentum=momentum) elif optimizer == 'rmsprop': opt = RMSProp(learning_rate=learning_rate, rho=rho) else: raise ValueError("Unsupported optimizer: choose from adam, sgd, rmsprop") # 构建CNN模型 model = Sequential() model.add(Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1))) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(dropout_rate)) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy']) return model # 使用scikeras新版本的初始化方式,传入model参数 model = KerasClassifier(model=create_model2, verbose=0) # 扩展参数网格,加入RMSProp的rho参数 param_grid = { 'optimizer': ['adam', 'sgd', 'rmsprop'], 'learning_rate': [0.001], 'dropout_rate': [0.3], 'batch_size': [64], 'epochs': [5], 'momentum': [0.9], 'beta_1': [0.9], 'rho': [0.9] } # 初始化GridSearchCV并执行拟合 grid = GridSearchCV(estimator=model, param_grid=param_grid, cv=2, n_jobs=1) grid_result = grid.fit(x_train_normalized, y_train) # 输出最优结果 print("Best Grid Score: %.4f using %s" % (grid_result.best_score_, grid_result.best_params_))
内容的提问来源于stack exchange,提问作者Don Woodward
相关产品推荐
相关产品推荐

