error when using keras' sk-learn API
<p>&emsp;&emsp;i'm learning keras these days, and i met an error when using scikit-learn API.Here are something maybe useful:  </p>

<p><strong>ENVIRONMENT</strong>:  </p>

<pre><code>python:3.5.2  
keras:1.0.5  
scikit-learn:0.17.1
</code></pre>

<p><strong>CODE</strong></p>

<pre><code>import pandas as pd
from keras.layers import Input, Dense
from keras.models import Model
from keras.models import Sequential
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.cross_validation import train_test_split
from sklearn.cross_validation import cross_val_score
from sqlalchemy import create_engine
from sklearn.cross_validation import KFold


def read_db():
    "get prepared data from 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 data

def nn_model():
    "create a 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 model

data = 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)  #something wrong here!
</code></pre>

<p><strong>ERROR</strong></p>

<pre><code>Traceback (most recent call last):
  File "C:/Users/Administrator/PycharmProjects/forecast/gridsearch.py", line 43, in &lt;module&gt;
    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
</code></pre>

<p>&emsp;&emsp;the model works well without packaging with kerasRegressor, but i wanna using sk_learn's gridSearch after this, so i'm here for help. I tried but still have no idea.  </p>

<p><strong>something maybe helpful:</strong></p>

<pre><code>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):
        '''Construct a new model with build_fn and fit the model according
        to the given training data.
    # Arguments
        X : array-like, shape `(n_samples, n_features)`
            Training samples where n_samples in the number of samples
            and n_features is the number of features.
        y : array-like, shape `(n_samples,)` or `(n_samples, n_outputs)`
            True labels for X.
        kwargs: dictionary arguments
            Legal arguments are the arguments of `Sequential.fit`

    # Returns
        history : object
            details about the training history at each 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
</code></pre>

<p>&emsp;&emsp;error occored in this line:</p>

<pre><code>    self.model = self.build_fn(
        **self.filter_sk_params(self.build_fn.__call__))
</code></pre>

<p>self.build_fn here is keras.models.Sequential  </p>

<pre><code>models.py  

class Sequential(Model):

    def call(self, x, mask=None):
        if not self.built:
            self.build()
        return self.model.call(x, mask)
</code></pre>

<p>So, what's that x mean and how to fix this error?<br>
Thanks!</p>

<p><a href="http://stackoverflow.com/users/6825808/xiao">xiao</a>, I ran into the same issue! Hopefully this helps:</p>

<h1>Background and The Issue</h1>

<p>The <a href="https://keras.io/scikit-learn-api/#wrappers-for-the-scikit-learn-api" rel="nofollow">documentation for Keras</a> states that, when implementing Wrappers for scikit-learn, there are two arguments. The first is the build function, which is a "callable function or class instance". Specifically, it states that:</p>

<blockquote>
  <p><code>build_fn</code> should construct, compile and return a Keras model, which will then be used to fit/predict. One of the following three values could be passed to build_fn:</p>
  
  <ol>
  <li>A function</li>
  <li>An instance of a class that implements the <strong>call</strong> method</li>
  <li>None. This means you implement a class that inherits from either <code>KerasClassifier</code> or <code>KerasRegressor</code>. The <strong>call</strong> method of the present class will then be treated as the default build_fn.</li>
  </ol>
</blockquote>

<p>In your code, you create the model, and then pass the model as the value for the argument <code>build_fn</code> when creating the <code>KerasRegressor</code> wrapper:</p>

<pre><code>model = nn_model()
model = KerasRegressor(build_fn=model, nb_epoch=2)
</code></pre>

<p>Herein lies the issue. Rather than passing your <code>nn_model</code> <strong>function</strong> as the <code>build_fn</code>, you pass an actual instance of the Keras <code>Sequential</code> model. For this reason, when <code>fit()</code> is called, it cannot find the <code>call</code> method, because it is not implemented in the class you returned.</p>

<h1>Proposed Solution</h1>

<p>What I did to make things work is pass the function as <code>build_fn</code>, rather than an actual model:</p>

<pre><code>data = read_db()
y = data.pop('PRICE').as_matrix()
x = data.as_matrix()
# model = nn_model() # Don't do this!
# set build_fn equal to the nn_model function
model = KerasRegressor(build_fn=nn_model, nb_epoch=2) # note that you do not call the function!
model.fit(x,y)  # fixed!
</code></pre>

<p>This is not the only solution (you could set <code>build_fn</code> to a class that implements the <code>call</code> method appropriately), but the one that worked for me. I hope it helps you!</p>

python machine-learning scikit-learn keras