使用 Keras 的 scikit-learn API 时出现错误

  我最近在学习 Keras,使用 scikit-learn API 时遇到了一个错误。以下是一些可能有用的信息:

环境

python:3.5.2  keras:1.0.5  scikit-learn:0.17.1

代码

import pandas as pdfrom keras.layers import Input, Densefrom keras.models import Modelfrom keras.models import Sequentialfrom keras.wrappers.scikit_learn import KerasRegressorfrom sklearn.cross_validation import train_test_splitfrom sklearn.cross_validation import cross_val_scorefrom sqlalchemy import create_enginefrom sklearn.cross_validation import KFolddef read_db():    "从 MySQL 获取准备好的数据。"    con_str = "mysql+mysqldb://root:0000@localhost/nbse?charset=utf8"    engine = create_engine(con_str)    data = pd.read_sql_table('data_ml', engine)    return datadef nn_model():    "创建模型。"    model = Sequential()    model.add(Dense(output_dim=100, input_dim=105, activation='softplus'))    model.add(Dense(output_dim=1, input_dim=100, activation='softplus'))    model.compile(loss='mean_squared_error', optimizer='adam')    return modeldata = read_db()y = data.pop('PRICE').as_matrix()x = data.as_matrix()model = nn_model()model = KerasRegressor(build_fn=model, nb_epoch=2)model.fit(x,y)  #这里出错了!

错误

Traceback (most recent call last):  File "C:/Users/Administrator/PycharmProjects/forecast/gridsearch.py", line 43, in <module>    model.fit(x,y)  File "D:\Program Files\Python35\lib\site-packages\keras\wrappers\scikit_learn.py", line 135, in fit    **self.filter_sk_params(self.build_fn.__call__))TypeError: __call__() missing 1 required positional argument: 'x'Process finished with exit code 1

  模型在没有使用 KerasRegressor 封装时运行良好,但我希望在之后使用 scikit-learn 的 GridSearch,所以我来这里寻求帮助。我尝试过但仍然没有头绪。

可能有帮助的信息:

keras.warappers.scikit_learn.py  class BaseWrapper(object):      def __init__(self, build_fn=None, **sk_params):        self.build_fn = build_fn        self.sk_params = sk_params        self.check_params(sk_params)      def fit(self, X, y, **kwargs):        '''根据给定的训练数据构建并拟合新模型。    # 参数        X : array-like, shape `(n_samples, n_features)`            训练样本,其中 n_samples 为样本数,n_features 为特征数。        y : array-like, shape `(n_samples,)` or `(n_samples, n_outputs)`            X 的真实标签。        kwargs: 字典参数            合法的参数是 `Sequential.fit` 的参数。    # 返回        history : object            关于每个 epoch 的训练历史的详细信息。    '''    if self.build_fn is None:        self.model = self.__call__(**self.filter_sk_params(self.__call__))    elif not isinstance(self.build_fn, types.FunctionType):        self.model = self.build_fn(            **self.filter_sk_params(self.build_fn.__call__))    else:        self.model = self.build_fn(**self.filter_sk_params(self.build_fn))    loss_name = self.model.loss    if hasattr(loss_name, '__name__'):        loss_name = loss_name.__name__    if loss_name == 'categorical_crossentropy' and len(y.shape) != 2:        y = to_categorical(y)    fit_args = copy.deepcopy(self.filter_sk_params(Sequential.fit))    fit_args.update(kwargs)    history = self.model.fit(X, y, **fit_args)    return history

  错误发生在这行:

    self.model = self.build_fn(        **self.filter_sk_params(self.build_fn.__call__))

这里的 self.build_fn 是 keras.models.Sequential

models.py  class Sequential(Model):    def call(self, x, mask=None):        if not self.built:            self.build()        return self.model.call(x, mask)

那么,这个 x 是什么意思,如何修复这个错误?
谢谢!


回答:

xiao,我也遇到了同样的问题!希望这对你有帮助:

背景与问题

Keras 的文档指出,在实现 scikit-learn 的包装器时,有两个参数。第一个是构建函数,它是一个“可调用的函数或类实例”。具体来说,它指出:

build_fn 应该构建、编译并返回一个 Keras 模型,该模型随后将用于拟合/预测。可以传递给 build_fn 的三种值之一是:

  1. 一个函数
  2. 实现 call 方法的类的实例
  3. None。这意味着你实现了一个从 KerasClassifierKerasRegressor 继承的类。当前类的 call 方法将被视为默认的 build_fn。

在你的代码中,你创建了模型,然后在创建 KerasRegressor 包装器时将模型作为参数 build_fn 的值传递:

model = nn_model()model = KerasRegressor(build_fn=model, nb_epoch=2)

问题就出在这里。你没有将 nn_model 函数 作为 build_fn 传递,而是传递了一个实际的 Keras Sequential 模型的实例。因此,当调用 fit() 时,它找不到 call 方法,因为你返回的类中没有实现它。

提议的解决方案

我为了使事情正常工作,是将函数作为 build_fn 传递,而不是一个实际的模型:

data = read_db()y = data.pop('PRICE').as_matrix()x = data.as_matrix()# model = nn_model() # 不要这样做!# 将 build_fn 设置为 nn_model 函数model = KerasRegressor(build_fn=nn_model, nb_epoch=2) # 注意你不调用该函数!model.fit(x,y)  # 修复了!

这不是唯一的解决方案(你可以将 build_fn 设置为一个适当实现 call 方法的类),但这是对我有效的方法。希望它能帮到你!

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注