尽管一切正常,但 KerasClassifier 无法拟合模型

Posted

技术标签:

【中文标题】尽管一切正常,但 KerasClassifier 无法拟合模型【英文标题】:KerasClassifier fails to fit model, despite everything working fine otherwise 【发布时间】:2021-01-13 11:23:14 【问题描述】:

我正在尝试使用 KerasClassifier 包装器来完成我的工作流程 对 scikit 友好。但是,当我尝试将它与以下功能一起使用时,它 给出错误;使用原生 Keras 模型 fit() 训练模型有效。 (这是 Tensorflow 2.2.0,运行在 conda 环境中)

def model_arch(n_features: int):
    i = tf.keras.layers.Input(shape=(n_features,))

    hidden_dense = tf.keras.layers.Dense(64)(i)
    hidden_dense = tf.keras.layers.BatchNormalization()(hidden_dense)
    hidden_dense = tf.keras.layers.Activation(tf.nn.tanh)(hidden_dense)

    o = tf.keras.layers.Dense(1)(hidden_dense)
    o = tf.keras.layers.BatchNormalization()(o)
    o = tf.keras.layers.Activation("sigmoid")(o)

    classifier = tf.keras.models.Model(inputs=i, outputs=o)

    opt = tf.keras.optimizers.SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True)
    classifier.compile(
        loss="binary_crossentropy",
        optimizer=opt,
        metrics=["accuracy"],
    )
    
    return classifier

以下作品:

X = np.random.random((100,3))
y = np.random.random((100,)) # 'y' is a binary vector in reality

clf = model_arch(3)
clf.fit(X, y, epochs=10)

但是,当我尝试使用 KerasClassifier 包装器时,出现错误:

clf = KerasClassifier(model_arch(3), epochs=10)
clf.fit(X, y)

# ValueError: The first argument to `Layer.call` must always be passed.

我在网上看到的每个例子似乎都和我做的一样:定义一个 返回已编译的 keras 模型,然后将其传递给包装器的函数,以及 适合它或在管道中使用。我注意到的唯一区别是大多数(如果不是 all) 示例使用 Sequential API 而不是功能 API,但是 afaik 这应该不是问题吧?

Tensorflow 文档似乎没有给出任何关于哪种类型的示例 我们应该传递给包装器的函数,但是因为每个示例都使用一个类似的 对我来说,我认为这是正确的。

谁能解释一下?谢谢。

编辑(在 cmets 之后):

我像这样导入 KerasClassifier:

from tensorflow.keras.wrappers.scikit_learn import KerasClassifier

错误日志:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/adrian/miniconda3/envs/kaggle/lib/python3.8/site-packages/tensorflow/python/keras/wrappers/scikit_learn.py", line 223, in fit
    return super(KerasClassifier, self).fit(x, y, **kwargs)
  File "/home/adrian/miniconda3/envs/kaggle/lib/python3.8/site-packages/tensorflow/python/keras/wrappers/scikit_learn.py", line 154, in fit
    self.model = self.build_fn(
  File "/home/adrian/miniconda3/envs/kaggle/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 799, in __call__
    raise ValueError(
ValueError: The first argument to `Layer.call` must always be passed.

【问题讨论】:

【参考方案1】:

KerasClassifer 需要一个构建函数,而不是模型实例本身,它在调用时会返回一个 Keras 模型的编译实例。因此,要以最少的更改解决此问题,您必须将其包装在一个函数中:

clf = KerasClassifier(lambda: model_arch(3), epochs=10)

另外,更好的方法是将模型的参数作为关键字参数传递:

clf = KerasClassifier(model_arch, n_features=3, epochs=10)

【讨论】:

读完这句话,我真的拍了拍我的额头。 Ofc 我可以说是传递了一个评估函数,而不是函数本身。 @today,你能看看这里吗:***.com/questions/65305864/…?

以上是关于尽管一切正常,但 KerasClassifier 无法拟合模型的主要内容,如果未能解决你的问题,请参考以下文章

具有多输入 KerasClassifier 的 Sklearn cross_val_score

WebGL:尽管使用相同的代码,但一切都很模糊

尽管我使用了有效的令牌,但 Laravel Passport 得到未经身份验证的响应

尽管一切都是高分辨率和未压缩的,但 Unity 纹理仍然模糊

Laravel NotFoundHttpException 尽管路由存在

ResultSet 为空,尽管 sql 查询正常但事件