使用KerasClassifier时遭遇optimizer参数不合法错误求解决
解决KerasClassifier初始化时optimizer参数报错问题
运行代码时触发ValueError: optimizer is not a legal parameter,根本原因是**optimizer不是KerasClassifier的合法初始化参数**,同时代码里build_fn的使用方式也存在错误。
错误原因拆解
KerasClassifier的初始化参数集合中没有optimizer,该参数属于模型构建函数(即baseline_model)的专属参数,不能直接传递给KerasClassifier。- 原代码中
build_fn=baseline_model(x)是直接调用函数并传入数据集,这会导致KerasClassifier无法正确触发模型构建流程,应传递函数本身而非调用后的结果。 baseline_model的第一个参数X设计冗余,模型输入维度可通过独立参数传递,无需直接传入整个数据集。
修正后的完整代码
from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import KFold from sklearn.model_selection import GridSearchCV, cross_val_score from keras.models import Sequential from keras.layers import Dense from keras.wrappers.scikit_learn import KerasClassifier from keras.optimizers import Adam from sklearn.metrics import accuracy_score import pandas as pd import numpy as np # 补全原代码缺失的5折交叉验证定义 cv_5 = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) def baseline_model(input_dim, optimizer='adam', learn_rate=0.1): model = Sequential() model.add(Dense(100, input_dim=input_dim, activation='relu')) model.add(Dense(50, activation='relu')) model.add(Dense(2, activation='softmax')) # 支持自定义优化器学习率 if optimizer == 'adam': optimizer = Adam(learning_rate=learn_rate) model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy']) return model def get_probability_labels(x, y, optimizer='adam'): all_predictions = [] # 传递build_fn为函数名,模型参数通过KerasClassifier传入并自动传递给build_fn estimator = KerasClassifier(build_fn=baseline_model, input_dim=x.shape[1], optimizer=optimizer, batch_size=32, epochs=100, verbose=0) for train_index, test_index in cv_5.split(x, y): X_train, X_test = x.iloc[train_index], x.iloc[test_index] y_train, y_test = y.iloc[train_index], y.iloc[test_index] estimator.fit(X_train, y_train) predictions = estimator.predict_proba(X_test) predictions = list(predictions[:, 1]) all_predictions.append(predictions) # 循环外统一展平列表,提升效率 a = [j for i in all_predictions for j in i] return a def add_labels(real_data, synthetic_data): # 真实数据标记0,合成数据标记1 data = pd.concat([real_data, synthetic_data], ignore_index=True) o_labels = np.zeros((len(real_data)), dtype=int) s_labels = np.ones((len(synthetic_data)), dtype=int) labels = np.concatenate([o_labels, s_labels], axis=0) data['class'] = labels x = data.drop('class', axis=1) y = data['class'] return x, y def main(): # 假设df、df_synth为已定义的真实/合成数据集 X, Y = add_labels(df, df_synth) probability_labels = get_probability_labels(X, Y) print(probability_labels)
关键修正点
- 重构
baseline_model,将输入维度改为独立参数input_dim,通过x.shape[1]动态传入,避免直接传递数据集。 KerasClassifier初始化时,build_fn传递函数名baseline_model,而非调用后的模型对象。- 将
optimizer作为KerasClassifier的参数传入,它会自动传递给baseline_model作为函数参数。 - 补全原代码缺失的
cv_5交叉验证对象定义,避免循环报错。 - 将列表展平操作移到循环外,减少重复计算。
内容的提问来源于stack exchange,提问作者Carola
相关产品推荐
相关产品推荐

