我正在使用Keras的sklearn包装器作为一个回归器,即tf.keras.wrappers.scikit_learn.KerasRegressor
。我希望这个回归器在sklearn的交叉验证方案中工作,也就是sklearn.model_selection.cross_validate
。
回归器通常在没有CV的情况下工作。然而,后者失败了,因为我在回归器的__init__
方法中有一个必要的参数来定义批处理输入形状,但它似乎丢失了。这似乎是因为使用clone(estimator)
不能正确克隆MyRegressor
或KerasRegressor
。具体的错误消息是:
KeyError: 'batch_input_shape'
有没有一种方法可以让MyRegressor
和cross_validate
一起工作?我是否在某种程度上违反了sklearn的要求?
请看这个精简的工作示例:
from sklearn.datasets import make_regression
from sklearn.model_selection import cross_validate
from tensorflow.keras.layers import Dense, LSTM
from tensorflow.keras.models import Sequential
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
class MyRegressor(KerasRegressor):
def __init__(self, batch_input_shape, build_fn=None, **kwargs):
self.batch_input_shape = batch_input_shape
super().__init__(**kwargs)
def __call__(self, *kwargs):
model = Sequential([
LSTM(16, stateful=True, batch_input_shape=self.batch_input_shape),
Dense(1),
])
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['RootMeanSquaredError'])
return model
def reset_states(self):
self.model.reset_states()
X, y = make_regression(6400, 5)
X = X.reshape(X.shape[0], 1, X.shape[1])
batch_size = 64
batch_input_shape = (batch_size, 1, X.shape[-1])
# Works fine
reg = MyRegressor(batch_input_shape)
for i in range(10):
reg.fit(X, y, batch_size=batch_size)
reg.reset_states()
# Doesn't work
reg = MyRegressor(batch_input_shape)
results = cross_validate(reg, X, y, scoring=['neg_mean_squared_error'])
发布于 2021-09-27 18:22:54
可复制性需要适当的get_params
方法。大多数情况下,这是通过继承sklearn的BaseEstimator
获得的,但是KerasRegressor
直接实现了自己的(source)。它的工作方式与您的附加batch_input_shape
不兼容;您可以调整它以使其正常工作:
def get_params(self, deep=False):
res = self.sk_params.copy() # sk_params was set by KerasRegressor.__init__
res.update({
'build_fn': self.build_fn,
'batch_input_shape': self.batch_input_shape,
})
return res
(在这次更新之后,我在您的示例中得到了一个关于输入形状的错误。但我对批处理大小和kera不太熟悉,无法回答后续问题。)
https://stackoverflow.com/questions/69349589
复制相似问题