【问题标题】:How to pass a parameter to Scikit-Learn Keras model function如何将参数传递给 Scikit-Learn Keras 模型函数
【发布时间】:2017-03-16 13:45:16
【问题描述】:

我有以下代码,使用Keras Scikit-Learn Wrapper,可以正常工作:

from keras.models import Sequential
from keras.layers import Dense
from sklearn import datasets
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
import numpy as np


def create_model():
    # create model
    model = Sequential()
    model.add(Dense(12, input_dim=4, init='uniform', activation='relu'))
    model.add(Dense(6, init='uniform', activation='relu'))
    model.add(Dense(1, init='uniform', activation='sigmoid'))
    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model


def main():
    """
    Description of main
    """


    iris = datasets.load_iris()
    X, y = iris.data, iris.target

    NOF_ROW, NOF_COL =  X.shape

    # evaluate using 10-fold cross validation
    seed = 7
    np.random.seed(seed)
    model = KerasClassifier(build_fn=create_model, nb_epoch=150, batch_size=10, verbose=0)
    kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
    results = cross_val_score(model, X, y, cv=kfold)

    print(results.mean())
    # 0.666666666667


if __name__ == '__main__':
    main()

pima-indians-diabetes.data可以下载here

现在我要做的是通过以下方式将值NOF_COL 传递给create_model() 函数的参数

model = KerasClassifier(build_fn=create_model(input_dim=NOF_COL), nb_epoch=150, batch_size=10, verbose=0)

create_model() 函数看起来像这样:

def create_model(input_dim=None):
    # create model
    model = Sequential()
    model.add(Dense(12, input_dim=input_dim, init='uniform', activation='relu'))
    model.add(Dense(6, init='uniform', activation='relu'))
    model.add(Dense(1, init='uniform', activation='sigmoid'))
    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

但它没有给出这个错误:

TypeError: __call__() takes at least 2 arguments (1 given)

正确的做法是什么?

【问题讨论】:

    标签: python function scikit-learn keras callable


    【解决方案1】:

    您可以将input_dim 关键字参数添加到KerasClassifier 构造函数:

    model = KerasClassifier(build_fn=create_model, input_dim=5, nb_epoch=150, batch_size=10, verbose=0)
    

    【讨论】:

      【解决方案2】:

      最后一个答案不再起作用。

      另一种方法是从 create_model 返回一个函数,因为 KerasClassifier build_fn 需要一个函数:

      def create_model(input_dim=None):
          def model():
              # create model
              nn = Sequential()
              nn.add(Dense(12, input_dim=input_dim, init='uniform', activation='relu'))
              nn.add(Dense(6, init='uniform', activation='relu'))
              nn.add(Dense(1, init='uniform', activation='sigmoid'))
              # Compile model
              nn.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
              return nn
      
          return model
      

      或者更好,根据documentation

      sk_params 接受模型参数和拟合参数。合法的模型参数是 build_fn 的参数。请注意,与 scikit-learn 中的所有其他估算器一样,build_fn 应该为其参数提供 默认值,这样您就可以创建估算器而无需将任何值传递给 sk_params

      所以你可以这样定义你的函数:

      def create_model(number_of_features=10): # 10 is the *default value*
          # create model
          nn = Sequential()
          nn.add(Dense(12, input_dim=number_of_features, init='uniform', activation='relu'))
          nn.add(Dense(6, init='uniform', activation='relu'))
          nn.add(Dense(1, init='uniform', activation='sigmoid'))
          # Compile model
          nn.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
          return nn
      

      并创建一个包装器:

      KerasClassifier(build_fn=create_model, number_of_features=20, epochs=25, batch_size=1000, ...)
      

      【讨论】:

        【解决方案3】:

        要将参数传递给 build_fn 模型,可以将参数传递给__init__(),然后将其直接传递给model_build_fn。例如,调用KerasClassifier(myparam=10) 将导致model_build_fn(my_param=10)

        这是一个例子:

        class MyMultiOutputKerasRegressor(KerasRegressor):
            
            # initializing
            def __init__(self, **kwargs):
                KerasRegressor.__init__(self, **kwargs)
                
            # simpler fit method
            def fit(self, X, y, **kwargs):
                KerasRegressor.fit(self, X, [y]*3, **kwargs)
        

        (...)

        def get_quantile_reg_rpf_nn(layers_shape=[50,100,200,100,50], inDim= 4, outDim=1, act='relu'):
                  # do model stuff...
        

        (...) 初始化 Keras 回归器:

        base_model = MyMultiOutputKerasRegressor(build_fn=get_quantile_reg_rpf_nn,
                                                 layers_shape=[50,100,200,100,50], inDim= 4, 
                                                 outDim=1, act='relu', epochs=numEpochs, 
                                                 batch_size=batch_size, verbose=0)
        

        【讨论】:

          猜你喜欢
          • 2016-12-26
          • 1970-01-01
          • 2020-02-21
          • 2017-07-13
          • 2016-01-11
          • 2013-12-20
          • 2021-11-05
          • 1970-01-01
          相关资源
          最近更新 更多