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

使用KerasClassifier时出现TypeError: NoneType无len()方法的问题

问题:Keras逻辑回归模型训练报错TypeError: object of type 'NoneType' has no len()

我想用Keras构建逻辑回归模型,训练指定epoch后获取准确率和损失值,但代码抛出TypeError: object of type 'NoneType' has no len()错误,已确认X_train[cv_train]和y_train[cv_train]不是NoneType。

代码

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=1) 

def build_logistic_regression_model():
    model = Sequential()
    model.add(Dense(units=1,kernel_initializer='glorot_uniform', activation='sigmoid',kernel_regularizer=l2(0.)))
    
    # Performance visualization callback
    performance_viz_cbk = PerformanceVisualizationCallback(model=model,validation_data=X_val,dat_dir='c:\\performance_charts')
    
    model.compile(optimizer='sgd',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    
    return model

lrscores = []
train_lrscores = []
for cv_train, cv_val in kfold.split(X_train, y_train):
    lr_model_logit = KerasClassifier(build_fn=build_logistic_regression_model, batch_size = 10)    
    hist = lr_model_logit.fit(X_train[cv_train], y_train[cv_train], epochs=200).history_
    losses = hist["mean_absolute_error"]
    train_lrscores.append(hist * 100)
    lr_score = hist.score(X_val, y_val)
    lrscores.append(lr_score * 100)

报错回溯

/opt/conda/lib/python3.7/site-packages/scikeras/wrappers.py:302: UserWarning: ``build_fn`` will be renamed to ``model`` in a future release, at which point use of ``build_fn`` will raise an Error instead.
  "``build_fn`` will be renamed to ``model`` in a future release,"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_18384/2762271288.py in <module>
      3 for cv_train, cv_val in kfold.split(X_train, y_train):
      4     lr_model_logit = KerasClassifier(build_fn=build_logistic_regression_model, batch_size = 10)
----> 5     hist = lr_model_logit.fit(X_train[cv_train], y_train[cv_train], epochs=200).history_
      6     losses = hist["mean_absolute_error"]
      7     train_lrscores.append(hist * 100)

/opt/conda/lib/python3.7/site-packages/scikeras/wrappers.py in fit(self, X, y, sample_weight, **kwargs)
   1492             sample_weight = 1 if sample_weight is None else sample_weight
   1493             sample_weight *= compute_sample_weight(class_weight=self.class_weight, y=y)
-> 1494         super().fit(X=X, y=y, sample_weight=sample_weight, **kwargs)
   1495         return self
   1496 

/opt/conda/lib/python3.7/site-packages/scikeras/wrappers.py in fit(self, X, y, sample_weight, **kwargs)
    765             sample_weight=sample_weight,
    766             warm_start=self.warm_start,
--> 767             **kwargs,
    768         )
    769 

/opt/conda/lib/python3.7/site-packages/scikeras/wrappers.py in _fit(self, X, y, sample_weight, warm_start, epochs, initial_epoch, **kwargs)
    927         X = self.feature_encoder_.transform(X)
    928 
-> 929         self._check_model_compatibility(y)
    930 
    931         self._fit_keras_model(

/opt/conda/lib/python3.7/site-packages/scikeras/wrappers.py in _check_model_compatibility(self, y)
    549             # we recognize the attribute but do not force it to be
    550             # generated
-> 551             if self.n_outputs_expected_ != len(self.model_.outputs):
    552                 raise ValueError(
    553                     "Detected a Keras model input of size"

TypeError: object of type 'NoneType' has no len()

数据示例

X_train[cv_train]

array([[ 3.49907650e-01,  1.01934833e+00,  9.22962131e-01, ...,
         4.65851423e-01,  5.85124577e-01, -2.30825406e-01],
       [-1.66145691e-01, -1.70198795e-01,  7.40812556e-01, ...,
        -1.25252966e-01,  6.11333541e-04, -1.85578709e+00],
       [-3.34532309e-01,  1.47744989e+00, -7.94889360e-01, ...,
         1.10431254e+00,  5.00866647e-01,  5.75451553e-01],
       ...,
       [-1.21341832e+00,  8.56729999e-01,  1.87070578e-01, ...,
        -8.38769062e-01, -7.08780127e-02, -6.54645722e-01],
       [ 3.45711192e-01,  8.01029131e-01,  9.37260745e-01, ...,
         6.35312010e-01, -1.77277404e-01, -1.05178867e+00],
       [ 1.65016194e+00,  1.34960903e+00,  1.17654404e+00, ...,
         3.79284887e-01,  4.38081218e-01, -3.55481467e-01]])

y_train

array([1, 3, 2, 2, 3, 2, 3, 3, 1, 2, 1, 1, 3, 2, 1, 1, 2, 3, 2, 1, 1, 1,
       1, 0, 1, 2, 3, 1, 1, 0, 0, 1, 1, 3, 1, 1, 2, 0, 1, 1, 2, 1, 0, 3,
       3, 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 2, 3, 1, 1, 3, 2,
       3, 1, 1, 2, 1, 2, 1, 1, 0, 2, 2, 3, 3, 2, 1, 1, 3, 1, 3, 1, 1, 3,
       1, 2, 0, 1, 2, 0, 2, 2, 2, 3, 1, 1, 2, 1, 0, 2, 2, 1, 1, 0, 2, 3,
       3, 3, 3, 1, 1, 1, 1, 2, 3, 2, 1, 1, 1, 2, 2, 0, 3, 2, 1, 2, 3, 3,
       2, 0, 3, 0, 1, 1, 1, 1, 2, 3, 3, 3, 2, 0, 3, 2, 3, 1, 3, 1, 2, 1,
       2, 3, 2, 2, 3, 3, 1, 0, 3, 1, 3, 2, 2, 2, 2, 3, 3, 1, 3, 2, 3, 1,
       3, 1, 2, 2, 1, 2, 3, 3, 1, 1, 2, 0, 2, 1, 2, 1, 3, 3, 3, 1, 3, 1,
       1, 2, 3, 1, 1, 1, 2, 1, 2, 2, 1, 1, 2, 0, 2, 0, 3, 1, 2, 3, 1, 1,
       3, 1, 3, 0, 3, 1, 3, 1, 1, 1, 1, 0, 3, 3, 2, 2, 3, 3, 1, 3, 1, 2,
       1, 2, 2, 3, 2, 1, 2, 3, 3, 3, 3, 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 2,
       3, 2, 1, 2, 1, 2, 1, 2, 3, 3, 1, 2, 0, 1, 2, 2, 2, 1, 1, 3, 3, 1,
       3, 3, 2, 1, 3, 1, 3, 1, 1, 1, 3, 1, 3, 1, 2, 1, 0, 1, 2, 1, 2, 2,
       1, 1, 2, 1, 2, 2, 2, 1, 3, 1, 2, 3, 2, 2, 3, 1, 2, 0, 0, 3, 2, 2,
       2, 3, 2, 1, 1, 1, 1, 2, 2, 2, 1, 3, 1, 2, 1, 3, 2, 2, 1, 1, 1, 2,
       3, 3, 2, 3, 2, 3, 1, 2, 2, 1, 2, 1, 1, 3, 3, 3, 2, 1, 1, 3, 2, 3,
       3, 2, 1, 1, 1, 2, 3, 0, 1, 2, 1, 1, 2, 0, 2, 1, 0, 2, 0, 3, 2, 3,
       2, 1, 1, 2, 3, 0, 0, 2, 2, 2, 1, 1, 1, 3, 1, 0, 1, 2, 2])

问题分析与修正方案

核心问题

  1. 任务类型不匹配:y_train是0-3的多分类标签,但模型用了二元分类的配置(输出单元1个+binary_crossentropy),导致Scikeras无法正确初始化模型,出现model_为None的错误。
  2. 训练后逻辑错误:hist是训练历史字典,不是模型对象,不能调用score();且编译时未指定mean_absolute_error指标,无法从历史中提取该值。
  3. 参数即将废弃:build_fn参数将被Scikeras移除,应改用model参数。

修正后的代码

from sklearn.model_selection import train_test_split, KFold
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.regularizers import l2
from tensorflow.keras.utils import to_categorical
from scikeras.wrappers import KerasClassifier

# 数据划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=1) 

# 多分类标签转独热编码
y_train_onehot = to_categorical(y_train)
y_val_onehot = to_categorical(y_val)

def build_logistic_regression_model():
    model = Sequential()
    # 多分类输出单元数等于类别数,激活用softmax
    model.add(Dense(units=4, kernel_initializer='glorot_uniform', activation='softmax', kernel_regularizer=l2(0.)))
    
    model.compile(optimizer='sgd',
                  loss='categorical_crossentropy',  # 多分类用交叉熵损失
                  metrics=['accuracy'])
    
    return model

lrscores = []
train_lrscores = []
kfold = KFold(n_splits=5, shuffle=True, random_state=1)

for cv_train_idx, cv_val_idx in kfold.split(X_train, y_train):
    # 准备当前折叠的训练/验证数据
    X_cv_train = X_train[cv_train_idx]
    y_cv_train_onehot = to_categorical(y_train[cv_train_idx])
    
    lr_model_logit = KerasClassifier(model=build_logistic_regression_model, batch_size=10)
    hist = lr_model_logit.fit(X_cv_train, y_cv_train_onehot, epochs=200, validation_data=(X_val, y_val_onehot)).history_
    
    # 记录训练集最后一轮准确率
    train_acc = hist['accuracy'][-1] * 100
    train_lrscores.append(train_acc)
    
    # 验证集评估
    val_loss, val_acc = lr_model_logit.score(X_val, y_val_onehot, return_dict=False)
    lrscores.append(val_acc * 100)

print(f"交叉验证训练准确率均值: {sum(train_lrscores)/len(train_lrscores):.2f}%")
print(f"交叉验证验证准确率均值: {sum(lrscores)/len(lrscores):.2f}%")

关键修正点

  • 适配多分类任务:输出单元改为4个,激活函数用softmax,损失函数换为categorical_crossentropy,标签转为独热编码。
  • 修正Scikeras参数:用model参数替代即将废弃的build_fn。
  • 修复训练后逻辑:从训练历史中提取最后一轮准确率,使用模型对象调用score()获取验证集结果。
  • 避免数据泄露:移除回调中硬编码的全局验证集,改为训练时传入独立验证数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:50:27