TypeError:“NoneType”类型的对象在尝试适合 KerasCLassifier 时没有 len()
Posted
技术标签:
【中文标题】TypeError:“NoneType”类型的对象在尝试适合 KerasCLassifier 时没有 len()【英文标题】:TypeError: object of type 'NoneType' has no len() when trying to fit a KerasCLassifier 【发布时间】: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,我也会收到此错误。
【问题讨论】:
【参考方案1】:scikeras.wrappers.KerasClassifier
与 keras.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.Sequential
和 tf.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 ...
。
【讨论】:
以上是关于TypeError:“NoneType”类型的对象在尝试适合 KerasCLassifier 时没有 len()的主要内容,如果未能解决你的问题,请参考以下文章
Pandas 合并 TypeError:“NoneType”类型的对象没有 len()
Anvil 错误:TypeError:“NoneType”对象不可下标
TypeError: *: 'int' 和 'NoneType' 不支持的操作数类型
TypeError:调用键函数时“NoneType”对象不可迭代