如何在无监督异常检测Autoencoder模型上实现GridSearchCV调参?
问题
构建无监督异常检测的Autoencoder模型,需对激活函数、优化器进行超参数调优,尝试用GridSearchCV时触发如下报错:
TypeError: Cannot clone object '<tensorflow.python.keras.engine.sequential.Sequential object at 0x7f486ca23410>' (type <class 'tensorflow.python.keras.engine.sequential.Sequential'>): it does not seem to be a scikit-learn estimator as it does not implement a 'get_params' method.
同时不确定当前使用的评估指标是否合适,已配置Early Stopping回调函数。
报错原因
Keras原生Sequential模型不属于scikit-learn兼容的estimator,没有实现get_params方法,无法直接传入GridSearchCV。此外,错误使用了KerasClassifier(适用于分类任务),而Autoencoder的重建任务属于回归性质,应使用KerasRegressor。
解决方案
1. 定义带超参数的模型构建函数
将需要调优的激活函数、优化器作为参数传入,在函数内完成模型的构建与编译:
import tensorflow as tf from tensorflow.keras.wrappers.scikit_learn import KerasRegressor from sklearn.model_selection import GridSearchCV from sklearn.metrics import make_scorer, mean_squared_error def build_autoencoder(input_dim, activation='elu', optimizer='adam'): autoencoder = tf.keras.models.Sequential([ # 编码层 tf.keras.layers.Dense(input_dim, activation=activation, input_shape=(input_dim, )), tf.keras.layers.Dense(2, activation=activation), # 解码层 tf.keras.layers.Dense(input_dim, activation=activation) ]) autoencoder.compile(optimizer=optimizer, loss="mse") return autoencoder
2. 配置GridSearchCV参数
- 用
KerasRegressor包装模型构建函数 - 定义要搜索的超参数网格(激活函数、优化器)
- 使用适合无监督重建的评估指标(如MSE)
- 整合已有的Early Stopping回调
# 初始化数据维度 input_dim = X_train_transformed.shape[1] # 包装模型 model = KerasRegressor(build_fn=build_autoencoder, input_dim=input_dim, epochs=100, batch_size=256, verbose=0) # 定义超参数网格 param_grid = { 'activation': ['elu', 'relu', 'tanh', 'sigmoid'], 'optimizer': ['SGD', 'RMSprop', 'Adagrad', 'Adadelta', 'Adam', 'Adamax', 'Nadam'] } # 自定义MSE评估器(适配scikit-learn格式) def mse_scorer(y_true, y_pred): return mean_squared_error(y_true, y_pred) scorer = make_scorer(mse_scorer, greater_is_better=False) # 越小越好,所以设为False # 定义Early Stopping early_stop = tf.keras.callbacks.EarlyStopping( monitor='val_loss', min_delta=0.0001, patience=10, verbose=1, mode='min', restore_best_weights=True ) # 初始化GridSearchCV grid = GridSearchCV( estimator=model, param_grid=param_grid, scoring=scorer, n_jobs=-1, cv=3, refit=True ) # 训练调参 result = grid.fit( X_train_transformed, X_train_transformed, callbacks=[early_stop], validation_split=0.1 # 划分验证集用于Early Stopping )
3. 查看调参结果
print(f"最佳参数组合: {result.best_params_}") print(f"最佳验证MSE: {-result.best_score_}") # 因为scorer设了greater_is_better=False,需要取反
评估指标修正建议
无监督异常检测场景下,原本使用的分类指标(accuracy、precision、recall)不适用,因为没有标签。核心评估指标应为:
- 重建损失(MSE):直接反映模型对正常样本的重建能力,损失越低说明模型对正常数据的拟合越好
- 若后续需基于重建损失区分异常样本,可在得到最佳模型后,通过统计正常样本的重建损失分布设定阈值,再结合少量验证标签计算F1-score等指标(属于半监督评估)
内容的提问来源于stack exchange,提问作者Art
相关产品推荐
相关产品推荐

