如何将参数传递给 Scikit-Learn Keras 模型函数
How to pass a parameter to Scikit-Learn Keras model function
我有以下代码,使用 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)
正确的做法是什么?
您可以向 KerasClassifier
构造函数添加一个 input_dim
关键字参数:
model = KerasClassifier(build_fn=create_model, input_dim=5, nb_epoch=150, batch_size=10, verbose=0)
最后一个答案不再有效。
另一种方法是 return 来自 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 takes both model parameters and fitting parameters. Legal model parameters are the arguments of build_fn. Note that like all other estimators in scikit-learn, build_fn should provide default values for its arguments, so that you could create the estimator without passing any values to 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, ...)
要将参数传递给 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)
我有以下代码,使用 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)
正确的做法是什么?
您可以向 KerasClassifier
构造函数添加一个 input_dim
关键字参数:
model = KerasClassifier(build_fn=create_model, input_dim=5, nb_epoch=150, batch_size=10, verbose=0)
最后一个答案不再有效。
另一种方法是 return 来自 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 takes both model parameters and fitting parameters. Legal model parameters are the arguments of build_fn. Note that like all other estimators in scikit-learn, build_fn should provide default values for its arguments, so that you could create the estimator without passing any values to 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, ...)
要将参数传递给 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)