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

使用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模型未定义输出"的报错。

修复步骤

  1. 修改参数字典:
    将optimizer改为model__optimizer,让Scikeras能正确把参数传递给模型构建函数:

    parameters = {
        'batch_size':[30,40,50,60,70],
        'model__optimizer':['adam','rmsprop','adamw']
    }
    
  2. 添加输入形状定义(可选但推荐):
    在模型的第一层显式指定输入形状,避免潜在的输入维度不匹配问题:

    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))
        # 后续层保持不变...
    
  3. 简化模型结构(可选):
    当前模型结构过于复杂(多层循环叠加),容易导致训练缓慢或过拟合,建议先尝试更简洁的结构(比如减少循环层数),验证调通后再逐步优化。

修改后运行代码,即可解决报错,正常进行超参数搜索。

内容的提问来源于stack exchange,提问作者vishv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 10:22:04