【问题标题】:TypeError: object of type 'NoneType' has no len() when trying to fit a KerasCLassifierTypeError:“NoneType”类型的对象在尝试适合 KerasCLassifier 时没有 len()
【发布时间】:2021-09-13 16:42:05
【问题描述】:

我正在尝试为使用 keras 创建的神经网络创建部分依赖图。为了实现这一点,我必须创建一个 KerasClassifier 或 KerasRegressor。在使用此导入无法正常工作后:

from keras.wrappers.scikit_learn import KerasClassifier

我尝试使用 scikeras 但使用以下代码

import numpy as np
import lime
import lime.lime_tabular
import matplotlib.pyplot as plt

df=pd.read_csv("heart.csv")
df.columns=["age", "sex", "chest_pain_type", "resting_blood_pressure", "cholesterol", "fasting_blood_sugar",
            "resting_ecg", "max_heart_rate", "exercise_induced_angina", "st_depression", "st_slope",
            "number_major_vessels", "thalassemia", "heart_attack"]
X=df.drop("heart_attack", axis=1).to_numpy()
y=df["heart_attack"].to_numpy()

from sklearn.model_selection import train_test_split
import keras
from keras.layers import Dense, Dropout, BatchNormalization
from keras.models import Sequential
from keras.callbacks import EarlyStopping
from scikeras.wrappers import KerasClassifier

def split_data(X, y):
        return train_test_split(X, y, train_size=0.8, random_state=10)

#   KerasClassifier for PDP
###############################################################################

def create_model_classifier():
    model=Sequential()
    model.add(BatchNormalization())
    model.add(Dense(70, activation="relu", input_shape=(13,)))
    model.add(Dense(70, activation="relu"))
    model.add(Dropout(0.2))
    model.add(Dense(70, activation="relu"))
    model.add(Dense(70, activation="relu"))
    model.add(Dense(1,activation="sigmoid"))

    opt=keras.optimizers.Adam(learning_rate=0.0001)
    model.compile(optimizer=opt, loss="binary_crossentropy", metrics=["accuracy", keras.metrics.FalseNegatives(), keras.metrics.FalsePositives()])


    return model

X_train, X_test, y_train, y_test=split_data(X, y)
model_reg = KerasClassifier(model=create_model_classifier)
    
early_stopping=EarlyStopping(monitor="val_loss", patience=10, verbose=0, mode="auto")
history=model_reg.fit(
    X_train,
    y_train,
    epochs=500,
    batch_size=32,
    shuffle=True,
    validation_data=(X_test, y_test),
    callbacks=[early_stopping]
    )

我得到这个错误代码:

Traceback (most recent call last):

  File "C:\Users\Leonard\Desktop\X AI - Heart Attacks\main.py", line 95, in <module>
    history=model_reg.fit(

  File "C:\Users\Leonard\anaconda3\lib\site-packages\scikeras\wrappers.py", line 1416, in fit
    super().fit(X=X, y=y, sample_weight=sample_weight, **kwargs)

  File "C:\Users\Leonard\anaconda3\lib\site-packages\scikeras\wrappers.py", line 747, in fit
    self._fit(

  File "C:\Users\Leonard\anaconda3\lib\site-packages\scikeras\wrappers.py", line 866, in _fit
    self._check_model_compatibility(y)

  File "C:\Users\Leonard\anaconda3\lib\site-packages\scikeras\wrappers.py", line 536, in _check_model_compatibility
    if self.n_outputs_expected_ != len(self.model_.outputs):

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

还有一些警告,因为我的 fit 方法中的参数似乎不是问题。即使我的 fit 方法中只有 X_train 和 y_train,我也会收到此错误。

【问题讨论】:

    标签: python machine-learning keras scikit-learn neural-network


    【解决方案1】:

    scikeras.wrappers.KerasClassifierkeras.wrappers.scikit_learn.KerasClassifier 不同。它需要一个tf.keras.Model,它有不同的语法。

    以下只是一个例子

    import tensorflow as tf
    
    def create_model_classifier():
        inputs = tf.keras.Input(shape=(13,))
        x = tf.keras.layers.Dense(70, activation=tf.nn.relu)(inputs)
        outputs = tf.keras.layers.Dense(70, activation=tf.nn.relu)(x)
        model = tf.keras.Model(inputs=inputs, outputs=outputs)
        return model
    

    文档: https://scikeras.readthedocs.io/en/latest/generated/scikeras.wrappers.KerasClassifier.html

    【讨论】:

    • 你确定这会导致错误,因为来自 scikeras 文档的 link 中的模型的实现与我的几乎相同
    • 是的,我确定。在教程中,它使用tf.keras.Sequential 帮助您自动推断输入和输出。但是,keras.Sequential 似乎不适合您。也许,您可以改用tf.keras.Sequential
    • 我现在已经尝试过了。我导入了 tensorflow 并尝试使用 tf.keras.Sequentialtf.keras.models.Sequential 但得到了同样的错误,所以很遗憾似乎还有另一个问题。
    • 仅供参考 @Leonard 的链接指向正确的文档 (adriangb.com/scikeras),readthedocs.io 链接已损坏
    【解决方案2】:

    SciKeras 支持序列模型。

    问题似乎是批处理规范层与tf.keras.Model.outputs 属性混淆。我认为它应该遵循您的输入。

    这是一个可重现的最小示例:

    import numpy as np
    
    X = np.ones((100,1))
    y = np.zeros((100,))
    
    from keras.layers import Dense, BatchNormalization
    from keras.models import Sequential
    from scikeras.wrappers import KerasClassifier
    
    def create_model_classifier():
        model=Sequential()
        model.add(BatchNormalization())
        model.add(Dense(1, activation="relu", input_shape=(1,)))
        model.add(Dense(1,activation="sigmoid"))
        model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
        return model
    
    model_reg = KerasClassifier(model=create_model_classifier)
        
    model_reg.fit(X, y)
    

    在输入层之后注释掉或移动BatchNormalization 层,它应该可以工作(后者可能是您想要的)。

    另外,您应该使用import tensorflow.keras ... 而不是import keras ...

    【讨论】:

      猜你喜欢
      • 2022-11-17
      • 2018-06-11
      • 2021-03-03
      • 2015-07-30
      • 1970-01-01
      • 2018-08-14
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多