使用GridSearchCV调参Keras回归模型时遇Sequential无输出错误求助
KerasRegressor+GridSearchCV报错:Sequential模型未定义输出
问题背景
已完成特征工程与MinMaxScaler标准化,正在进行神经网络超参数调优,执行步骤如下:
- 特征工程/数据标准化(预处理)
- 编写神经网络构建函数
- 基于构建函数创建KerasRegressor对象
- 定义待测试的参数字典
- 以KerasRegressor为估计器、参数字典为param_grid创建GridSearchCV对象
- 用train_test_split划分的训练集拟合数据
- 打印最优参数
best_params_
运行时触发如下错误:
Traceback (most recent call last): File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\externals\loky\process_executor.py", line 428, in _process_worker r = call_item() ^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\externals\loky\process_executor.py", line 275, in __call__ return self.fn(*self.args, **self.kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\_parallel_backends.py", line 620, in __call__ return self.func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\parallel.py", line 288, in __call__ return [func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\parallel.py", line 288, in <listcomp> return [func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\utils\parallel.py", line 127, in __call__ return self.function(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\model_selection\_validation.py", line 732, in _fit_and_score estimator.fit(X_train, y_train, **fit_params) File "C:\Users\vishv\anaconda3\Lib\site-packages\scikeras\wrappers.py", line 760, in fit self._fit( File "C:\Users\vishv\anaconda3\Lib\site-packages\scikeras\wrappers.py", line 926, in _fit self._check_model_compatibility(y) File "C:\Users\vishv\anaconda3\Lib\site-packages\scikeras\wrappers.py", line 549, in _check_model_compatibility if self.n_outputs_expected_ != len(self.model_.outputs): ^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\keras\src\models\sequential.py", line 277, in outputs raise ValueError( ValueError: Sequential model 'sequential' has no defined outputs yet. """ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "c:\Users\vishv\OneDrive\Documents\Projects and Personal Learning\Spotify Top 200 Chart Analysis\prediction_test.py", line 100, in <module> grid = grid.fit(X_train,y_train) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\base.py", line 1151, in wrapper return fit_method(estimator, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\model_selection\_search.py", line 898, in fit self._run_search(evaluate_candidates) File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\model_selection\_search.py", line 1419, in _run_search evaluate_candidates(ParameterGrid(self.param_grid)) File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\model_selection\_search.py", line 845, in evaluate_candidates out = parallel( ^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\sklearn\utils\parallel.py", line 65, in __call__ return super().__call__(iterable_with_config) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\parallel.py", line 1098, in __call__ self.retrieve() File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\parallel.py", line 975, in retrieve self._output.extend(job.get(timeout=self.timeout)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\site-packages\joblib\_parallel_backends.py", line 567, in wrap_future_result return future.result(timeout=timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\concurrent\futures\_base.py", line 456, in result return self.__get_result() ^^^^^^^^^^^^^^^^^^^ File "C:\Users\vishv\anaconda3\Lib\concurrent\futures\_base.py", line 401, in __get_result raise self._exception ValueError: Sequential model 'sequential' has no defined outputs yet.
完整代码
# DataFrame Libraries import pandas as pd import numpy as np import random as rnd # Visualization Libraries import matplotlib.pyplot as plt from pandasgui import show import seaborn as sns # Machine Learning Libraries from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.metrics import r2_score from sklearn.preprocessing import MinMaxScaler import tensorflow as tf from tensorflow.keras.models import Sequential from scikeras.wrappers import KerasRegressor from tensorflow.keras.layers import Dense, Dropout from tensorflow.keras.metrics import R2Score from tensorflow.keras.callbacks import EarlyStopping # Read in Data spotify_df = pd.read_csv('spotify_top_songs_audio_features.csv',index_col="id") # Clean Data # Dropping source, mode, key, time_signature (no/little correlation to features) spotify_df.drop(['source','mode', 'key', 'time_signature'],axis=1,inplace=True) # Mapping outlier in artist_names (Tyler, The Creator -> Tyler The Creator) def tyler_map(artist_names): if 'Tyler, The Creator' in artist_names: return artist_names.replace('Tyler, The Creator','Tyler The Creator') else: return artist_names spotify_df['artist_names'] = spotify_df['artist_names'].apply(tyler_map) # Splitting artist names into lists of each artist + making dummies for each artist spotify_df['artist_names'] = spotify_df['artist_names'].apply(lambda x:x.split(", ")) artist_dummy = pd.get_dummies(data=spotify_df['artist_names'].explode(),drop_first=True).groupby(level=0).sum() # Concat dummies to original list (without artist_names) spotify_df = pd.concat([spotify_df.drop('artist_names',axis=1),artist_dummy],axis=1) X = spotify_df.iloc[:,13:] y = spotify_df['weeks_on_chart'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) scaler = MinMaxScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) early_stop = EarlyStopping(monitor='val_loss', mode='min', verbose=0, patience=25) def buildModel(optimizer='adam'): model = Sequential() model.add(Dense(234, activation = 'relu')) model.add(Dropout(0.1)) for i in range(2): model.add(Dense(78, activation = 'relu')) model.add(Dropout(0.1)) model.add(Dense(78, activation = 'relu')) model.add(Dropout(0.2)) for i in range(5): model.add(Dense(39, activation = 'relu')) model.add(Dropout(0.1)) model.add(Dense(39, activation = 'relu')) model.add(Dropout(0.2)) for i in range(3): model.add(Dense(13, activation = 'relu')) model.add(Dropout(0.1)) model.add(Dense(13, activation = 'relu')) model.add(Dropout(0.2)) model.add(Dense(1, activation = 'linear')) model.compile(optimizer=optimizer,loss='mean_absolute_error',metrics=['mean_absolute_error']) return model nn = KerasRegressor(model=buildModel,epochs=600,callbacks=[early_stop]) parameters = {'batch_size':[30,40,50,60,70], 'optimizer':['adam','rmsprop','adamw']} grid = GridSearchCV(estimator=nn,param_grid=parameters,scoring='neg_mean_absolute_error',cv=3) grid = grid.fit(X_train,y_train) print(grid.best_params_)
问题原因与修复方案
核心原因
Scikeras的KerasRegressor要求自定义模型的参数必须通过model__前缀传递,原代码中直接在param_grid里写optimizer,导致GridSearchCV无法将参数正确传递给buildModel函数,模型构建过程异常,最终触发"Sequential模型未定义输出"的报错。
修复步骤
修改参数字典:
将optimizer改为model__optimizer,让Scikeras能正确把参数传递给模型构建函数:parameters = { 'batch_size':[30,40,50,60,70], 'model__optimizer':['adam','rmsprop','adamw'] }添加输入形状定义(可选但推荐):
在模型的第一层显式指定输入形状,避免潜在的输入维度不匹配问题:def buildModel(optimizer='adam'): model = Sequential() # 显式指定输入特征数,X_train.shape[1]为训练集的特征数量 model.add(Dense(234, activation='relu', input_shape=(X_train.shape[1],))) model.add(Dropout(0.1)) # 后续层保持不变...简化模型结构(可选):
当前模型结构过于复杂(多层循环叠加),容易导致训练缓慢或过拟合,建议先尝试更简洁的结构(比如减少循环层数),验证调通后再逐步优化。
修改后运行代码,即可解决报错,正常进行超参数搜索。
内容的提问来源于stack exchange,提问作者vishv
相关产品推荐
相关产品推荐

